]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
FS-9775: Added preliminary support for processing find_nodes query, including calls...
authorShane Bryldt <astaelan@gmail.com>
Tue, 6 Dec 2016 23:37:36 +0000 (23:37 +0000)
committerMike Jerris <mike@jerris.com>
Wed, 25 Jan 2017 20:59:34 +0000 (14:59 -0600)
libs/libks/src/dht/ks_dht-int.h
libs/libks/src/dht/ks_dht.c

index 4f835ed18d60a9a392487561a5a2a3bd3e197060..f74d3d906512beb517d96c2b6485badd4ef4a98e 100644 (file)
@@ -5,6 +5,19 @@
 
 KS_BEGIN_EXTERN_C
 
+/**
+ *
+ */
+KS_DECLARE(ks_status_t) ks_dht2_utility_compact_address(ks_sockaddr_t *address,
+                                                                                                               uint8_t *buffer,
+                                                                                                               ks_size_t *buffer_length,
+                                                                                                               ks_size_t buffer_size);
+KS_DECLARE(ks_status_t) ks_dht2_utility_compact_node(ks_dht2_nodeid_raw_t *nodeid,
+                                                                                                        ks_sockaddr_t *address,
+                                                                                                        uint8_t *buffer,
+                                                                                                        ks_size_t *buffer_length,
+                                                                                                        ks_size_t buffer_size);
+
 /**
  *
  */
