]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
FS-9775: Add flags to dhtrt_create_node (merge)
authorcolm <colm@freeswitch1>
Tue, 27 Dec 2016 18:20:10 +0000 (13:20 -0500)
committerMike Jerris <mike@jerris.com>
Wed, 25 Jan 2017 20:59:38 +0000 (14:59 -0600)
libs/libks/src/dht/ks_dht.c
libs/libks/src/dht/ks_dht.h
libs/libks/src/dht/ks_dht_bucket.c
libs/libks/test/testbuckets.c

index b54e2ad2c449bdf5d75e15ec0d4172153e5182b8..28c981594711c39369a856d06db977a913303a43 100644 (file)
@@ -542,6 +542,7 @@ KS_DECLARE(ks_status_t) ks_dht_bind(ks_dht_t *dht, const ks_dht_nodeid_t *nodeid
                                                                                KS_DHT_LOCAL,
                                                                                ep->addr.host,
                                                                                ep->addr.port,
+                                                                               KS_DHTRT_CREATE_DEFAULT,
                                                                                &ep->node)) != KS_STATUS_SUCCESS) goto done;
        } else {
                if (!dht->rt_ipv6 && (ret = ks_dhtrt_initroute(&dht->rt_ipv6, dht, dht->pool)) != KS_STATUS_SUCCESS) goto done;
@@ -550,6 +551,7 @@ KS_DECLARE(ks_status_t) ks_dht_bind(ks_dht_t *dht, const ks_dht_nodeid_t *nodeid
                                                                                KS_DHT_LOCAL,
                                                                                ep->addr.host,
                                                                                ep->addr.port,
+                                                                               KS_DHTRT_CREATE_DEFAULT,
                                                                                &ep->node)) != KS_STATUS_SUCCESS) goto done;
        }
        /**
@@ -1473,6 +1475,7 @@ KS_DECLARE(ks_status_t) ks_dht_process_query(ks_dht_t *dht, ks_dht_message_t *me
                                                                        KS_DHT_REMOTE,
                                                                        message->raddr.host,
                                                                        message->raddr.port,
+                                                                       KS_DHTRT_CREATE_DEFAULT,
                                                                        &node)) != KS_STATUS_SUCCESS) goto done;
        if ((ret = ks_dhtrt_release_node(node)) != KS_STATUS_SUCCESS) goto done;
 
@@ -1518,6 +1521,7 @@ KS_DECLARE(ks_status_t) ks_dht_process_response(ks_dht_t *dht, ks_dht_message_t
                                                                        KS_DHT_REMOTE,
                                                                        message->raddr.host,
                                                                        message->raddr.port,
+                                                                       KS_DHTRT_CREATE_DEFAULT,
                                                                        &node)) != KS_STATUS_SUCCESS) goto done;
        if ((ret = ks_dhtrt_release_node(node)) != KS_STATUS_SUCCESS) goto done;
        
@@ -2177,7 +2181,7 @@ KS_DECLARE(ks_status_t) ks_dht_process_response_findnode(ks_dht_t *dht, ks_dht_j
                           addr.port);
 
                ks_log(KS_LOG_DEBUG, "Creating node %s\n", ks_dht_hex(nid.id, id_buf, KS_DHT_NODEID_SIZE));
-               ks_dhtrt_create_node(dht->rt_ipv4, nid, KS_DHT_REMOTE, addr.host, addr.port, &node);
+               ks_dhtrt_create_node(dht->rt_ipv4, nid, KS_DHT_REMOTE, addr.host, addr.port, KS_DHTRT_CREATE_DEFAULT, &node);
                job->response_nodes[job->response_nodes_count++] = node;
 
                // @todo move search to it's own job, and make reusable for find_node and get, and others that return nodes/nodes6
@@ -2239,7 +2243,7 @@ KS_DECLARE(ks_status_t) ks_dht_process_response_findnode(ks_dht_t *dht, ks_dht_j
                           addr.port);
 
                ks_log(KS_LOG_DEBUG, "Creating node %s\n", ks_dht_hex(nid.id, id_buf, KS_DHT_NODEID_SIZE));
-               ks_dhtrt_create_node(dht->rt_ipv6, nid, KS_DHT_REMOTE, addr.host, addr.port, &node);
+               ks_dhtrt_create_node(dht->rt_ipv6, nid, KS_DHT_REMOTE, addr.host, addr.port, KS_DHTRT_CREATE_DEFAULT, &node);
                job->response_nodes6[job->response_nodes6_count++] = node;
 
                // @todo move search to it's own job, and make reusable for find_node and get, and others that return nodes/nodes6
@@ -2521,7 +2525,7 @@ KS_DECLARE(ks_status_t) ks_dht_process_response_get(ks_dht_t *dht, ks_dht_job_t
                           addr.port);
 
                ks_log(KS_LOG_DEBUG, "Creating node %s\n", ks_dht_hex(nid.id, id_buf, KS_DHT_NODEID_SIZE));
-               ks_dhtrt_create_node(dht->rt_ipv4, nid, KS_DHT_REMOTE, addr.host, addr.port, &node);
+               ks_dhtrt_create_node(dht->rt_ipv4, nid, KS_DHT_REMOTE, addr.host, addr.port, KS_DHTRT_CREATE_DEFAULT, &node);
                job->response_nodes[job->response_nodes_count++] = node;
        }
        while (nodes6_len < nodes6_size) {
@@ -2538,7 +2542,7 @@ KS_DECLARE(ks_status_t) ks_dht_process_response_get(ks_dht_t *dht, ks_dht_job_t
                           addr.port);
 
                ks_log(KS_LOG_DEBUG, "Creating node %s\n", ks_dht_hex(nid.id, id_buf, KS_DHT_NODEID_SIZE));
-               ks_dhtrt_create_node(dht->rt_ipv6, nid, KS_DHT_REMOTE, addr.host, addr.port, &node);
+               ks_dhtrt_create_node(dht->rt_ipv6, nid, KS_DHT_REMOTE, addr.host, addr.port, KS_DHTRT_CREATE_DEFAULT, &node);
                job->response_nodes6[job->response_nodes6_count++] = node;
        }
        
index 7a2caca64336cdf82c53d6ff530dd0a7bb36b056..237495711ea19e4d474502b8522d4bc348f4a793 100644 (file)
@@ -85,13 +85,18 @@ struct ks_dht_nodeid_s {
 
 enum ks_afflags_t { ifv4=AF_INET, ifv6=AF_INET6, ifboth=AF_INET+AF_INET6};
 enum ks_dht_nodetype_t { KS_DHT_REMOTE=0x01, 
-                         KS_DHT_LOCAL=0x02, 
-                         KS_DHT_BOTH=KS_DHT_REMOTE+KS_DHT_LOCAL };
-
+                                                KS_DHT_LOCAL=0x02, 
+                                                KS_DHT_BOTH=KS_DHT_REMOTE+KS_DHT_LOCAL };
+
+enum ks_create_node_flags_t { 
+                                                KS_DHTRT_CREATE_DEFAULT=0,
+                                                KS_DHTRT_CREATE_PING,
+                                                KS_DHTRT_CREATE_TOUCH 
+};             
+                               
 struct ks_dht_node_s {
     ks_dht_nodeid_t  nodeid;
     ks_sockaddr_t    addr;
-//    enum ks_afflags_t family;                  /* AF_INET or AF_INET6 */
     enum ks_dht_nodetype_t type;               /* local or remote */
     ks_dhtrt_routetable_t* table;
     ks_rwl_t        *reflock;          
