From 9b4973e7d96a3605583c3f9a80567945c8d4be71 Mon Sep 17 00:00:00 2001 From: Jesper Jensen Date: Fri, 3 Sep 2021 22:32:42 +0200 Subject: Add ping support --- src/query.c | 84 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 84 insertions(+) create mode 100644 src/query.c (limited to 'src/query.c') diff --git a/src/query.c b/src/query.c new file mode 100644 index 0000000..5645271 --- /dev/null +++ b/src/query.c @@ -0,0 +1,84 @@ +#include "query.h" +#include "benc.h" +#include "log.h" + +#include +#include + +int handle_request(struct nodeid* self, const char* method, const char* packet, size_t packet_len, char** response, size_t response_len) { + if(strcmp(method, "ping") == 0) { + struct bcursor bcursor; + struct benc_node stream[256]; + bcur_open(&bcursor, packet, packet+packet_len, stream, 256); + + if(bcursor.readhead->type != BNT_DICT) { + err("Bad query: Packet is not a dict"); + return QUERY_EBADQ; + } + if(bcur_next(&bcursor, 1) < 0) { + err("Bad query: No token after outer dict start"); + return QUERY_EBADQ; + } + + if(bcur_find_key(&bcursor, (const enum benc_nodetype[]){BNT_STRING}, (const char*[]){"a"}, (const size_t[]){1}, 1) != 0) { + err("Bad query: No arguments to request"); + return QUERY_EBADQ; + } + bcur_next(&bcursor, 1); + if(bcursor.readhead->type != BNT_DICT) { + err("Bad query: Wrong value type for request"); + return QUERY_EBADQ; + } + // Skip the dict element + bcur_next(&bcursor, 1); + bool source_set = false; + struct nodeid source_id; + while(bcursor.readhead->type != BNT_END) { + switch(bcur_find_key(&bcursor, (const enum benc_nodetype[]){BNT_STRING}, (const char*[]){"id"}, (const size_t[]){6}, 1)) { + case 0: + // Skip the key + bcur_next(&bcursor, 1); + + if(bcursor.readhead->type != BNT_STRING) { + err("Bad query: Wrong value type for id"); + return QUERY_EBADQ; + } + + if(bcursor.readhead->size != 20) { + err("Bad query: Incorrect id length"); + return QUERY_EBADQ; + } + + source_set = true; + memcpy(&source_id, bcursor.readhead->loc, 20); + + // Skip the value + bcur_next(&bcursor, 1); + break; + } + } + + if(!source_set) { + err("Id argument not set"); + return QUERY_EBADQ; + } + + char* end = (*response) + response_len; + + int rc = snprintf(*response, end-*response, "d2:id20:"); + if(rc < 0) + return QUERY_EBADQ; + *response += rc; + memcpy(*response, self, sizeof(struct nodeid)); + *response += sizeof(struct nodeid); + rc = snprintf(*response, end-*response, "ee"); + if(rc < 0) + return QUERY_EBADQ; + *response += rc; + } else { + return QUERY_EUNK; + } + + return 0; +} + -- cgit v1.2.3