From: Jordan Lee <jordan@transmissionbt.com>
Date: Mon, 5 May 2014 20:45:14 +0000 (+0000)
Subject: (trunk) #5671 'dht-0.22': update third-party/dht.c to Juliusz Chroboczek's upstream... 
X-Git-Tag: 2.83~12
X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=6ee973aaac1cf7d919ae7ecd2fe1054c3fe0d7f6;p=transmission

(trunk) #5671 'dht-0.22': update third-party/dht.c to Juliusz Chroboczek's upstream v0.22
---

diff --git a/libtransmission/tr-dht.c b/libtransmission/tr-dht.c
index 436dcb7d0..6b00fe157 100644
--- a/libtransmission/tr-dht.c
+++ b/libtransmission/tr-dht.c
@@ -514,7 +514,7 @@ tr_dhtPrintableStatus (int status)
 
 static void
 callback (void *ignore UNUSED, int event,
-          unsigned char *info_hash, void *data, size_t data_len)
+          const unsigned char *info_hash, const void *data, size_t data_len)
 {
     if (event == DHT_EVENT_VALUES || event == DHT_EVENT_VALUES6) {
         tr_torrent *tor;
diff --git a/third-party/dht/CHANGES b/third-party/dht/CHANGES
index 0c69ac4de..6904abd60 100644
--- a/third-party/dht/CHANGES
+++ b/third-party/dht/CHANGES
@@ -1,3 +1,13 @@
+3 May 2014: dht-0.22
+
+  * INCOMPATIBLE CHANGE: the callback now takes const arguments.
+  * Consult the local storage when performing a search, which should
+    make bootstrapping of tiny DHTs easier.  Note that we're still not
+    performing local stores, since that would require knowing our IP
+    address.
+  * Don't attempt to flush the debug stream if debugging is disabled.
+    This appears to work around a bug in Transmission.
+
 25 July 2011: dht-0.21
 
   * Blacklisting support.
diff --git a/third-party/dht/dht-example.c b/third-party/dht/dht-example.c
index dc69e2b43..7ab08b6c2 100644
--- a/third-party/dht/dht-example.c
+++ b/third-party/dht/dht-example.c
@@ -79,8 +79,8 @@ const unsigned char hash[20] = {
 static void
 callback(void *closure,
          int event,
-         unsigned char *info_hash,
-         void *data, size_t data_len)
+         const unsigned char *info_hash,
+         const void *data, size_t data_len)
 {
     if(event == DHT_EVENT_SEARCH_DONE)
         printf("Search done.\n");
diff --git a/third-party/dht/dht.c b/third-party/dht/dht.c
index fa7a959c1..61522bff8 100644
--- a/third-party/dht/dht.c
+++ b/third-party/dht/dht.c
@@ -212,6 +212,7 @@ struct storage {
     struct storage *next;
 };
 
+static struct storage * find_storage(const unsigned char *id);
 static void flush_search_node(struct search_node *n, struct search *sr);
 
 static int send_ping(const struct sockaddr *sa, int salen,
@@ -326,11 +327,11 @@ debugf(const char *format, ...)
 {
     va_list args;
     va_start(args, format);
-    if(dht_debug) {
+    if(dht_debug)
         vfprintf(dht_debug, format, args);
-        fflush(dht_debug);
-    }
     va_end(args);
+    if(dht_debug)
+        fflush(dht_debug);
 }
 
 static void
@@ -1193,6 +1194,7 @@ dht_search(const unsigned char *id, int port, int af,
            dht_callback *callback, void *closure)
 {
     struct search *sr;
+    struct storage *st;
     struct bucket *b = find_bucket(id, af);
 
     if(b == NULL) {
@@ -1200,6 +1202,36 @@ dht_search(const unsigned char *id, int port, int af,
         return -1;
     }
 
+    /* Try to answer this search locally.  In a fully grown DHT this
+       is very unlikely, but people are running modified versions of
+       this code in private DHTs with very few nodes.  What's wrong
+       with flooding? */
+    if(callback) {
+        st = find_storage(id);
+        if(st) {
+            unsigned short swapped;
+            unsigned char buf[18];
+            int i;
+
+            debugf("Found local data (%d peers).\n", st->numpeers);
+
+            for(i = 0; i < st->numpeers; i++) {
+                swapped = htons(st->peers[i].port);
+                if(st->peers[i].len == 4) {
+                    memcpy(buf, st->peers[i].ip, 4);
+                    memcpy(buf + 4, &swapped, 2);
+                    (*callback)(closure, DHT_EVENT_VALUES, id,
+                                (void*)buf, 6);
+                } else if(st->peers[i].len == 16) {
+                    memcpy(buf, st->peers[i].ip, 16);
+                    memcpy(buf + 16, &swapped, 2);
+                    (*callback)(closure, DHT_EVENT_VALUES6, id,
+                                (void*)buf, 18);
+                }
+            }
+        }
+    }
+
     sr = searches;
     while(sr) {
         if(sr->af == af && id_cmp(sr->id, id) == 0)
diff --git a/third-party/dht/dht.h b/third-party/dht/dht.h
index f88e46b29..2a0c63323 100644
--- a/third-party/dht/dht.h
+++ b/third-party/dht/dht.h
@@ -22,8 +22,8 @@ THE SOFTWARE.
 
 typedef void
 dht_callback(void *closure, int event,
-             unsigned char *info_hash,
-             void *data, size_t data_len);
+             const unsigned char *info_hash,
+             const void *data, size_t data_len);
 
 #define DHT_EVENT_NONE 0
 #define DHT_EVENT_VALUES 1