index 746c9e62faddf7eb39e39dc0bb0852243724bf90..02327a242131a7b47012d7edb1059ffbeebac659 100644 (file)
@@ -180,8 +180,8 @@ KS_DECLARE(ks_status_t) ks_dht2_autoroute(ks_dht2_t *dht, ks_bool_t autoroute, k
 
        if (!autoroute) {
                port = 0;
-       } else if (port == 0) {
-               return KS_STATUS_FAIL;
+       } else if (port <= 0) {
+               port = KS_DHT_DEFAULT_PORT;
        }
        
        dht->autoroute = autoroute;
@@ -331,13 +331,81 @@ KS_DECLARE(void) ks_dht2_pulse(ks_dht2_t *dht, int32_t timeout)
 /**
  *
  */
-KS_DECLARE(ks_status_t) ks_dht2_maketid(ks_dht2_t *dht)
+KS_DECLARE(ks_status_t) ks_dht2_utility_compact_address(ks_sockaddr_t *address,
+                                                                                                               uint8_t *buffer,
+                                                                                                               ks_size_t *buffer_length,
+                                                                                                               ks_size_t buffer_size)
 {
-       ks_assert(dht);
+       ks_size_t required = sizeof(uint16_t);
+       uint16_t port = 0;
+       
+       ks_assert(address);
+       ks_assert(buffer);
+       ks_assert(buffer_length);
+       ks_assert(buffer_size);
+       ks_assert(address->family == AF_INET || address->family == AF_INET6);
+
+       if (address->family == AF_INET) {
+               required += sizeof(uint32_t);
+       } else {
+               required += 8 * sizeof(uint16_t);
+       }
+
+       if (*buffer_length + required > buffer_size) {
+               ks_log(KS_LOG_DEBUG, "Insufficient space remaining for compacting\n");
+               return KS_STATUS_FAIL;
+       }
+
+       if (address->family == AF_INET) {
+               uint32_t *paddr = (uint32_t *)&address->v.v4.sin_addr;
+               uint32_t addr = htonl(*paddr);
+               port = htons(address->v.v4.sin_port);
 
+               memcpy(buffer + (*buffer_length), (void *)&addr, sizeof(uint32_t));
+               *buffer_length += sizeof(uint32_t);
+       } else {
+               uint16_t *paddr = (uint16_t *)&address->v.v6.sin6_addr;
+               port = htons(address->v.v6.sin6_port);
+
+               for (int32_t i = 0; i < 8; ++i) {
+                       uint16_t addr = htons(paddr[i]);
+                       memcpy(buffer + (*buffer_length), (void *)&addr, sizeof(uint16_t));
+                       *buffer_length += sizeof(uint16_t);
+               }
+       }
+
+       memcpy(buffer + (*buffer_length), (void *)&port, sizeof(uint16_t));
+       *buffer_length += sizeof(uint16_t);
+       
        return KS_STATUS_SUCCESS;
 }
 
+/**
+ *
+ */
+KS_DECLARE(ks_status_t) ks_dht2_utility_compact_node(ks_dht2_nodeid_raw_t *nodeid,
+                                                                                                        ks_sockaddr_t *address,
+                                                                                                        uint8_t *buffer,
+                                                                                                        ks_size_t *buffer_length,
+                                                                                                        ks_size_t buffer_size)
+{
+       ks_assert(address);
+       ks_assert(buffer);
+       ks_assert(buffer_length);
+       ks_assert(buffer_size);
+       ks_assert(address->family == AF_INET || address->family == AF_INET6);
+
+       if (*buffer_length + KS_DHT_NODEID_LENGTH > buffer_size) {
+               ks_log(KS_LOG_DEBUG, "Insufficient space remaining for compacting\n");
+               return KS_STATUS_FAIL;
+       }
+
+       memcpy(buffer + (*buffer_length), (void *)nodeid, KS_DHT_NODEID_LENGTH);
+       *buffer_length += KS_DHT_NODEID_LENGTH;
+
+       return ks_dht2_utility_compact_address(address, buffer, buffer_length, buffer_size);
+}
+
 /**
  *
  */
@@ -904,37 +972,44 @@ KS_DECLARE(ks_status_t) ks_dht2_process_query_findnode(ks_dht2_t *dht, ks_dht2_m
 {
        struct bencode *id;
        struct bencode *target;
-       //const char *idv;
+       struct bencode *want;
+       const char *idv;
        //const char *targetv;
        ks_size_t idv_len;
        ks_size_t targetv_len;
+       ks_bool_t want4 = KS_FALSE;
+       ks_bool_t want6 = KS_FALSE;
        ks_dht2_message_t *response = NULL;
        struct bencode *r = NULL;
+       uint8_t buffer[1000];
+       ks_size_t buffer_length = 0;
        ks_status_t ret = KS_STATUS_FAIL;
 
        ks_assert(dht);
        ks_assert(message);
        ks_assert(message->args);
 
+       
     id = ben_dict_get_by_str(message->args, "id");
     if (!id) {
                ks_log(KS_LOG_DEBUG, "Message args missing required key 'id'\n");
                return KS_STATUS_FAIL;
        }
        
-    //idv = ben_str_val(id);
+    idv = ben_str_val(id);
        idv_len = ben_str_len(id);
     if (idv_len != KS_DHT_NODEID_LENGTH) {
                ks_log(KS_LOG_DEBUG, "Message args 'id' value has an unexpected size of %d\n", idv_len);
                return KS_STATUS_FAIL;
        }
 
+       
        target = ben_dict_get_by_str(message->args, "target");
     if (!target) {
                ks_log(KS_LOG_DEBUG, "Message args missing required key 'target'\n");
                return KS_STATUS_FAIL;
        }
-       
+
     //targetv = ben_str_val(target);
     targetv_len = ben_str_len(target);
     if (targetv_len != KS_DHT_NODEID_LENGTH) {
@@ -943,9 +1018,37 @@ KS_DECLARE(ks_status_t) ks_dht2_process_query_findnode(ks_dht2_t *dht, ks_dht2_m
        }
 
        
-       ks_log(KS_LOG_DEBUG, "Message query find_node is valid\n");
+       want = ben_dict_get_by_str(message->args, "want");
+       if (want) {
+               size_t want_len = ben_list_len(want);
+               for (size_t i = 0; i < want_len; ++i) {
+                       struct bencode *iv = ben_list_get(want, i);
+                       if (!ben_cmp_with_str(iv, "n4")) {
+                               want4 = KS_TRUE;
+                       }
+                       if (!ben_cmp_with_str(iv, "n6")) {
+                               want6 = KS_TRUE;
+                       }
+               }
+       }
+
+       if (!want4 && !want6) {
+               want4 = message->raddr.family == AF_INET;
+               want6 = message->raddr.family == AF_INET6;
+       }
 
+       // @todo add/touch bucket entry for remote node
        
+       ks_log(KS_LOG_DEBUG, "Message query find_node is valid\n");
+
+       // @todo get closest nodes to target from route table
+
+       // @todo compact into buffer
+       if (ks_dht2_utility_compact_node((ks_dht2_nodeid_raw_t *)idv, &message->raddr, buffer, &buffer_length, sizeof(buffer)) != KS_STATUS_SUCCESS) {
+               return KS_STATUS_FAIL;
+       }
+
+
        if (ks_dht2_message_alloc(&response, dht->pool) != KS_STATUS_SUCCESS) {
                goto done;
        }
@@ -959,6 +1062,8 @@ KS_DECLARE(ks_status_t) ks_dht2_process_query_findnode(ks_dht2_t *dht, ks_dht2_m
        }
        
        ben_dict_set(r, ben_blob("id", 2), ben_blob(dht->nodeid.id, KS_DHT_NODEID_LENGTH));
+       // @todo populate nodes/nodes6
+       ben_dict_set(r, ben_blob("nodes", 5), ben_blob(buffer, buffer_length));
 
        ks_log(KS_LOG_DEBUG, "Sending message response find_node\n");
        ks_q_push(dht->send_q, (void *)response);