@@ -487,6 +492,7 @@ KS_DECLARE(ks_status_t)        ks_dhtrt_create_node(ks_dhtrt_routetable_t* table
                                                                                                        ks_dht_nodeid_t nodeid,
                                                                                                        enum ks_dht_nodetype_t type,
                                                                                                        char* ip, unsigned short port,
+                                                    enum ks_create_node_flags_t flags,
                                                                                                        ks_dht_node_t** node);
 
 KS_DECLARE(ks_status_t)        ks_dhtrt_delete_node(ks_dhtrt_routetable_t* table, ks_dht_node_t* node);
index 5e6378627cbe6b093350441f2a091806e26101a4..841ec879c58cab73135b4adf5bdeb55552402045 100644 (file)
@@ -31,7 +31,7 @@
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-#pragma GCC optimize ("O0")
+/* # pragma GCC optimize ("O0") */
 
 
 #include "ks_dht.h"
@@ -159,9 +159,9 @@ void ks_dhtrt_process_deleted(ks_dhtrt_routetable_t *table, int8_t all);
 static
 ks_dht_node_t *ks_dhtrt_make_node(ks_dhtrt_routetable_t *table);
 static
-ks_status_t ks_dhtrt_insert_node(ks_dhtrt_routetable_t *table, ks_dht_node_t *node);
+ks_status_t ks_dhtrt_insert_node(ks_dhtrt_routetable_t *table, ks_dht_node_t *node, enum ks_create_node_flags_t flags);
 static
-ks_status_t ks_dhtrt_insert_id(ks_dhtrt_bucket_t *bucket, ks_dht_node_t *node);
+ks_dhtrt_bucket_entry_t* ks_dhtrt_insert_id(ks_dhtrt_bucket_t *bucket, ks_dht_node_t *node);
 static
 ks_status_t ks_dhtrt_delete_id(ks_dhtrt_bucket_t *bucket, ks_dhtrt_nodeid_t id);
 static
@@ -279,6 +279,7 @@ KS_DECLARE(ks_status_t)      ks_dhtrt_create_node( ks_dhtrt_routetable_t *table,
                                                                                           enum ks_dht_nodetype_t type, 
                                                                                           char *ip,
                                                                                           unsigned short port,
+                                                                                          enum ks_create_node_flags_t flags,
                                                                                           ks_dht_node_t **node) 
 {
     if (!table || !table->internal) {
@@ -295,16 +296,36 @@ KS_DECLARE(ks_status_t)    ks_dhtrt_create_node( ks_dhtrt_routetable_t *table,
 
     ks_dhtrt_bucket_entry_t *bentry = ks_dhtrt_find_bucketentry(header, nodeid.id);
 
-    if (bentry != 0) {
+    if (bentry != 0) { 
+
+        ks_rwl_read_lock(header->bucket->lock);
+
                bentry->tyme = ks_time_now_sec();
+
+               /* touch */
+               if (flags == KS_DHTRT_CREATE_TOUCH) {
+                       bentry->outstanding_pings = 0;
+                       bentry->touched = 1;    
+                       if (bentry->flags == DHTPEER_EXPIRED) {
+                               --header->bucket->expired_count;
+                       }               
+               }
         
         if (bentry->touched) {
             bentry->flags = DHTPEER_ACTIVE;
         }
 
+               /* ping */
+        if (!bentry->touched && !bentry->outstanding_pings) {
+                       ks_dhtrt_ping(internal, bentry);        
+               }
+
                tnode = bentry->gptr;
+
+               ks_rwl_read_unlock(header->bucket->lock);
         ks_rwl_read_lock( tnode->reflock);
                ks_rwl_read_unlock(internal->lock);
+
         (*node) = tnode;
                return KS_STATUS_SUCCESS;
     }
@@ -313,13 +334,15 @@ KS_DECLARE(ks_status_t)    ks_dhtrt_create_node( ks_dhtrt_routetable_t *table,
     tnode = ks_dhtrt_make_node(table);
        tnode->table = table;
 
-    enum ks_afflags_t family;
+    enum ks_afflags_t family =  AF_INET;
 
        for (int i = 0; i < 5; ++i) {
                if (ip[i] == ':') { 
-                       family =         AF_INET6; break;
+                       family =         AF_INET6; 
+                       break;
                } else if (ip[i] == '.') { 
-                       family =         AF_INET; break; 
+                       family =         AF_INET; 
+                       break; 
                }
        }
 
@@ -333,7 +356,7 @@ KS_DECLARE(ks_status_t)      ks_dhtrt_create_node( ks_dhtrt_routetable_t *table,
         return KS_STATUS_FAIL;
     }
 
-    ks_status_t s = ks_dhtrt_insert_node(table, tnode);
+    ks_status_t s = ks_dhtrt_insert_node(table, tnode, flags);
 
     if (tnode && s == KS_STATUS_SUCCESS) {
                ks_rwl_read_lock( tnode->reflock);
@@ -387,7 +410,7 @@ KS_DECLARE(ks_status_t) ks_dhtrt_delete_node(ks_dhtrt_routetable_t *table, ks_dh
 }
 
 static
-ks_status_t ks_dhtrt_insert_node(ks_dhtrt_routetable_t *table, ks_dht_node_t *node)
+ks_status_t ks_dhtrt_insert_node(ks_dhtrt_routetable_t *table, ks_dht_node_t *node, enum ks_create_node_flags_t flags)
 {
        if (!table || !table->internal) {
                return KS_STATUS_FAIL;
@@ -420,9 +443,9 @@ ks_status_t ks_dhtrt_insert_node(ks_dhtrt_routetable_t *table, ks_dht_node_t *no
 
                /* first - seek a stale entry to eject */
                if (bucket->expired_count) {
-                       ks_status_t s = ks_dhtrt_insert_id(bucket, node);
+                       ks_dhtrt_bucket_entry_t* entry = ks_dhtrt_insert_id(bucket, node);
 
-                       if (s == KS_STATUS_SUCCESS) {
+                       if (entry != NULL) {
 #ifdef  KS_DHT_DEBUGLOCKPRINTF_
                                 ks_log(KS_LOG_DEBUG, "insert node: UNLOCKING bucket %s\n", ks_dhtrt_printableid(header->mask, buf));
 #endif
@@ -503,7 +526,20 @@ ks_status_t ks_dhtrt_insert_node(ks_dhtrt_routetable_t *table, ks_dht_node_t *no
        ks_log(KS_LOG_DEBUG, "  ...into bucket %s\n", ks_dhtrt_printableid(header->mask, buffer));
 #endif
 
-       ks_status_t s = ks_dhtrt_insert_id(bucket, node);
+       ks_status_t s = KS_STATUS_FAIL;
+
+       ks_dhtrt_bucket_entry_t* entry = ks_dhtrt_insert_id(bucket, node);
+    if (entry != NULL) {
+        s = KS_STATUS_SUCCESS;
+               /* touch */
+               if (flags == KS_DHTRT_CREATE_TOUCH) {
+                        entry->flags = DHTPEER_ACTIVE;
+                        entry->touched = 1;
+               }
+               else if (flags == KS_DHTRT_CREATE_PING ) {
+                        ks_dhtrt_ping(internal, entry);
+               }
+       }
        ks_rwl_write_unlock(internal->lock);
 #ifdef  KS_DHT_DEBUGLOCKPRINTF_
        ks_log(KS_LOG_DEBUG, "Insert node: UNLOCKING bucket %s\n",
@@ -1295,7 +1331,7 @@ void ks_dhtrt_split_bucket(ks_dhtrt_bucket_header_t *original,
  *       so at least the static array does away with the need for locking.
  */
 static 
-ks_status_t ks_dhtrt_insert_id(ks_dhtrt_bucket_t *bucket, ks_dht_node_t *node)
+ks_dhtrt_bucket_entry_t* ks_dhtrt_insert_id(ks_dhtrt_bucket_t *bucket, ks_dht_node_t *node)
 {
        /* sanity checks */
        if (!bucket || bucket->count > KS_DHT_BUCKETSIZE) {
@@ -1327,7 +1363,7 @@ ks_status_t ks_dhtrt_insert_id(ks_dhtrt_bucket_t *bucket, ks_dht_node_t *node)
                        ks_log(KS_LOG_DEBUG, "duplicate peer %s found at %d\n", ks_dhtrt_printableid(node->nodeid.id, buffer), ix);
 #endif
                        bucket->entries[ix].tyme = ks_time_now_sec();
-                       return KS_STATUS_SUCCESS;  /* already exists : leave flags unchanged */
+                       return &bucket->entries[ix];  /* already exists : leave flags unchanged */
                }
        }
 
@@ -1352,10 +1388,10 @@ ks_status_t ks_dhtrt_insert_id(ks_dhtrt_bucket_t *bucket, ks_dht_node_t *node)
                char buffer[100];
                ks_log(KS_LOG_DEBUG, "Inserting node %s at %d\n",  ks_dhtrt_printableid(node->nodeid.id, buffer), free);
 #endif 
-               return KS_STATUS_SUCCESS;
+               return &bucket->entries[free];
        }
 
-       return KS_STATUS_FAIL;
+       return NULL;
 }
         
 static
index b744ee78e948c9f60fbc42e70d02f8735d6121a5..f79019c50bf9907da523aa8572d0567353c63636 100644 (file)
@@ -45,7 +45,7 @@ void test01()
        ks_dht_node_t *peer1;
        
        ks_status_t status;  
-       status = ks_dhtrt_create_node(rt, homeid, KS_DHT_LOCAL, ip, port, &peer);
+       status = ks_dhtrt_create_node(rt, homeid, KS_DHT_LOCAL, ip, port, KS_DHTRT_CREATE_DEFAULT, &peer);
        if (status == KS_STATUS_FAIL) {
                printf("* **ks_dhtrt_create_node test01 failed\n");
                exit(101);
@@ -65,9 +65,9 @@ void test01()
         exit(102);
     }
 
-       status = ks_dhtrt_create_node(rt, homeid, KS_DHT_LOCAL, ip, port, &peer1);
+       status = ks_dhtrt_create_node(rt, homeid, KS_DHT_LOCAL, ip, port, KS_DHTRT_CREATE_DEFAULT, &peer1);
        if (status == KS_STATUS_FAIL) {
-               printf("**** ks_dhtrt_create_node test01 did allow duplicate createnodes!!\n");
+               printf("**** ks_dhtrt_create_node test01 did not  allow duplicate createnodes!!\n");
                exit(103);
        }
        if (peer != peer1) {
@@ -81,6 +81,44 @@ void test01()
                exit(104);
        }
 
+    /* test create_node flags */
+       /* ---------------------- */
+
+    memset(homeid.id,  0xab, KS_DHT_NODEID_SIZE);      
+    status = ks_dhtrt_create_node(rt, homeid, KS_DHT_LOCAL, ip, port, KS_DHTRT_CREATE_PING, &peer);
+
+    peer = ks_dhtrt_find_node(rt, homeid);
+    if (peer != 0)  {
+        printf("*** ks_dhtrt_find_node test01  failed. find@2 should fail\n"); fflush(stdout);
+        exit(106);
+    }
+
+    status = ks_dhtrt_create_node(rt, homeid, KS_DHT_LOCAL, ip, port, KS_DHTRT_CREATE_TOUCH, &peer);
+    peer1 = ks_dhtrt_find_node(rt, homeid);
+    if (peer1 == 0)  {
+        printf("*** ks_dhtrt_find_node test01  failed. find@3 should succeed after create w/touch\n"); fflush(stdout);
+        exit(106);
+    }
+    if (peer1 != peer) {
+        printf("*** peer != peer1 @4 - both creates should return the same node\n"); fflush(stdout);
+        exit(107);
+       }
+
+    /* ok now delete both and see what happens */
+    ks_dhtrt_delete_node(rt, peer);
+    ks_dhtrt_delete_node(rt, peer1);
+
+    memset(nodeid.id,  0xab, KS_DHT_NODEID_SIZE);
+    status = ks_dhtrt_create_node(rt, homeid, KS_DHT_LOCAL, ip, port, KS_DHTRT_CREATE_TOUCH, &peer);
+
+    peer = ks_dhtrt_find_node(rt, nodeid);
+    if (peer == 0)  {
+        printf("*** ks_dhtrt_find_node test01  failed. find@5 should succeed after create_node w/touch\n"); fflush(stdout);
+        exit(108);
+    }
+
+    ks_dhtrt_delete_node(rt, peer);
+
        printf("**** testbuckets - test01 complete\n\n\n"); fflush(stdout);
 }
 
@@ -100,39 +138,39 @@ void test02()
        ks_status_t status;
 
        nodeid.id[0] = 1;
-       status = ks_dhtrt_create_node(rt, nodeid, KS_DHT_LOCAL, ipv6, port, &peer);
+       status = ks_dhtrt_create_node(rt, nodeid, KS_DHT_LOCAL, ipv6, port, KS_DHTRT_CREATE_DEFAULT, &peer);
        ks_dhtrt_touch_node(rt, nodeid);
        nodeid.id[0] = 2;
-       status = ks_dhtrt_create_node(rt,  nodeid,  KS_DHT_REMOTE, ipv6, port, &peer);
+       status = ks_dhtrt_create_node(rt,  nodeid,  KS_DHT_REMOTE, ipv6, port, KS_DHTRT_CREATE_DEFAULT, &peer);
        ks_dhtrt_touch_node(rt, nodeid);
        nodeid.id[0] = 3;
-       status = ks_dhtrt_create_node(rt,  nodeid, KS_DHT_REMOTE, ipv6, port, &peer);
+       status = ks_dhtrt_create_node(rt,  nodeid, KS_DHT_REMOTE, ipv6, port, KS_DHTRT_CREATE_DEFAULT, &peer);
        ks_dhtrt_touch_node(rt, nodeid);
        nodeid.id[0] = 4;
-       status = ks_dhtrt_create_node(rt,  nodeid, KS_DHT_LOCAL, ipv6, port, &peer);
+       status = ks_dhtrt_create_node(rt,  nodeid, KS_DHT_LOCAL, ipv6, port, KS_DHTRT_CREATE_DEFAULT, &peer);
        ks_dhtrt_touch_node(rt, nodeid);
        nodeid.id[1] = 1;
-       status = ks_dhtrt_create_node(rt,  nodeid, KS_DHT_REMOTE, ipv6, port, &peer);
+       status = ks_dhtrt_create_node(rt,  nodeid, KS_DHT_REMOTE, ipv6, port, KS_DHTRT_CREATE_DEFAULT, &peer);
        ks_dhtrt_touch_node(rt, nodeid);
 
 
        nodeid.id[19] = 1;
-       status = ks_dhtrt_create_node(rt,  nodeid, KS_DHT_REMOTE, ipv4, port, &peer);
+       status = ks_dhtrt_create_node(rt,  nodeid, KS_DHT_REMOTE, ipv4, port, KS_DHTRT_CREATE_DEFAULT, &peer);
        ks_dhtrt_touch_node(rt, nodeid);
        nodeid.id[19] = 2;
-       status = ks_dhtrt_create_node(rt,  nodeid, KS_DHT_REMOTE, ipv4, port, &peer);
+       status = ks_dhtrt_create_node(rt,  nodeid, KS_DHT_REMOTE, ipv4, port, KS_DHTRT_CREATE_DEFAULT, &peer);
        ks_dhtrt_touch_node(rt, nodeid);
        nodeid.id[19] = 3;
-       status = ks_dhtrt_create_node(rt,  nodeid, KS_DHT_REMOTE, ipv4, port, &peer);
+       status = ks_dhtrt_create_node(rt,  nodeid, KS_DHT_REMOTE, ipv4, port, KS_DHTRT_CREATE_DEFAULT, &peer);
        ks_dhtrt_touch_node(rt, nodeid);
        nodeid.id[19] = 4;
-       status = ks_dhtrt_create_node(rt,  nodeid,  KS_DHT_LOCAL, ipv4, port, &peer);
+       status = ks_dhtrt_create_node(rt,  nodeid,  KS_DHT_LOCAL, ipv4, port, KS_DHTRT_CREATE_DEFAULT, &peer);
        ks_dhtrt_touch_node(rt, nodeid);
 
        nodeid.id[19] = 5;
-       status = ks_dhtrt_create_node(rt,  nodeid, KS_DHT_REMOTE, ipv4, port, &peer);
+       status = ks_dhtrt_create_node(rt,  nodeid, KS_DHT_REMOTE, ipv4, port, KS_DHTRT_CREATE_DEFAULT, &peer);
        nodeid.id[19] = 6;
-       status = ks_dhtrt_create_node(rt,  nodeid,  KS_DHT_LOCAL, ipv4, port, &peer);
+       status = ks_dhtrt_create_node(rt,  nodeid,  KS_DHT_LOCAL, ipv4, port, KS_DHTRT_CREATE_DEFAULT, &peer);
 
        int qcount = doquery(rt, nodeid.id, KS_DHT_LOCAL, both);
        printf("\n* **local query count expected 3, actual %d\n", qcount); fflush(stdout);
@@ -191,45 +229,45 @@ void test03()
 
        for (int i=0; i<200; ++i) {
                if (i%10 == 0) {
-       ++nodeid.id[0];
-       nodeid.id[1] = 0;
+                       ++nodeid.id[0];
+                       nodeid.id[1] = 0;
                }
                else {
-        ++nodeid.id[1];
+                       ++nodeid.id[1];
                } 
-               ks_status_t s0 = ks_dhtrt_create_node(rt, nodeid, KS_DHT_REMOTE, ipv4, port, &peer);
-       if (s0 == KS_STATUS_SUCCESS) {
-       ks_dhtrt_touch_node(rt, nodeid);
-       ++ipv4_remote;
+               ks_status_t s0 = ks_dhtrt_create_node(rt, nodeid, KS_DHT_REMOTE, ipv4, port, KS_DHTRT_CREATE_DEFAULT, &peer);
+               if (s0 == KS_STATUS_SUCCESS) {
+                       ks_dhtrt_touch_node(rt, nodeid);
+                       ++ipv4_remote;
                }
        }
 
  
        for (int i=0; i<2; ++i) {
-       if (i%10 == 0) {
-       ++nodeid.id[0];
-       nodeid.id[1] = 0;
+               if (i%10 == 0) {
+                       ++nodeid.id[0];
+                       nodeid.id[1] = 0;
                }
                else {
-       ++nodeid.id[1];
+                       ++nodeid.id[1];
                }
 
-               ks_status_t s0 = ks_dhtrt_create_node(rt, nodeid, KS_DHT_LOCAL, ipv4, port, &peer);
+               ks_status_t s0 = ks_dhtrt_create_node(rt, nodeid, KS_DHT_LOCAL, ipv4, port, KS_DHTRT_CREATE_DEFAULT,  &peer);
                if (s0 == KS_STATUS_SUCCESS) {
-       ks_dhtrt_touch_node(rt, nodeid);
-       ++ipv4_local;
+                       ks_dhtrt_touch_node(rt, nodeid);
+                       ++ipv4_local;
                }
        }
 
        for (int i=0; i<201; ++i) {
                if (i%10 == 0) {
-       ++nodeid.id[0];
-       nodeid.id[1] = 0;
+                       ++nodeid.id[0];
+                       nodeid.id[1] = 0;
                }
                else {
-       ++nodeid.id[1];
+                       ++nodeid.id[1];
                }
-               ks_dhtrt_create_node(rt, nodeid, KS_DHT_REMOTE, ipv6, port, &peer);
+               ks_dhtrt_create_node(rt, nodeid, KS_DHT_REMOTE, ipv6, port, KS_DHTRT_CREATE_DEFAULT, &peer);
                ks_dhtrt_touch_node(rt, nodeid);
        }
 
@@ -297,7 +335,7 @@ void test04()
                else {
        ++nodeid.id[1];
                }
-               ks_dhtrt_create_node(rt, nodeid, KS_DHT_REMOTE, ipv4, port, &peer);
+               ks_dhtrt_create_node(rt, nodeid, KS_DHT_REMOTE, ipv4, port, KS_DHTRT_CREATE_DEFAULT, &peer);
                ks_dhtrt_touch_node(rt, nodeid);
        }
 
@@ -332,7 +370,7 @@ void test05()
        char ipv4[] = "123.123.123.123";
        unsigned short port = 7001;
 
-       ks_dhtrt_create_node(rt, nodeid, KS_DHT_REMOTE, ipv4, port, &peer);
+       ks_dhtrt_create_node(rt, nodeid, KS_DHT_REMOTE, ipv4, port, KS_DHTRT_CREATE_DEFAULT, &peer);
     ks_dhtrt_touch_node(rt, nodeid);
        
        peer1 = ks_dhtrt_find_node(rt, nodeid);
@@ -404,7 +442,7 @@ void test06()
        char ipv4[] = "123.123.123.123";
        unsigned short port = 7000;
 
-       ks_dhtrt_create_node(rt, g_nodeid1, KS_DHT_REMOTE, ipv4, port, &peer);  // lock=1
+       ks_dhtrt_create_node(rt, g_nodeid1, KS_DHT_REMOTE, ipv4, port, KS_DHTRT_CREATE_DEFAULT, &peer);  // lock=1
        ks_dhtrt_touch_node(rt, g_nodeid1);
 
        ks_dht_node_t  *peer2 = ks_dhtrt_find_node(rt, g_nodeid1);   //lock=2
@@ -458,7 +496,7 @@ void test07()
            else {
                        ++ g_nodeid2.id[19];
                }
-               ks_dhtrt_create_node(rt, g_nodeid2, KS_DHT_REMOTE, ipv4, port, &peer);
+               ks_dhtrt_create_node(rt, g_nodeid2, KS_DHT_REMOTE, ipv4, port, KS_DHTRT_CREATE_DEFAULT, &peer);
                ks_dhtrt_touch_node(rt, g_nodeid2);
                ks_dhtrt_release_node(peer);
         }
@@ -521,8 +559,8 @@ static void *test60ex2(ks_thread_t *thread, void *data)
                ks_sleep(10000);
        
                for (int i=0; i<query.count; ++i) {
-       ks_dhtrt_release_node(query.nodes[i]);
-       ks_sleep(10000);
+                       ks_dhtrt_release_node(query.nodes[i]);
+                       ks_sleep(10000);
                } 
                ks_sleep(2000000);
 
@@ -552,19 +590,19 @@ static void *test60ex(ks_thread_t *thread, void *data)
        for (int loop=0; loop<test60loops; ++loop) {
 
                for (int i=0; i<test60nodes; ++i) {
-       ++nodeid.id[19];
-       ks_dhtrt_create_node(rt, nodeid, KS_DHT_LOCAL, ipv4, port, &peer);
-       ks_sleep(1000);
-       ks_dhtrt_touch_node(rt, nodeid);
+                       ++nodeid.id[19];
+                       ks_dhtrt_create_node(rt, nodeid, KS_DHT_LOCAL, ipv4, port, KS_DHTRT_CREATE_DEFAULT, &peer);
+                       ks_sleep(1000);
+                       ks_dhtrt_touch_node(rt, nodeid);
                }
 
                for (int i=0; i<test60nodes; ++i) {
-       peer = ks_dhtrt_find_node(rt, nodeid);
-       if (peer) {
-               ks_dhtrt_delete_node(rt, peer);
-               ks_sleep(400);
-       }
-       --nodeid.id[19];
+                       peer = ks_dhtrt_find_node(rt, nodeid);
+                       if (peer) {
+                               ks_dhtrt_delete_node(rt, peer);
+                               ks_sleep(400);
+                       }
+                       --nodeid.id[19];
                }
 
        }
@@ -628,44 +666,44 @@ void test30()
 
        for (int i=0; i<200; ++i) {
                if (i%10 == 0) {
-       ++nodeid.id[0];
-       nodeid.id[1] = 0;
+                       ++nodeid.id[0];
+                       nodeid.id[1] = 0;
                }
                else {
-       ++nodeid.id[1];
+                       ++nodeid.id[1];
                }
-               ks_status_t s0 = ks_dhtrt_create_node(rt, nodeid, KS_DHT_REMOTE, ipv4, port, &peer);
+               ks_status_t s0 = ks_dhtrt_create_node(rt, nodeid, KS_DHT_REMOTE, ipv4, port, KS_DHTRT_CREATE_DEFAULT, &peer);
                if (s0 == KS_STATUS_SUCCESS) {
-       ks_dhtrt_touch_node(rt, nodeid);
-       ++ipv4_remote;
+                       ks_dhtrt_touch_node(rt, nodeid);
+                       ++ipv4_remote;
                }
        }
 
        for (int i=0; i<2; ++i) {
                if (i%10 == 0) {
-       ++nodeid.id[0];
-       nodeid.id[1] = 0;
+                       ++nodeid.id[0];
+                       nodeid.id[1] = 0;
                }
                else {
-       ++nodeid.id[1];
+                       ++nodeid.id[1];
                }
 
-               ks_status_t s0 = ks_dhtrt_create_node(rt, nodeid, KS_DHT_LOCAL, ipv4, port, &peer);
+               ks_status_t s0 = ks_dhtrt_create_node(rt, nodeid, KS_DHT_LOCAL, ipv4, port, KS_DHTRT_CREATE_DEFAULT, &peer);
                if (s0 == KS_STATUS_SUCCESS) {
-       ks_dhtrt_touch_node(rt, nodeid);
-       ++ipv4_local;
+                       ks_dhtrt_touch_node(rt, nodeid);
+                       ++ipv4_local;
                }
        }
 
        for (int i=0; i<201; ++i) {
                if (i%10 == 0) {
-       ++nodeid.id[0];
-       nodeid.id[1] = 0;
+                       ++nodeid.id[0];
+                       nodeid.id[1] = 0;
                }
                else {
-       ++nodeid.id[1];
+                       ++nodeid.id[1];
                }
-               ks_dhtrt_create_node(rt, nodeid, KS_DHT_REMOTE, ipv6, port, &peer);
+               ks_dhtrt_create_node(rt, nodeid, KS_DHT_REMOTE, ipv6, port, KS_DHTRT_CREATE_DEFAULT, &peer);
                ks_dhtrt_touch_node(rt, nodeid);
        }
 
@@ -710,41 +748,41 @@ void test50()
 
        for (int i=0,i2=0; i<200; ++i, ++i2) {
                if (i%20 == 0) {
-       nodeid.id[0] =  nodeid.id[0] / 2;
-       if (i2%20 == 0) {
-               i2 = 0;
-               nodeid.id[1] =  nodeid.id[1] / 2;
-       }
-       else {
-               ++nodeid.id[2];
-       }
+                       nodeid.id[0] =  nodeid.id[0] / 2;
+                       if (i2%20 == 0) {
+                               i2 = 0;
+                               nodeid.id[1] =  nodeid.id[1] / 2;
+                       }
+                       else {
+                               ++nodeid.id[2];
+                       }
                }
                else {
-       ++nodeid.id[1];
+                       ++nodeid.id[1];
                }
-               ks_dhtrt_create_node(rt, nodeid, KS_DHT_REMOTE, ipv4, port, &peer);
+               ks_dhtrt_create_node(rt, nodeid, KS_DHT_REMOTE, ipv4, port, KS_DHTRT_CREATE_DEFAULT, &peer);
                ks_dhtrt_touch_node(rt, nodeid);
        }
 
        memset(nodeid.id,  0xef, KS_DHT_NODEID_SIZE);
        for (int i=0,i2=0; i<200; ++i, ++i2) {
-       if (i%20 == 0) { 
-       nodeid.id[0] =  nodeid.id[0] / 2;
-       if (i2%20 == 0) {
-               i2 = 0; 
-               nodeid.id[1] =  nodeid.id[1] / 2;
-       }
-       else {
-               ++nodeid.id[2];
-       }
+               if (i%20 == 0) { 
+                       nodeid.id[0] =  nodeid.id[0] / 2;
+                       if (i2%20 == 0) {
+                               i2 = 0; 
+                               nodeid.id[1] =  nodeid.id[1] / 2;
+                       }
+                       else {
+                               ++nodeid.id[2];
+                       }
                }
                else {
-       ++nodeid.id[1];
+                       ++nodeid.id[1];
                }
                ks_dht_node_t *n = ks_dhtrt_find_node(rt, nodeid);
                if (n != NULL) {
-       ks_dhtrt_release_node(n);
-       ks_dhtrt_delete_node(rt, n);
+                       ks_dhtrt_release_node(n);
+                       ks_dhtrt_delete_node(rt, n);
                }
        }
 
@@ -754,19 +792,19 @@ void test50()
 
        for (int i=0,i2=0; i<200; ++i, ++i2) {
                if (i%20 == 0) {
-       nodeid.id[0] =  nodeid.id[0] / 2;
-       if (i2%20 == 0) {
-               i2 = 0;
-               nodeid.id[1] =  nodeid.id[1] / 2;
-       }
-       else {
-               ++nodeid.id[2];
-       }
+                       nodeid.id[0] =  nodeid.id[0] / 2;
+                       if (i2%20 == 0) {
+                               i2 = 0;
+                               nodeid.id[1] =  nodeid.id[1] / 2;
+                       }
+                       else {
+                               ++nodeid.id[2];
+                       }
                }
                else {
-       ++nodeid.id[1];
+                       ++nodeid.id[1];
                }
-               ks_dhtrt_create_node(rt, nodeid, KS_DHT_REMOTE, ipv4, port, &peer);
+               ks_dhtrt_create_node(rt, nodeid, KS_DHT_REMOTE, ipv4, port, KS_DHTRT_CREATE_DEFAULT, &peer);
                ks_dhtrt_touch_node(rt, nodeid);
        }
 
@@ -794,19 +832,19 @@ void test51()
 
        for (int i=0,i2=0; i<2; ++i, ++i2) {
                if (i%20 == 0) {
-       nodeid.id[0] =  nodeid.id[0] / 2;
-       if (i2%20 == 0) {
-               i2 = 0;
-               nodeid.id[1] =  nodeid.id[1] / 2;
-       }
-       else {
-               ++nodeid.id[2];
-       }
+                       nodeid.id[0] =  nodeid.id[0] / 2;
+                       if (i2%20 == 0) {
+                               i2 = 0;
+                               nodeid.id[1] =  nodeid.id[1] / 2;
+                       }
+                       else {
+                               ++nodeid.id[2];
+                       }
                }
                else {
-       ++nodeid.id[1];
+                       ++nodeid.id[1];
                }
-               ks_dhtrt_create_node(rt, nodeid, KS_DHT_REMOTE, ipv4, port, &peer);
+               ks_dhtrt_create_node(rt, nodeid, KS_DHT_REMOTE, ipv4, port, KS_DHTRT_CREATE_DEFAULT, &peer);
                ks_dhtrt_touch_node(rt, nodeid);
        }
 
@@ -875,45 +913,45 @@ int main(int argc, char *argv[]) {
        for (int tix=0; tix<argc; ++tix) {
 
                if (tests[tix] == 1) {
-       ks_dhtrt_initroute(&rt, dht, pool);
-       test01();
-       ks_dhtrt_deinitroute(&rt);
-       continue;
+                       ks_dhtrt_initroute(&rt, dht, pool);
+                       test01();
+                       ks_dhtrt_deinitroute(&rt);
+                       continue;
                }
 
                if (tests[tix] == 2) {
-       ks_dhtrt_initroute(&rt, dht, pool);
-       test02();
-       ks_dhtrt_deinitroute(&rt);
-       continue;
+                       ks_dhtrt_initroute(&rt, dht, pool);
+                       test02();
+                       ks_dhtrt_deinitroute(&rt);
+                       continue;
                }
 
                if (tests[tix] == 3) {  
-       ks_dhtrt_initroute(&rt, dht, pool);
-       test03();
-       ks_dhtrt_deinitroute(&rt);
-       continue; 
+                       ks_dhtrt_initroute(&rt, dht, pool);
+                       test03();
+                       ks_dhtrt_deinitroute(&rt);
+                       continue; 
                }
 
                if (tests[tix] == 4) {
-       ks_dhtrt_initroute(&rt, dht, pool);
-       test04();
-       ks_dhtrt_deinitroute(&rt);
-       continue;
+                       ks_dhtrt_initroute(&rt, dht, pool);
+                       test04();
+                       ks_dhtrt_deinitroute(&rt);
+                       continue;
                }
 
                if (tests[tix] == 5) {
-       ks_dhtrt_initroute(&rt, dht, pool);
-       test05();
-       ks_dhtrt_deinitroute(&rt);
-       continue;
+                       ks_dhtrt_initroute(&rt, dht, pool);
+                       test05();
+                       ks_dhtrt_deinitroute(&rt);
+                       continue;
                }
 
                if (tests[tix] == 6) {
-       ks_dhtrt_initroute(&rt, dht, pool);
-       test06();
-       ks_dhtrt_deinitroute(&rt);
-       continue;
+                       ks_dhtrt_initroute(&rt, dht, pool);
+                       test06();
+                       ks_dhtrt_deinitroute(&rt);
+                       continue;
                }
 
 
@@ -925,39 +963,39 @@ int main(int argc, char *argv[]) {
             }
 
                if (tests[tix] == 30) {
-       ks_dhtrt_initroute(&rt, dht, pool);
-       test30();
-       ks_dhtrt_deinitroute(&rt);
-       continue;
+                       ks_dhtrt_initroute(&rt, dht, pool);
+                       test30();
+                       ks_dhtrt_deinitroute(&rt);
+                       continue;
                }
 
 
                if (tests[tix] == 50) {
-       ks_dhtrt_initroute(&rt, dht, pool);
-       test50();
-       ks_dhtrt_deinitroute(&rt);
-       continue;
+                       ks_dhtrt_initroute(&rt, dht, pool);
+                       test50();
+                       ks_dhtrt_deinitroute(&rt);
+                       continue;
                }
 
                if (tests[tix] == 51) {
-       ks_dhtrt_initroute(&rt, dht, pool);
-       test51();
-       ks_dhtrt_deinitroute(&rt);
-       continue;
+                       ks_dhtrt_initroute(&rt, dht, pool);
+                       test51();
+                       ks_dhtrt_deinitroute(&rt);
+                       continue;
                }
 
                if (tests[tix] == 60) {
-       ks_dhtrt_initroute(&rt, dht, pool);
-       test60();
-       ks_dhtrt_deinitroute(&rt);
-       continue;
+                       ks_dhtrt_initroute(&rt, dht, pool);
+                       test60();
+                       ks_dhtrt_deinitroute(&rt);
+                       continue;
                }
 
                if (tests[tix] == 99) {
-       ks_dhtrt_initroute(&rt, dht, pool);
-       //testnodelocking();
-       ks_dhtrt_deinitroute(&rt);
-       continue;
+                       ks_dhtrt_initroute(&rt, dht, pool);
+                       //testnodelocking();
+                       ks_dhtrt_deinitroute(&rt);
+                       continue;
                }