2 * transsip - the telephony network
3 * By Daniel Borkmann <daniel@transsip.org>
4 * Copyright 2011 Daniel Borkmann <dborkma@tik.ee.ethz.ch>,
5 * Swiss federal institute of technology (ETH Zurich)
6 * Subject to the GPL, version 2.
10 * Copyright (C) 2011 Daniel Borkmann (cleanups, improvements)
11 * Copyright (c) 2009-2011 by Juliusz Chroboczek
13 * Permission is hereby granted, free of charge, to any person obtaining a copy
14 * of this software and associated documentation files (the "Software"), to deal
15 * in the Software without restriction, including without limitation the rights
16 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
17 * copies of the Software, and to permit persons to whom the Software is
18 * furnished to do so, subject to the following conditions:
20 * The above copyright notice and this permission notice shall be included in
21 * all copies or substantial portions of the Software.
23 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
24 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
26 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
28 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
44 #include <arpa/inet.h>
45 #include <sys/types.h>
46 #include <sys/socket.h>
47 #include <netinet/in.h>
50 #define WINVER WindowsXP
68 #define EAFNOSUPPORT WSAEAFNOSUPPORT
70 set_nonblocking(int fd
, int nonblocking
)
74 unsigned long mode
= !!nonblocking
;
75 rc
= ioctlsocket(fd
, FIONBIO
, &mode
);
77 errno
= WSAGetLastError();
78 return (rc
== 0 ? 0 : -1);
86 extern const char *inet_ntop(int, const void *, char *, socklen_t
);
91 set_nonblocking(int fd
, int nonblocking
)
94 rc
= fcntl(fd
, F_GETFL
, 0);
98 rc
= fcntl(fd
, F_SETFL
, nonblocking
?(rc
| O_NONBLOCK
):(rc
& ~O_NONBLOCK
));
107 /* We set sin_family to 0 to mark unused slots. */
108 #if AF_INET == 0 || AF_INET6 == 0
112 #if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
114 #elif defined(__GNUC__)
115 #define inline __inline
117 #define restrict __restrict
119 #define restrict /**/
123 #define restrict /**/
126 #define MAX(x, y) ((x) >= (y) ? (x) : (y))
127 #define MIN(x, y) ((x) <= (y) ? (x) : (y))
130 unsigned char id
[20];
131 struct sockaddr_storage ss
;
133 time_t time
; /* time of last message received */
134 time_t reply_time
; /* time of last correct reply received */
135 time_t pinged_time
; /* time of last request */
136 int pinged
; /* how many requests we sent since last reply */
142 unsigned char first
[20];
143 int count
; /* number of nodes */
144 int time
; /* time of last reply in this bucket */
146 struct sockaddr_storage cached
; /* the address of a likely candidate */
152 unsigned char id
[20];
153 struct sockaddr_storage ss
;
155 time_t request_time
; /* the time of the last unanswered request */
156 time_t reply_time
; /* the time of the last reply */
158 unsigned char token
[40];
160 int replied
; /* whether we have received a reply */
161 int acked
; /* whether they acked our announcement */
164 /* When performing a search, we search for up to SEARCH_NODES closest nodes
165 to the destination, and use the additional ones to backtrack if any of
166 the target 8 turn out to be dead. */
167 #define SEARCH_NODES 14
172 time_t step_time
; /* the time of the last search_step */
173 unsigned char id
[20];
174 unsigned short port
; /* 0 for pure searches */
176 struct search_node nodes
[SEARCH_NODES
];
183 unsigned char ip
[16];
188 /* The maximum number of peers we store for a given hash. */
189 #ifndef DHT_MAX_PEERS
190 #define DHT_MAX_PEERS 2048
193 /* The maximum number of hashes we're willing to track. */
194 #ifndef DHT_MAX_HASHES
195 #define DHT_MAX_HASHES 16384
198 /* The maximum number of searches we keep data about. */
199 #ifndef DHT_MAX_SEARCHES
200 #define DHT_MAX_SEARCHES 1024
203 /* The time after which we consider a search to be expirable. */
204 #ifndef DHT_SEARCH_EXPIRE_TIME
205 #define DHT_SEARCH_EXPIRE_TIME (62 * 60)
209 unsigned char id
[20];
210 int numpeers
, maxpeers
;
212 struct storage
*next
;
215 static void flush_search_node(struct search_node
*n
, struct search
*sr
);
217 static int send_ping(const struct sockaddr
*sa
, int salen
,
218 const unsigned char *tid
, int tid_len
);
219 static int send_pong(const struct sockaddr
*sa
, int salen
,
220 const unsigned char *tid
, int tid_len
);
221 static int send_find_node(const struct sockaddr
*sa
, int salen
,
222 const unsigned char *tid
, int tid_len
,
223 const unsigned char *target
, int want
, int confirm
);
224 static int send_nodes_peers(const struct sockaddr
*sa
, int salen
,
225 const unsigned char *tid
, int tid_len
,
226 const unsigned char *nodes
, int nodes_len
,
227 const unsigned char *nodes6
, int nodes6_len
,
228 int af
, struct storage
*st
,
229 const unsigned char *token
, int token_len
);
230 static int send_closest_nodes(const struct sockaddr
*sa
, int salen
,
231 const unsigned char *tid
, int tid_len
,
232 const unsigned char *id
, int want
,
233 int af
, struct storage
*st
,
234 const unsigned char *token
, int token_len
);
235 static int send_get_peers(const struct sockaddr
*sa
, int salen
,
236 unsigned char *tid
, int tid_len
,
237 unsigned char *infohash
, int want
, int confirm
);
238 static int send_announce_peer(const struct sockaddr
*sa
, int salen
,
239 unsigned char *tid
, int tid_len
,
240 unsigned char *infohas
, unsigned short port
,
241 unsigned char *token
, int token_len
, int confirm
);
242 static int send_peer_announced(const struct sockaddr
*sa
, int salen
,
243 unsigned char *tid
, int tid_len
);
244 static int send_error(const struct sockaddr
*sa
, int salen
,
245 unsigned char *tid
, int tid_len
,
246 int code
, const char *message
);
253 #define ANNOUNCE_PEER 5
258 static int parse_message(const unsigned char *buf
, int buflen
,
259 unsigned char *tid_return
, int *tid_len
,
260 unsigned char *id_return
,
261 unsigned char *info_hash_return
,
262 unsigned char *target_return
,
263 unsigned short *port_return
,
264 unsigned char *token_return
, int *token_len
,
265 unsigned char *nodes_return
, int *nodes_len
,
266 unsigned char *nodes6_return
, int *nodes6_len
,
267 unsigned char *values_return
, int *values_len
,
268 unsigned char *values6_return
, int *values6_len
,
271 static const unsigned char zeroes
[20] = {0};
272 static const unsigned char ones
[20] = {
273 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
274 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
275 0xFF, 0xFF, 0xFF, 0xFF
277 static const unsigned char v4prefix
[16] = {
278 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF, 0, 0, 0, 0
281 static int dht_socket
= -1;
282 static int dht_socket6
= -1;
284 static time_t search_time
;
285 static time_t confirm_nodes_time
;
286 static time_t rotate_secrets_time
;
288 static unsigned char myid
[20];
289 static int have_v
= 0;
290 static unsigned char my_v
[9];
291 static unsigned char secret
[8];
292 static unsigned char oldsecret
[8];
294 static struct bucket
*buckets
= NULL
;
295 static struct bucket
*buckets6
= NULL
;
296 static struct storage
*storage
;
297 static int numstorage
;
299 static struct search
*searches
= NULL
;
300 static int numsearches
;
301 static unsigned short search_id
;
303 /* The maximum number of nodes that we snub. There is probably little
304 reason to increase this value. */
305 #ifndef DHT_MAX_BLACKLISTED
306 #define DHT_MAX_BLACKLISTED 10
308 static struct sockaddr_storage blacklist
[DHT_MAX_BLACKLISTED
];
309 int next_blacklisted
;
311 static struct timeval now
;
312 static time_t mybucket_grow_time
, mybucket6_grow_time
;
313 static time_t expire_stuff_time
;
315 #define MAX_TOKEN_BUCKET_TOKENS 400
316 static time_t token_bucket_time
;
317 static int token_bucket_tokens
;
319 FILE *dht_debug
= NULL
;
322 __attribute__ ((format (printf
, 1, 2)))
325 debugf(const char *format
, ...)
328 va_start(args
, format
);
330 vfprintf(dht_debug
, format
, args
);
336 debug_printable(const unsigned char *buf
, int buflen
)
340 for(i
= 0; i
< buflen
; i
++)
341 putc(buf
[i
] >= 32 && buf
[i
] <= 126 ? buf
[i
] : '.', dht_debug
);
346 print_hex(FILE *f
, const unsigned char *buf
, int buflen
)
349 for(i
= 0; i
< buflen
; i
++)
350 fprintf(f
, "%02x", buf
[i
]);
354 is_martian(const struct sockaddr
*sa
)
356 switch(sa
->sa_family
) {
358 struct sockaddr_in
*sin
= (struct sockaddr_in
*)sa
;
359 const unsigned char *address
= (const unsigned char*)&sin
->sin_addr
;
360 return sin
->sin_port
== 0 ||
362 (address
[0] == 127) ||
363 ((address
[0] & 0xE0) == 0xE0);
366 struct sockaddr_in6
*sin6
= (struct sockaddr_in6
*)sa
;
367 const unsigned char *address
= (const unsigned char*)&sin6
->sin6_addr
;
368 return sin6
->sin6_port
== 0 ||
369 (address
[0] == 0xFF) ||
370 (address
[0] == 0xFE && (address
[1] & 0xC0) == 0x80) ||
371 (memcmp(address
, zeroes
, 15) == 0 &&
372 (address
[15] == 0 || address
[15] == 1)) ||
373 (memcmp(address
, v4prefix
, 12) == 0);
381 /* Forget about the ``XOR-metric''. An id is just a path from the
382 root of the tree, so bits are numbered from the start. */
385 id_cmp(const unsigned char *restrict id1
, const unsigned char *restrict id2
)
387 /* Memcmp is guaranteed to perform an unsigned comparison. */
388 return memcmp(id1
, id2
, 20);
391 /* Find the lowest 1 bit in an id. */
393 lowbit(const unsigned char *id
)
396 for(i
= 19; i
>= 0; i
--)
403 for(j
= 7; j
>= 0; j
--)
404 if((id
[i
] & (0x80 >> j
)) != 0)
410 /* Find how many bits two ids have in common. */
412 common_bits(const unsigned char *id1
, const unsigned char *id2
)
416 for(i
= 0; i
< 20; i
++) {
424 xor = id1
[i
] ^ id2
[i
];
427 while((xor & 0x80) == 0) {
435 /* Determine whether id1 or id2 is closer to ref */
437 xorcmp(const unsigned char *id1
, const unsigned char *id2
,
438 const unsigned char *ref
)
441 for(i
= 0; i
< 20; i
++) {
442 unsigned char xor1
, xor2
;
445 xor1
= id1
[i
] ^ ref
[i
];
446 xor2
= id2
[i
] ^ ref
[i
];
455 /* We keep buckets in a sorted linked list. A bucket b ranges from
456 b->first inclusive up to b->next->first exclusive. */
458 in_bucket(const unsigned char *id
, struct bucket
*b
)
460 return id_cmp(b
->first
, id
) <= 0 &&
461 (b
->next
== NULL
|| id_cmp(id
, b
->next
->first
) < 0);
464 static struct bucket
*
465 find_bucket(unsigned const char *id
, int af
)
467 struct bucket
*b
= af
== AF_INET
? buckets
: buckets6
;
475 if(id_cmp(id
, b
->next
->first
) < 0)
481 static struct bucket
*
482 previous_bucket(struct bucket
*b
)
484 struct bucket
*p
= b
->af
== AF_INET
? buckets
: buckets6
;
498 /* Every bucket contains an unordered list of nodes. */
500 find_node(const unsigned char *id
, int af
)
502 struct bucket
*b
= find_bucket(id
, af
);
510 if(id_cmp(n
->id
, id
) == 0)
517 /* Return a random node in a bucket. */
519 random_node(struct bucket
*b
)
527 nn
= random() % b
->count
;
536 /* Return the middle id of a bucket. */
538 bucket_middle(struct bucket
*b
, unsigned char *id_return
)
540 int bit1
= lowbit(b
->first
);
541 int bit2
= b
->next
? lowbit(b
->next
->first
) : -1;
542 int bit
= MAX(bit1
, bit2
) + 1;
547 memcpy(id_return
, b
->first
, 20);
548 id_return
[bit
/ 8] |= (0x80 >> (bit
% 8));
552 /* Return a random id within a bucket. */
554 bucket_random(struct bucket
*b
, unsigned char *id_return
)
556 int bit1
= lowbit(b
->first
);
557 int bit2
= b
->next
? lowbit(b
->next
->first
) : -1;
558 int bit
= MAX(bit1
, bit2
) + 1;
562 memcpy(id_return
, b
->first
, 20);
566 memcpy(id_return
, b
->first
, bit
/ 8);
567 id_return
[bit
/ 8] = b
->first
[bit
/ 8] & (0xFF00 >> (bit
% 8));
568 id_return
[bit
/ 8] |= random() & 0xFF >> (bit
% 8);
569 for(i
= bit
/ 8 + 1; i
< 20; i
++)
570 id_return
[i
] = random() & 0xFF;
574 /* Insert a new node into a bucket. */
576 insert_node(struct node
*node
)
578 struct bucket
*b
= find_bucket(node
->id
, node
->ss
.ss_family
);
583 node
->next
= b
->nodes
;
589 /* This is our definition of a known-good node. */
591 node_good(struct node
*node
)
595 node
->reply_time
>= now
.tv_sec
- 7200 &&
596 node
->time
>= now
.tv_sec
- 900;
599 /* Our transaction-ids are 4-bytes long, with the first two bytes identi-
600 fying the kind of request, and the remaining two a sequence number in
604 make_tid(unsigned char *tid_return
, const char *prefix
, unsigned short seqno
)
606 tid_return
[0] = prefix
[0] & 0xFF;
607 tid_return
[1] = prefix
[1] & 0xFF;
608 memcpy(tid_return
+ 2, &seqno
, 2);
612 tid_match(const unsigned char *tid
, const char *prefix
,
613 unsigned short *seqno_return
)
615 if(tid
[0] == (prefix
[0] & 0xFF) && tid
[1] == (prefix
[1] & 0xFF)) {
617 memcpy(seqno_return
, tid
+ 2, 2);
623 /* Every bucket caches the address of a likely node. Ping it. */
625 send_cached_ping(struct bucket
*b
)
627 unsigned char tid
[4];
629 /* We set family to 0 when there's no cached node. */
630 if(b
->cached
.ss_family
== 0)
633 debugf("Sending ping to cached node.\n");
634 make_tid(tid
, "pn", 0);
635 rc
= send_ping((struct sockaddr
*)&b
->cached
, b
->cachedlen
, tid
, 4);
636 b
->cached
.ss_family
= 0;
641 /* Called whenever we send a request to a node, increases the ping count
642 and, if that reaches 3, sends a ping to a new candidate. */
644 pinged(struct node
*n
, struct bucket
*b
)
647 n
->pinged_time
= now
.tv_sec
;
649 send_cached_ping(b
? b
: find_bucket(n
->id
, n
->ss
.ss_family
));
652 /* The internal blacklist is an LRU cache of nodes that have sent
653 incorrect messages. */
655 blacklist_node(const unsigned char *id
, const struct sockaddr
*sa
, int salen
)
659 debugf("Blacklisting broken node.\n");
664 /* Make the node easy to discard. */
665 n
= find_node(id
, sa
->sa_family
);
670 /* Discard it from any searches in progress. */
673 for(i
= 0; i
< sr
->numnodes
; i
++)
674 if(id_cmp(sr
->nodes
[i
].id
, id
) == 0)
675 flush_search_node(&sr
->nodes
[i
], sr
);
679 /* And make sure we don't hear from it again. */
680 memcpy(&blacklist
[next_blacklisted
], sa
, salen
);
681 next_blacklisted
= (next_blacklisted
+ 1) % DHT_MAX_BLACKLISTED
;
685 node_blacklisted(const struct sockaddr
*sa
, int salen
)
689 if(salen
> sizeof(struct sockaddr_storage
))
692 if(dht_blacklisted(sa
, salen
))
695 for(i
= 0; i
< DHT_MAX_BLACKLISTED
; i
++) {
696 if(memcmp(&blacklist
[i
], sa
, salen
) == 0)
703 /* Split a bucket into two equal parts. */
704 static struct bucket
*
705 split_bucket(struct bucket
*b
)
710 unsigned char new_id
[20];
712 rc
= bucket_middle(b
, new_id
);
716 new = calloc(1, sizeof(struct bucket
));
724 memcpy(new->first
, new_id
, 20);
741 /* We just learnt about a node, not necessarily a new one. Confirm is 1 if
742 the node sent a message, 2 if it sent us a reply. */
744 new_node(const unsigned char *id
, const struct sockaddr
*sa
, int salen
,
747 struct bucket
*b
= find_bucket(id
, sa
->sa_family
);
754 if(id_cmp(id
, myid
) == 0)
757 if(is_martian(sa
) || node_blacklisted(sa
, salen
))
760 mybucket
= in_bucket(myid
, b
);
763 b
->time
= now
.tv_sec
;
767 if(id_cmp(n
->id
, id
) == 0) {
768 if(confirm
|| n
->time
< now
.tv_sec
- 15 * 60) {
769 /* Known node. Update stuff. */
770 memcpy((struct sockaddr
*)&n
->ss
, sa
, salen
);
772 n
->time
= now
.tv_sec
;
774 n
->reply_time
= now
.tv_sec
;
787 if(sa
->sa_family
== AF_INET
)
788 mybucket_grow_time
= now
.tv_sec
;
790 mybucket6_grow_time
= now
.tv_sec
;
793 /* First, try to get rid of a known-bad node. */
796 if(n
->pinged
>= 3 && n
->pinged_time
< now
.tv_sec
- 15) {
797 memcpy(n
->id
, id
, 20);
798 memcpy((struct sockaddr
*)&n
->ss
, sa
, salen
);
799 n
->time
= confirm
? now
.tv_sec
: 0;
800 n
->reply_time
= confirm
>= 2 ? now
.tv_sec
: 0;
809 /* Bucket full. Ping a dubious node */
813 /* Pick the first dubious node that we haven't pinged in the
814 last 15 seconds. This gives nodes the time to reply, but
815 tends to concentrate on the same nodes, so that we get rid
816 of bad nodes fast. */
819 if(n
->pinged_time
< now
.tv_sec
- 15) {
820 unsigned char tid
[4];
821 debugf("Sending ping to dubious node.\n");
822 make_tid(tid
, "pn", 0);
823 send_ping((struct sockaddr
*)&n
->ss
, n
->sslen
,
826 n
->pinged_time
= now
.tv_sec
;
837 /* If there's only one bucket, split eagerly. This is
838 incorrect unless there's more than 8 nodes in the DHT. */
839 else if(b
->af
== AF_INET
&& buckets
->next
== NULL
)
841 else if(b
->af
== AF_INET6
&& buckets6
->next
== NULL
)
846 debugf("Splitting.\n");
848 return new_node(id
, sa
, salen
, confirm
);
851 /* No space for this node. Cache it away for later. */
852 if(confirm
|| b
->cached
.ss_family
== 0) {
853 memcpy(&b
->cached
, sa
, salen
);
854 b
->cachedlen
= salen
;
860 /* Create a new node. */
861 n
= calloc(1, sizeof(struct node
));
864 memcpy(n
->id
, id
, 20);
865 memcpy(&n
->ss
, sa
, salen
);
867 n
->time
= confirm
? now
.tv_sec
: 0;
868 n
->reply_time
= confirm
>= 2 ? now
.tv_sec
: 0;
875 /* Called periodically to purge known-bad nodes. Note that we're very
876 conservative here: broken nodes in the table don't do much harm, we'll
877 recover as soon as we find better ones. */
879 expire_buckets(struct bucket
*b
)
885 while(b
->nodes
&& b
->nodes
->pinged
>= 4) {
895 while(p
->next
&& p
->next
->pinged
>= 4) {
910 expire_stuff_time
= now
.tv_sec
+ 120 + random() % 240;
914 /* While a search is in progress, we don't necessarily keep the nodes being
915 walked in the main bucket table. A search in progress is identified by
916 a unique transaction id, a short (and hence small enough to fit in the
917 transaction id of the protocol packets). */
919 static struct search
*
920 find_search(unsigned short tid
, int af
)
922 struct search
*sr
= searches
;
924 if(sr
->tid
== tid
&& sr
->af
== af
)
931 /* A search contains a list of nodes, sorted by decreasing distance to the
932 target. We just got a new candidate, insert it at the right spot or
936 insert_search_node(unsigned char *id
,
937 const struct sockaddr
*sa
, int salen
,
938 struct search
*sr
, int replied
,
939 unsigned char *token
, int token_len
)
941 struct search_node
*n
;
944 if(sa
->sa_family
!= sr
->af
) {
945 debugf("Attempted to insert node in the wrong family.\n");
949 for(i
= 0; i
< sr
->numnodes
; i
++) {
950 if(id_cmp(id
, sr
->nodes
[i
].id
) == 0) {
954 if(xorcmp(id
, sr
->nodes
[i
].id
, sr
->id
) < 0)
958 if(i
== SEARCH_NODES
)
961 if(sr
->numnodes
< SEARCH_NODES
)
964 for(j
= sr
->numnodes
- 1; j
> i
; j
--) {
965 sr
->nodes
[j
] = sr
->nodes
[j
- 1];
970 memset(n
, 0, sizeof(struct search_node
));
971 memcpy(n
->id
, id
, 20);
974 memcpy(&n
->ss
, sa
, salen
);
979 n
->reply_time
= now
.tv_sec
;
984 if(token_len
>= 40) {
985 debugf("Eek! Overlong token.\n");
987 memcpy(n
->token
, token
, token_len
);
988 n
->token_len
= token_len
;
996 flush_search_node(struct search_node
*n
, struct search
*sr
)
998 int i
= n
- sr
->nodes
, j
;
999 for(j
= i
; j
< sr
->numnodes
- 1; j
++)
1000 sr
->nodes
[j
] = sr
->nodes
[j
+ 1];
1005 expire_searches(void)
1007 struct search
*sr
= searches
, *previous
= NULL
;
1010 struct search
*next
= sr
->next
;
1011 if(sr
->step_time
< now
.tv_sec
- DHT_SEARCH_EXPIRE_TIME
) {
1013 previous
->next
= next
;
1025 /* This must always return 0 or 1, never -1, not even on failure (see below). */
1027 search_send_get_peers(struct search
*sr
, struct search_node
*n
)
1030 unsigned char tid
[4];
1034 for(i
= 0; i
< sr
->numnodes
; i
++) {
1035 if(sr
->nodes
[i
].pinged
< 3 && !sr
->nodes
[i
].replied
&&
1036 sr
->nodes
[i
].request_time
< now
.tv_sec
- 15)
1041 if(!n
|| n
->pinged
>= 3 || n
->replied
||
1042 n
->request_time
>= now
.tv_sec
- 15)
1045 debugf("Sending get_peers.\n");
1046 make_tid(tid
, "gp", sr
->tid
);
1047 send_get_peers((struct sockaddr
*)&n
->ss
, n
->sslen
, tid
, 4, sr
->id
, -1,
1048 n
->reply_time
>= now
.tv_sec
- 15);
1050 n
->request_time
= now
.tv_sec
;
1051 /* If the node happens to be in our main routing table, mark it
1053 node
= find_node(n
->id
, n
->ss
.ss_family
);
1054 if(node
) pinged(node
, NULL
);
1058 /* When a search is in progress, we periodically call search_step to send
1059 further requests. */
1061 search_step(struct search
*sr
, dht_callback
*callback
, void *closure
)
1066 /* Check if the first 8 live nodes have replied. */
1068 for(i
= 0; i
< sr
->numnodes
&& j
< 8; i
++) {
1069 struct search_node
*n
= &sr
->nodes
[i
];
1085 for(i
= 0; i
< sr
->numnodes
&& j
< 8; i
++) {
1086 struct search_node
*n
= &sr
->nodes
[i
];
1088 unsigned char tid
[4];
1091 /* A proposed extension to the protocol consists in
1092 omitting the token when storage tables are full. While
1093 I don't think this makes a lot of sense -- just sending
1094 a positive reply is just as good --, let's deal with it. */
1095 if(n
->token_len
== 0)
1099 debugf("Sending announce_peer.\n");
1100 make_tid(tid
, "ap", sr
->tid
);
1101 send_announce_peer((struct sockaddr
*)&n
->ss
,
1102 sizeof(struct sockaddr_storage
),
1103 tid
, 4, sr
->id
, sr
->port
,
1104 n
->token
, n
->token_len
,
1105 n
->reply_time
>= now
.tv_sec
- 15);
1107 n
->request_time
= now
.tv_sec
;
1108 node
= find_node(n
->id
, n
->ss
.ss_family
);
1109 if(node
) pinged(node
, NULL
);
1116 sr
->step_time
= now
.tv_sec
;
1120 if(sr
->step_time
+ 15 >= now
.tv_sec
)
1124 for(i
= 0; i
< sr
->numnodes
; i
++) {
1125 j
+= search_send_get_peers(sr
, &sr
->nodes
[i
]);
1129 sr
->step_time
= now
.tv_sec
;
1135 (*callback
)(closure
,
1137 DHT_EVENT_SEARCH_DONE
: DHT_EVENT_SEARCH_DONE6
,
1139 sr
->step_time
= now
.tv_sec
;
1142 static struct search
*
1145 struct search
*sr
, *oldest
= NULL
;
1147 /* Find the oldest done search */
1151 (oldest
== NULL
|| oldest
->step_time
> sr
->step_time
))
1156 /* The oldest slot is expired. */
1157 if(oldest
&& oldest
->step_time
< now
.tv_sec
- DHT_SEARCH_EXPIRE_TIME
)
1160 /* Allocate a new slot. */
1161 if(numsearches
< DHT_MAX_SEARCHES
) {
1162 sr
= calloc(1, sizeof(struct search
));
1164 sr
->next
= searches
;
1171 /* Oh, well, never mind. Reuse the oldest slot. */
1175 /* Insert the contents of a bucket into a search structure. */
1177 insert_search_bucket(struct bucket
*b
, struct search
*sr
)
1182 insert_search_node(n
->id
, (struct sockaddr
*)&n
->ss
, n
->sslen
,
1188 /* Start a search. If port is non-zero, perform an announce when the
1189 search is complete. */
1191 dht_search(const unsigned char *id
, int port
, int af
,
1192 dht_callback
*callback
, void *closure
)
1195 struct bucket
*b
= find_bucket(id
, af
);
1198 errno
= EAFNOSUPPORT
;
1204 if(sr
->af
== af
&& id_cmp(sr
->id
, id
) == 0)
1210 /* We're reusing data from an old search. Reusing the same tid
1211 means that we can merge replies for both searches. */
1215 for(i
= 0; i
< sr
->numnodes
; i
++) {
1216 struct search_node
*n
;
1218 /* Discard any doubtful nodes. */
1219 if(n
->pinged
>= 3 || n
->reply_time
< now
.tv_sec
- 7200) {
1220 flush_search_node(n
, sr
);
1235 sr
->tid
= search_id
++;
1237 memcpy(sr
->id
, id
, 20);
1244 insert_search_bucket(b
, sr
);
1246 if(sr
->numnodes
< SEARCH_NODES
) {
1247 struct bucket
*p
= previous_bucket(b
);
1249 insert_search_bucket(b
->next
, sr
);
1251 insert_search_bucket(p
, sr
);
1253 if(sr
->numnodes
< SEARCH_NODES
)
1254 insert_search_bucket(find_bucket(myid
, af
), sr
);
1256 search_step(sr
, callback
, closure
);
1257 search_time
= now
.tv_sec
;
1261 /* A struct storage stores all the stored peer addresses for a given info
1264 static struct storage
*
1265 find_storage(const unsigned char *id
)
1267 struct storage
*st
= storage
;
1270 if(id_cmp(id
, st
->id
) == 0)
1278 storage_store(const unsigned char *id
,
1279 const struct sockaddr
*sa
, unsigned short port
)
1285 if(sa
->sa_family
== AF_INET
) {
1286 struct sockaddr_in
*sin
= (struct sockaddr_in
*)sa
;
1287 ip
= (unsigned char*)&sin
->sin_addr
;
1289 } else if(sa
->sa_family
== AF_INET6
) {
1290 struct sockaddr_in6
*sin6
= (struct sockaddr_in6
*)sa
;
1291 ip
= (unsigned char*)&sin6
->sin6_addr
;
1297 st
= find_storage(id
);
1300 if(numstorage
>= DHT_MAX_HASHES
)
1302 st
= calloc(1, sizeof(struct storage
));
1303 if(st
== NULL
) return -1;
1304 memcpy(st
->id
, id
, 20);
1310 for(i
= 0; i
< st
->numpeers
; i
++) {
1311 if(st
->peers
[i
].port
== port
&& st
->peers
[i
].len
== len
&&
1312 memcmp(st
->peers
[i
].ip
, ip
, len
) == 0)
1316 if(i
< st
->numpeers
) {
1317 /* Already there, only need to refresh */
1318 st
->peers
[i
].time
= now
.tv_sec
;
1322 if(i
>= st
->maxpeers
) {
1323 /* Need to expand the array. */
1324 struct peer
*new_peers
;
1326 if(st
->maxpeers
>= DHT_MAX_PEERS
)
1328 n
= st
->maxpeers
== 0 ? 2 : 2 * st
->maxpeers
;
1329 n
= MIN(n
, DHT_MAX_PEERS
);
1330 new_peers
= realloc(st
->peers
, n
* sizeof(struct peer
));
1331 if(new_peers
== NULL
)
1333 st
->peers
= new_peers
;
1336 p
= &st
->peers
[st
->numpeers
++];
1337 p
->time
= now
.tv_sec
;
1339 memcpy(p
->ip
, ip
, len
);
1346 expire_storage(void)
1348 struct storage
*st
= storage
, *previous
= NULL
;
1351 while(i
< st
->numpeers
) {
1352 if(st
->peers
[i
].time
< now
.tv_sec
- 32 * 60) {
1353 if(i
!= st
->numpeers
- 1)
1354 st
->peers
[i
] = st
->peers
[st
->numpeers
- 1];
1361 if(st
->numpeers
== 0) {
1364 previous
->next
= st
->next
;
1369 st
= previous
->next
;
1373 if(numstorage
< 0) {
1374 debugf("Eek... numstorage became negative.\n");
1386 rotate_secrets(void)
1390 rotate_secrets_time
= now
.tv_sec
+ 900 + random() % 1800;
1392 memcpy(oldsecret
, secret
, sizeof(secret
));
1393 rc
= dht_random_bytes(secret
, sizeof(secret
));
1402 #define TOKEN_SIZE 8
1406 make_token(const struct sockaddr
*sa
, int old
, unsigned char *token_return
)
1410 unsigned short port
;
1412 if(sa
->sa_family
== AF_INET
) {
1413 struct sockaddr_in
*sin
= (struct sockaddr_in
*)sa
;
1414 ip
= &sin
->sin_addr
;
1416 port
= htons(sin
->sin_port
);
1417 } else if(sa
->sa_family
== AF_INET6
) {
1418 struct sockaddr_in6
*sin6
= (struct sockaddr_in6
*)sa
;
1419 ip
= &sin6
->sin6_addr
;
1421 port
= htons(sin6
->sin6_port
);
1426 dht_hash(token_return
, TOKEN_SIZE
,
1427 old
? oldsecret
: secret
, sizeof(secret
),
1428 ip
, iplen
, (unsigned char*)&port
, 2);
1431 token_match(const unsigned char *token
, int token_len
,
1432 const struct sockaddr
*sa
)
1434 unsigned char t
[TOKEN_SIZE
];
1435 if(token_len
!= TOKEN_SIZE
)
1437 make_token(sa
, 0, t
);
1438 if(memcmp(t
, token
, TOKEN_SIZE
) == 0)
1440 make_token(sa
, 1, t
);
1441 if(memcmp(t
, token
, TOKEN_SIZE
) == 0)
1447 dht_nodes(int af
, int *good_return
, int *dubious_return
, int *cached_return
,
1448 int *incoming_return
)
1450 int good
= 0, dubious
= 0, cached
= 0, incoming
= 0;
1451 struct bucket
*b
= af
== AF_INET
? buckets
: buckets6
;
1454 struct node
*n
= b
->nodes
;
1458 if(n
->time
> n
->reply_time
)
1465 if(b
->cached
.ss_family
> 0)
1470 *good_return
= good
;
1472 *dubious_return
= dubious
;
1474 *cached_return
= cached
;
1476 *incoming_return
= incoming
;
1477 return good
+ dubious
;
1481 dump_bucket(FILE *f
, struct bucket
*b
)
1483 struct node
*n
= b
->nodes
;
1484 fprintf(f
, "Bucket ");
1485 print_hex(f
, b
->first
, 20);
1486 fprintf(f
, " count %d age %d%s%s:\n",
1487 b
->count
, (int)(now
.tv_sec
- b
->time
),
1488 in_bucket(myid
, b
) ? " (mine)" : "",
1489 b
->cached
.ss_family
? " (cached)" : "");
1492 unsigned short port
;
1493 fprintf(f
, " Node ");
1494 print_hex(f
, n
->id
, 20);
1495 if(n
->ss
.ss_family
== AF_INET
) {
1496 struct sockaddr_in
*sin
= (struct sockaddr_in
*)&n
->ss
;
1497 inet_ntop(AF_INET
, &sin
->sin_addr
, buf
, 512);
1498 port
= ntohs(sin
->sin_port
);
1499 } else if(n
->ss
.ss_family
== AF_INET6
) {
1500 struct sockaddr_in6
*sin6
= (struct sockaddr_in6
*)&n
->ss
;
1501 inet_ntop(AF_INET6
, &sin6
->sin6_addr
, buf
, 512);
1502 port
= ntohs(sin6
->sin6_port
);
1504 snprintf(buf
, 512, "unknown(%d)", n
->ss
.ss_family
);
1508 if(n
->ss
.ss_family
== AF_INET6
)
1509 fprintf(f
, " [%s]:%d ", buf
, port
);
1511 fprintf(f
, " %s:%d ", buf
, port
);
1512 if(n
->time
!= n
->reply_time
)
1513 fprintf(f
, "age %ld, %ld",
1514 (long)(now
.tv_sec
- n
->time
),
1515 (long)(now
.tv_sec
- n
->reply_time
));
1517 fprintf(f
, "age %ld", (long)(now
.tv_sec
- n
->time
));
1519 fprintf(f
, " (%d)", n
->pinged
);
1521 fprintf(f
, " (good)");
1529 dht_dump_tables(FILE *f
)
1533 struct storage
*st
= storage
;
1534 struct search
*sr
= searches
;
1536 fprintf(f
, "My id ");
1537 print_hex(f
, myid
, 20);
1555 fprintf(f
, "\nSearch%s id ", sr
->af
== AF_INET6
? " (IPv6)" : "");
1556 print_hex(f
, sr
->id
, 20);
1557 fprintf(f
, " age %d%s\n", (int)(now
.tv_sec
- sr
->step_time
),
1558 sr
->done
? " (done)" : "");
1559 for(i
= 0; i
< sr
->numnodes
; i
++) {
1560 struct search_node
*n
= &sr
->nodes
[i
];
1561 fprintf(f
, "Node %d id ", i
);
1562 print_hex(f
, n
->id
, 20);
1563 fprintf(f
, " bits %d age ", common_bits(sr
->id
, n
->id
));
1565 fprintf(f
, "%d, ", (int)(now
.tv_sec
- n
->request_time
));
1566 fprintf(f
, "%d", (int)(now
.tv_sec
- n
->reply_time
));
1568 fprintf(f
, " (%d)", n
->pinged
);
1569 fprintf(f
, "%s%s.\n",
1570 find_node(n
->id
, AF_INET
) ? " (known)" : "",
1571 n
->replied
? " (replied)" : "");
1577 fprintf(f
, "\nStorage ");
1578 print_hex(f
, st
->id
, 20);
1579 fprintf(f
, " %d/%d nodes:", st
->numpeers
, st
->maxpeers
);
1580 for(i
= 0; i
< st
->numpeers
; i
++) {
1582 if(st
->peers
[i
].len
== 4) {
1583 inet_ntop(AF_INET
, st
->peers
[i
].ip
, buf
, 100);
1584 } else if(st
->peers
[i
].len
== 16) {
1586 inet_ntop(AF_INET6
, st
->peers
[i
].ip
, buf
+ 1, 98);
1591 fprintf(f
, " %s:%u (%ld)",
1592 buf
, st
->peers
[i
].port
,
1593 (long)(now
.tv_sec
- st
->peers
[i
].time
));
1603 dht_init(int s
, int s6
, const unsigned char *id
, const unsigned char *v
)
1607 if(dht_socket
>= 0 || dht_socket6
>= 0 || buckets
|| buckets6
) {
1619 buckets
= calloc(sizeof(struct bucket
), 1);
1622 buckets
->af
= AF_INET
;
1624 rc
= set_nonblocking(s
, 1);
1630 buckets6
= calloc(sizeof(struct bucket
), 1);
1631 if(buckets6
== NULL
)
1633 buckets6
->af
= AF_INET6
;
1635 rc
= set_nonblocking(s6
, 1);
1640 memcpy(myid
, id
, 20);
1642 memcpy(my_v
, "1:v4:", 5);
1643 memcpy(my_v
+ 5, v
, 4);
1649 gettimeofday(&now
, NULL
);
1651 mybucket_grow_time
= now
.tv_sec
;
1652 mybucket6_grow_time
= now
.tv_sec
;
1653 confirm_nodes_time
= now
.tv_sec
+ random() % 3;
1655 search_id
= random() & 0xFFFF;
1658 next_blacklisted
= 0;
1660 token_bucket_time
= now
.tv_sec
;
1661 token_bucket_tokens
= MAX_TOKEN_BUCKET_TOKENS
;
1663 memset(secret
, 0, sizeof(secret
));
1664 rc
= rotate_secrets();
1671 expire_buckets(buckets
);
1672 expire_buckets(buckets6
);
1685 if(dht_socket
< 0 && dht_socket6
< 0) {
1694 struct bucket
*b
= buckets
;
1697 struct node
*n
= b
->nodes
;
1705 struct bucket
*b
= buckets6
;
1708 struct node
*n
= b
->nodes
;
1716 struct storage
*st
= storage
;
1717 storage
= storage
->next
;
1723 struct search
*sr
= searches
;
1724 searches
= searches
->next
;
1731 /* Rate control for requests we receive. */
1736 if(token_bucket_tokens
== 0) {
1737 token_bucket_tokens
= MIN(MAX_TOKEN_BUCKET_TOKENS
,
1738 100 * (now
.tv_sec
- token_bucket_time
));
1739 token_bucket_time
= now
.tv_sec
;
1742 if(token_bucket_tokens
== 0)
1745 token_bucket_tokens
--;
1750 neighbourhood_maintenance(int af
)
1752 unsigned char id
[20];
1753 struct bucket
*b
= find_bucket(myid
, af
);
1760 memcpy(id
, myid
, 20);
1761 id
[19] = random() & 0xFF;
1763 if(q
->next
&& (q
->count
== 0 || (random() & 7) == 0))
1765 if(q
->count
== 0 || (random() & 7) == 0) {
1767 r
= previous_bucket(b
);
1768 if(r
&& r
->count
> 0)
1773 /* Since our node-id is the same in both DHTs, it's probably
1774 profitable to query both families. */
1775 int want
= dht_socket
>= 0 && dht_socket6
>= 0 ? (WANT4
| WANT6
) : -1;
1778 unsigned char tid
[4];
1779 debugf("Sending find_node for%s neighborhood maintenance.\n",
1780 af
== AF_INET6
? " IPv6" : "");
1781 make_tid(tid
, "fn", 0);
1782 send_find_node((struct sockaddr
*)&n
->ss
, n
->sslen
,
1784 n
->reply_time
>= now
.tv_sec
- 15);
1793 bucket_maintenance(int af
)
1797 b
= af
== AF_INET
? buckets
: buckets6
;
1801 if(b
->time
< now
.tv_sec
- 600) {
1802 /* This bucket hasn't seen any positive confirmation for a long
1803 time. Pick a random id in this bucket's range, and send
1804 a request to a random node. */
1805 unsigned char id
[20];
1809 rc
= bucket_random(b
, id
);
1811 memcpy(id
, b
->first
, 20);
1814 /* If the bucket is empty, we try to fill it from a neighbour.
1815 We also sometimes do it gratuitiously to recover from
1816 buckets full of broken nodes. */
1817 if(q
->next
&& (q
->count
== 0 || (random() & 7) == 0))
1819 if(q
->count
== 0 || (random() & 7) == 0) {
1821 r
= previous_bucket(b
);
1822 if(r
&& r
->count
> 0)
1829 unsigned char tid
[4];
1832 if(dht_socket
>= 0 && dht_socket6
>= 0) {
1833 struct bucket
*otherbucket
;
1835 find_bucket(id
, af
== AF_INET
? AF_INET6
: AF_INET
);
1836 if(otherbucket
&& otherbucket
->count
< 8)
1837 /* The corresponding bucket in the other family
1838 is emptyish -- querying both is useful. */
1839 want
= WANT4
| WANT6
;
1840 else if(random() % 37 == 0)
1841 /* Most of the time, this just adds overhead.
1842 However, it might help stitch back one of
1843 the DHTs after a network collapse, so query
1844 both, but only very occasionally. */
1845 want
= WANT4
| WANT6
;
1848 debugf("Sending find_node for%s bucket maintenance.\n",
1849 af
== AF_INET6
? " IPv6" : "");
1850 make_tid(tid
, "fn", 0);
1851 send_find_node((struct sockaddr
*)&n
->ss
, n
->sslen
,
1853 n
->reply_time
>= now
.tv_sec
- 15);
1855 /* In order to avoid sending queries back-to-back,
1856 give up for now and reschedule us soon. */
1867 dht_periodic(const void *buf
, size_t buflen
,
1868 const struct sockaddr
*from
, int fromlen
,
1870 dht_callback
*callback
, void *closure
)
1872 gettimeofday(&now
, NULL
);
1876 unsigned char tid
[16], id
[20], info_hash
[20], target
[20];
1877 unsigned char nodes
[256], nodes6
[1024], token
[128];
1878 int tid_len
= 16, token_len
= 128;
1879 int nodes_len
= 256, nodes6_len
= 1024;
1880 unsigned short port
;
1881 unsigned char values
[2048], values6
[2048];
1882 int values_len
= 2048, values6_len
= 2048;
1884 unsigned short ttid
;
1886 if(is_martian(from
))
1889 if(node_blacklisted(from
, fromlen
)) {
1890 debugf("Received packet from blacklisted node.\n");
1894 if(((char*)buf
)[buflen
] != '\0') {
1895 debugf("Unterminated message.\n");
1900 message
= parse_message(buf
, buflen
, tid
, &tid_len
, id
, info_hash
,
1901 target
, &port
, token
, &token_len
,
1902 nodes
, &nodes_len
, nodes6
, &nodes6_len
,
1903 values
, &values_len
, values6
, &values6_len
,
1906 if(message
< 0 || message
== ERROR
|| id_cmp(id
, zeroes
) == 0) {
1907 debugf("Unparseable message: ");
1908 debug_printable(buf
, buflen
);
1913 if(id_cmp(id
, myid
) == 0) {
1914 debugf("Received message from self.\n");
1918 if(message
> REPLY
) {
1919 /* Rate limit requests. */
1920 if(!token_bucket()) {
1921 debugf("Dropping request due to rate limiting.\n");
1929 debugf("Broken node truncates transaction ids: ");
1930 debug_printable(buf
, buflen
);
1932 /* This is really annoying, as it means that we will
1933 time-out all our searches that go through this node.
1935 blacklist_node(id
, from
, fromlen
);
1938 if(tid_match(tid
, "pn", NULL
)) {
1940 new_node(id
, from
, fromlen
, 2);
1941 } else if(tid_match(tid
, "fn", NULL
) ||
1942 tid_match(tid
, "gp", NULL
)) {
1944 struct search
*sr
= NULL
;
1945 if(tid_match(tid
, "gp", &ttid
)) {
1947 sr
= find_search(ttid
, from
->sa_family
);
1949 debugf("Nodes found (%d+%d)%s!\n", nodes_len
/26, nodes6_len
/38,
1950 gp
? " for get_peers" : "");
1951 if(nodes_len
% 26 != 0 || nodes6_len
% 38 != 0) {
1952 debugf("Unexpected length for node info!\n");
1953 blacklist_node(id
, from
, fromlen
);
1954 } else if(gp
&& sr
== NULL
) {
1955 debugf("Unknown search!\n");
1956 new_node(id
, from
, fromlen
, 1);
1959 new_node(id
, from
, fromlen
, 2);
1960 for(i
= 0; i
< nodes_len
/ 26; i
++) {
1961 unsigned char *ni
= nodes
+ i
* 26;
1962 struct sockaddr_in sin
;
1963 if(id_cmp(ni
, myid
) == 0)
1965 memset(&sin
, 0, sizeof(sin
));
1966 sin
.sin_family
= AF_INET
;
1967 memcpy(&sin
.sin_addr
, ni
+ 20, 4);
1968 memcpy(&sin
.sin_port
, ni
+ 24, 2);
1969 new_node(ni
, (struct sockaddr
*)&sin
, sizeof(sin
), 0);
1970 if(sr
&& sr
->af
== AF_INET
) {
1971 insert_search_node(ni
,
1972 (struct sockaddr
*)&sin
,
1977 for(i
= 0; i
< nodes6_len
/ 38; i
++) {
1978 unsigned char *ni
= nodes6
+ i
* 38;
1979 struct sockaddr_in6 sin6
;
1980 if(id_cmp(ni
, myid
) == 0)
1982 memset(&sin6
, 0, sizeof(sin6
));
1983 sin6
.sin6_family
= AF_INET6
;
1984 memcpy(&sin6
.sin6_addr
, ni
+ 20, 16);
1985 memcpy(&sin6
.sin6_port
, ni
+ 36, 2);
1986 new_node(ni
, (struct sockaddr
*)&sin6
, sizeof(sin6
), 0);
1987 if(sr
&& sr
->af
== AF_INET6
) {
1988 insert_search_node(ni
,
1989 (struct sockaddr
*)&sin6
,
1995 /* Since we received a reply, the number of
1996 requests in flight has decreased. Let's push
1998 search_send_get_peers(sr
, NULL
);
2001 insert_search_node(id
, from
, fromlen
, sr
,
2002 1, token
, token_len
);
2003 if(values_len
> 0 || values6_len
> 0) {
2004 debugf("Got values (%d+%d)!\n",
2005 values_len
/ 6, values6_len
/ 18);
2008 (*callback
)(closure
, DHT_EVENT_VALUES
, sr
->id
,
2009 (void*)values
, values_len
);
2012 (*callback
)(closure
, DHT_EVENT_VALUES6
, sr
->id
,
2013 (void*)values6
, values6_len
);
2017 } else if(tid_match(tid
, "ap", &ttid
)) {
2019 debugf("Got reply to announce_peer.\n");
2020 sr
= find_search(ttid
, from
->sa_family
);
2022 debugf("Unknown search!\n");
2023 new_node(id
, from
, fromlen
, 1);
2026 new_node(id
, from
, fromlen
, 2);
2027 for(i
= 0; i
< sr
->numnodes
; i
++)
2028 if(id_cmp(sr
->nodes
[i
].id
, id
) == 0) {
2029 sr
->nodes
[i
].request_time
= 0;
2030 sr
->nodes
[i
].reply_time
= now
.tv_sec
;
2031 sr
->nodes
[i
].acked
= 1;
2032 sr
->nodes
[i
].pinged
= 0;
2035 /* See comment for gp above. */
2036 search_send_get_peers(sr
, NULL
);
2039 debugf("Unexpected reply: ");
2040 debug_printable(buf
, buflen
);
2045 debugf("Ping (%d)!\n", tid_len
);
2046 new_node(id
, from
, fromlen
, 1);
2047 debugf("Sending pong.\n");
2048 send_pong(from
, fromlen
, tid
, tid_len
);
2051 debugf("Find node!\n");
2052 new_node(id
, from
, fromlen
, 1);
2053 debugf("Sending closest nodes (%d).\n", want
);
2054 send_closest_nodes(from
, fromlen
,
2055 tid
, tid_len
, target
, want
,
2059 debugf("Get_peers!\n");
2060 new_node(id
, from
, fromlen
, 1);
2061 if(id_cmp(info_hash
, zeroes
) == 0) {
2062 debugf("Eek! Got get_peers with no info_hash.\n");
2063 send_error(from
, fromlen
, tid
, tid_len
,
2064 203, "Get_peers with no info_hash");
2067 struct storage
*st
= find_storage(info_hash
);
2068 unsigned char token
[TOKEN_SIZE
];
2069 make_token(from
, 0, token
);
2070 if(st
&& st
->numpeers
> 0) {
2071 debugf("Sending found%s peers.\n",
2072 from
->sa_family
== AF_INET6
? " IPv6" : "");
2073 send_closest_nodes(from
, fromlen
,
2076 from
->sa_family
, st
,
2079 debugf("Sending nodes for get_peers.\n");
2080 send_closest_nodes(from
, fromlen
,
2081 tid
, tid_len
, info_hash
, want
,
2082 0, NULL
, token
, TOKEN_SIZE
);
2087 debugf("Announce peer!\n");
2088 new_node(id
, from
, fromlen
, 1);
2089 if(id_cmp(info_hash
, zeroes
) == 0) {
2090 debugf("Announce_peer with no info_hash.\n");
2091 send_error(from
, fromlen
, tid
, tid_len
,
2092 203, "Announce_peer with no info_hash");
2095 if(!token_match(token
, token_len
, from
)) {
2096 debugf("Incorrect token for announce_peer.\n");
2097 send_error(from
, fromlen
, tid
, tid_len
,
2098 203, "Announce_peer with wrong token");
2102 debugf("Announce_peer with forbidden port %d.\n", port
);
2103 send_error(from
, fromlen
, tid
, tid_len
,
2104 203, "Announce_peer with forbidden port number");
2107 storage_store(info_hash
, from
, port
);
2108 /* Note that if storage_store failed, we lie to the requestor.
2109 This is to prevent them from backtracking, and hence
2110 polluting the DHT. */
2111 debugf("Sending peer announced.\n");
2112 send_peer_announced(from
, fromlen
, tid
, tid_len
);
2117 if(now
.tv_sec
>= rotate_secrets_time
)
2120 if(now
.tv_sec
>= expire_stuff_time
) {
2121 expire_buckets(buckets
);
2122 expire_buckets(buckets6
);
2127 if(search_time
> 0 && now
.tv_sec
>= search_time
) {
2131 if(!sr
->done
&& sr
->step_time
+ 5 <= now
.tv_sec
) {
2132 search_step(sr
, callback
, closure
);
2142 time_t tm
= sr
->step_time
+ 15 + random() % 10;
2143 if(search_time
== 0 || search_time
> tm
)
2150 if(now
.tv_sec
>= confirm_nodes_time
) {
2153 soon
|= bucket_maintenance(AF_INET
);
2154 soon
|= bucket_maintenance(AF_INET6
);
2157 if(mybucket_grow_time
>= now
.tv_sec
- 150)
2158 soon
|= neighbourhood_maintenance(AF_INET
);
2159 if(mybucket6_grow_time
>= now
.tv_sec
- 150)
2160 soon
|= neighbourhood_maintenance(AF_INET6
);
2163 /* In order to maintain all buckets' age within 600 seconds, worst
2164 case is roughly 27 seconds, assuming the table is 22 bits deep.
2165 We want to keep a margin for neighborhood maintenance, so keep
2166 this within 25 seconds. */
2168 confirm_nodes_time
= now
.tv_sec
+ 5 + random() % 20;
2170 confirm_nodes_time
= now
.tv_sec
+ 60 + random() % 120;
2173 if(confirm_nodes_time
> now
.tv_sec
)
2174 *tosleep
= confirm_nodes_time
- now
.tv_sec
;
2178 if(search_time
> 0) {
2179 if(search_time
<= now
.tv_sec
)
2181 else if(*tosleep
> search_time
- now
.tv_sec
)
2182 *tosleep
= search_time
- now
.tv_sec
;
2189 dht_get_nodes(struct sockaddr_in
*sin
, int *num
,
2190 struct sockaddr_in6
*sin6
, int *num6
)
2198 /* For restoring to work without discarding too many nodes, the list
2199 must start with the contents of our bucket. */
2200 b
= find_bucket(myid
, AF_INET
);
2205 while(n
&& i
< *num
) {
2207 sin
[i
] = *(struct sockaddr_in
*)&n
->ss
;
2214 while(b
&& i
< *num
) {
2215 if(!in_bucket(myid
, b
)) {
2217 while(n
&& i
< *num
) {
2219 sin
[i
] = *(struct sockaddr_in
*)&n
->ss
;
2232 b
= find_bucket(myid
, AF_INET6
);
2237 while(n
&& j
< *num6
) {
2239 sin6
[j
] = *(struct sockaddr_in6
*)&n
->ss
;
2246 while(b
&& j
< *num6
) {
2247 if(!in_bucket(myid
, b
)) {
2249 while(n
&& j
< *num6
) {
2251 sin6
[j
] = *(struct sockaddr_in6
*)&n
->ss
;
2268 dht_insert_node(const unsigned char *id
, struct sockaddr
*sa
, int salen
)
2272 if(sa
->sa_family
!= AF_INET
) {
2273 errno
= EAFNOSUPPORT
;
2277 n
= new_node(id
, (struct sockaddr
*)sa
, salen
, 0);
2282 dht_ping_node(struct sockaddr
*sa
, int salen
)
2284 unsigned char tid
[4];
2286 debugf("Sending ping.\n");
2287 make_tid(tid
, "pn", 0);
2288 return send_ping(sa
, salen
, tid
, 4);
2291 /* We could use a proper bencoding printer and parser, but the format of
2292 DHT messages is fairly stylised, so this seemed simpler. */
2294 #define CHECK(offset, delta, size) \
2295 if(delta < 0 || offset + delta > size) goto fail
2297 #define INC(offset, delta, size) \
2298 CHECK(offset, delta, size); \
2301 #define COPY(buf, offset, src, delta, size) \
2302 CHECK(offset, delta, size); \
2303 memcpy(buf + offset, src, delta); \
2306 #define ADD_V(buf, offset, size) \
2308 COPY(buf, offset, my_v, sizeof(my_v), size); \
2312 dht_send(const void *buf
, size_t len
, int flags
,
2313 const struct sockaddr
*sa
, int salen
)
2320 if(node_blacklisted(sa
, salen
)) {
2321 debugf("Attempting to send to blacklisted node.\n");
2326 if(sa
->sa_family
== AF_INET
)
2328 else if(sa
->sa_family
== AF_INET6
)
2334 errno
= EAFNOSUPPORT
;
2338 return sendto(s
, buf
, len
, flags
, sa
, salen
);
2342 send_ping(const struct sockaddr
*sa
, int salen
,
2343 const unsigned char *tid
, int tid_len
)
2347 rc
= snprintf(buf
+ i
, 512 - i
, "d1:ad2:id20:"); INC(i
, rc
, 512);
2348 COPY(buf
, i
, myid
, 20, 512);
2349 rc
= snprintf(buf
+ i
, 512 - i
, "e1:q4:ping1:t%d:", tid_len
);
2351 COPY(buf
, i
, tid
, tid_len
, 512);
2353 rc
= snprintf(buf
+ i
, 512 - i
, "1:y1:qe"); INC(i
, rc
, 512);
2354 return dht_send(buf
, i
, 0, sa
, salen
);
2362 send_pong(const struct sockaddr
*sa
, int salen
,
2363 const unsigned char *tid
, int tid_len
)
2367 rc
= snprintf(buf
+ i
, 512 - i
, "d1:rd2:id20:"); INC(i
, rc
, 512);
2368 COPY(buf
, i
, myid
, 20, 512);
2369 rc
= snprintf(buf
+ i
, 512 - i
, "e1:t%d:", tid_len
); INC(i
, rc
, 512);
2370 COPY(buf
, i
, tid
, tid_len
, 512);
2372 rc
= snprintf(buf
+ i
, 512 - i
, "1:y1:re"); INC(i
, rc
, 512);
2373 return dht_send(buf
, i
, 0, sa
, salen
);
2381 send_find_node(const struct sockaddr
*sa
, int salen
,
2382 const unsigned char *tid
, int tid_len
,
2383 const unsigned char *target
, int want
, int confirm
)
2387 rc
= snprintf(buf
+ i
, 512 - i
, "d1:ad2:id20:"); INC(i
, rc
, 512);
2388 COPY(buf
, i
, myid
, 20, 512);
2389 rc
= snprintf(buf
+ i
, 512 - i
, "6:target20:"); INC(i
, rc
, 512);
2390 COPY(buf
, i
, target
, 20, 512);
2392 rc
= snprintf(buf
+ i
, 512 - i
, "4:wantl%s%se",
2393 (want
& WANT4
) ? "2:n4" : "",
2394 (want
& WANT6
) ? "2:n6" : "");
2397 rc
= snprintf(buf
+ i
, 512 - i
, "e1:q9:find_node1:t%d:", tid_len
);
2399 COPY(buf
, i
, tid
, tid_len
, 512);
2401 rc
= snprintf(buf
+ i
, 512 - i
, "1:y1:qe"); INC(i
, rc
, 512);
2402 return dht_send(buf
, i
, confirm
? MSG_CONFIRM
: 0, sa
, salen
);
2410 send_nodes_peers(const struct sockaddr
*sa
, int salen
,
2411 const unsigned char *tid
, int tid_len
,
2412 const unsigned char *nodes
, int nodes_len
,
2413 const unsigned char *nodes6
, int nodes6_len
,
2414 int af
, struct storage
*st
,
2415 const unsigned char *token
, int token_len
)
2418 int i
= 0, rc
, j0
, j
, k
, len
;
2420 rc
= snprintf(buf
+ i
, 2048 - i
, "d1:rd2:id20:"); INC(i
, rc
, 2048);
2421 COPY(buf
, i
, myid
, 20, 2048);
2423 rc
= snprintf(buf
+ i
, 2048 - i
, "5:nodes%d:", nodes_len
);
2425 COPY(buf
, i
, nodes
, nodes_len
, 2048);
2427 if(nodes6_len
> 0) {
2428 rc
= snprintf(buf
+ i
, 2048 - i
, "6:nodes6%d:", nodes6_len
);
2430 COPY(buf
, i
, nodes6
, nodes6_len
, 2048);
2433 rc
= snprintf(buf
+ i
, 2048 - i
, "5:token%d:", token_len
);
2435 COPY(buf
, i
, token
, token_len
, 2048);
2438 if(st
&& st
->numpeers
> 0) {
2439 /* We treat the storage as a circular list, and serve a randomly
2440 chosen slice. In order to make sure we fit within 1024 octets,
2441 we limit ourselves to 50 peers. */
2443 len
= af
== AF_INET
? 4 : 16;
2444 j0
= random() % st
->numpeers
;
2448 rc
= snprintf(buf
+ i
, 2048 - i
, "6:valuesl"); INC(i
, rc
, 2048);
2450 if(st
->peers
[j
].len
== len
) {
2451 unsigned short swapped
;
2452 swapped
= htons(st
->peers
[j
].port
);
2453 rc
= snprintf(buf
+ i
, 2048 - i
, "%d:", len
+ 2);
2455 COPY(buf
, i
, st
->peers
[j
].ip
, len
, 2048);
2456 COPY(buf
, i
, &swapped
, 2, 2048);
2459 j
= (j
+ 1) % st
->numpeers
;
2460 } while(j
!= j0
&& k
< 50);
2461 rc
= snprintf(buf
+ i
, 2048 - i
, "e"); INC(i
, rc
, 2048);
2464 rc
= snprintf(buf
+ i
, 2048 - i
, "e1:t%d:", tid_len
); INC(i
, rc
, 2048);
2465 COPY(buf
, i
, tid
, tid_len
, 2048);
2466 ADD_V(buf
, i
, 2048);
2467 rc
= snprintf(buf
+ i
, 2048 - i
, "1:y1:re"); INC(i
, rc
, 2048);
2469 return dht_send(buf
, i
, 0, sa
, salen
);
2477 insert_closest_node(unsigned char *nodes
, int numnodes
,
2478 const unsigned char *id
, struct node
*n
)
2482 if(n
->ss
.ss_family
== AF_INET
)
2484 else if(n
->ss
.ss_family
== AF_INET6
)
2489 for(i
= 0; i
< numnodes
; i
++) {
2490 if(id_cmp(n
->id
, nodes
+ size
* i
) == 0)
2492 if(xorcmp(n
->id
, nodes
+ size
* i
, id
) < 0)
2502 if(i
< numnodes
- 1)
2503 memmove(nodes
+ size
* (i
+ 1), nodes
+ size
* i
,
2504 size
* (numnodes
- i
- 1));
2506 if(n
->ss
.ss_family
== AF_INET
) {
2507 struct sockaddr_in
*sin
= (struct sockaddr_in
*)&n
->ss
;
2508 memcpy(nodes
+ size
* i
, n
->id
, 20);
2509 memcpy(nodes
+ size
* i
+ 20, &sin
->sin_addr
, 4);
2510 memcpy(nodes
+ size
* i
+ 24, &sin
->sin_port
, 2);
2511 } else if(n
->ss
.ss_family
== AF_INET6
) {
2512 struct sockaddr_in6
*sin6
= (struct sockaddr_in6
*)&n
->ss
;
2513 memcpy(nodes
+ size
* i
, n
->id
, 20);
2514 memcpy(nodes
+ size
* i
+ 20, &sin6
->sin6_addr
, 16);
2515 memcpy(nodes
+ size
* i
+ 36, &sin6
->sin6_port
, 2);
2524 buffer_closest_nodes(unsigned char *nodes
, int numnodes
,
2525 const unsigned char *id
, struct bucket
*b
)
2527 struct node
*n
= b
->nodes
;
2530 numnodes
= insert_closest_node(nodes
, numnodes
, id
, n
);
2537 send_closest_nodes(const struct sockaddr
*sa
, int salen
,
2538 const unsigned char *tid
, int tid_len
,
2539 const unsigned char *id
, int want
,
2540 int af
, struct storage
*st
,
2541 const unsigned char *token
, int token_len
)
2543 unsigned char nodes
[8 * 26];
2544 unsigned char nodes6
[8 * 38];
2545 int numnodes
= 0, numnodes6
= 0;
2549 want
= sa
->sa_family
== AF_INET
? WANT4
: WANT6
;
2551 if((want
& WANT4
)) {
2552 b
= find_bucket(id
, AF_INET
);
2554 numnodes
= buffer_closest_nodes(nodes
, numnodes
, id
, b
);
2556 numnodes
= buffer_closest_nodes(nodes
, numnodes
, id
, b
->next
);
2557 b
= previous_bucket(b
);
2559 numnodes
= buffer_closest_nodes(nodes
, numnodes
, id
, b
);
2563 if((want
& WANT6
)) {
2564 b
= find_bucket(id
, AF_INET6
);
2566 numnodes6
= buffer_closest_nodes(nodes6
, numnodes6
, id
, b
);
2569 buffer_closest_nodes(nodes6
, numnodes6
, id
, b
->next
);
2570 b
= previous_bucket(b
);
2572 numnodes6
= buffer_closest_nodes(nodes6
, numnodes6
, id
, b
);
2575 debugf(" (%d+%d nodes.)\n", numnodes
, numnodes6
);
2577 return send_nodes_peers(sa
, salen
, tid
, tid_len
,
2578 nodes
, numnodes
* 26,
2579 nodes6
, numnodes6
* 38,
2580 af
, st
, token
, token_len
);
2584 send_get_peers(const struct sockaddr
*sa
, int salen
,
2585 unsigned char *tid
, int tid_len
, unsigned char *infohash
,
2586 int want
, int confirm
)
2591 rc
= snprintf(buf
+ i
, 512 - i
, "d1:ad2:id20:"); INC(i
, rc
, 512);
2592 COPY(buf
, i
, myid
, 20, 512);
2593 rc
= snprintf(buf
+ i
, 512 - i
, "9:info_hash20:"); INC(i
, rc
, 512);
2594 COPY(buf
, i
, infohash
, 20, 512);
2596 rc
= snprintf(buf
+ i
, 512 - i
, "4:wantl%s%se",
2597 (want
& WANT4
) ? "2:n4" : "",
2598 (want
& WANT6
) ? "2:n6" : "");
2601 rc
= snprintf(buf
+ i
, 512 - i
, "e1:q9:get_peers1:t%d:", tid_len
);
2603 COPY(buf
, i
, tid
, tid_len
, 512);
2605 rc
= snprintf(buf
+ i
, 512 - i
, "1:y1:qe"); INC(i
, rc
, 512);
2606 return dht_send(buf
, i
, confirm
? MSG_CONFIRM
: 0, sa
, salen
);
2614 send_announce_peer(const struct sockaddr
*sa
, int salen
,
2615 unsigned char *tid
, int tid_len
,
2616 unsigned char *infohash
, unsigned short port
,
2617 unsigned char *token
, int token_len
, int confirm
)
2622 rc
= snprintf(buf
+ i
, 512 - i
, "d1:ad2:id20:"); INC(i
, rc
, 512);
2623 COPY(buf
, i
, myid
, 20, 512);
2624 rc
= snprintf(buf
+ i
, 512 - i
, "9:info_hash20:"); INC(i
, rc
, 512);
2625 COPY(buf
, i
, infohash
, 20, 512);
2626 rc
= snprintf(buf
+ i
, 512 - i
, "4:porti%ue5:token%d:", (unsigned)port
,
2629 COPY(buf
, i
, token
, token_len
, 512);
2630 rc
= snprintf(buf
+ i
, 512 - i
, "e1:q13:announce_peer1:t%d:", tid_len
);
2632 COPY(buf
, i
, tid
, tid_len
, 512);
2634 rc
= snprintf(buf
+ i
, 512 - i
, "1:y1:qe"); INC(i
, rc
, 512);
2636 return dht_send(buf
, i
, confirm
? 0 : MSG_CONFIRM
, sa
, salen
);
2644 send_peer_announced(const struct sockaddr
*sa
, int salen
,
2645 unsigned char *tid
, int tid_len
)
2650 rc
= snprintf(buf
+ i
, 512 - i
, "d1:rd2:id20:"); INC(i
, rc
, 512);
2651 COPY(buf
, i
, myid
, 20, 512);
2652 rc
= snprintf(buf
+ i
, 512 - i
, "e1:t%d:", tid_len
);
2654 COPY(buf
, i
, tid
, tid_len
, 512);
2656 rc
= snprintf(buf
+ i
, 512 - i
, "1:y1:re"); INC(i
, rc
, 512);
2657 return dht_send(buf
, i
, 0, sa
, salen
);
2665 send_error(const struct sockaddr
*sa
, int salen
,
2666 unsigned char *tid
, int tid_len
,
2667 int code
, const char *message
)
2672 rc
= snprintf(buf
+ i
, 512 - i
, "d1:eli%de%d:",
2673 code
, (int)strlen(message
));
2675 COPY(buf
, i
, message
, (int)strlen(message
), 512);
2676 rc
= snprintf(buf
+ i
, 512 - i
, "e1:t%d:", tid_len
); INC(i
, rc
, 512);
2677 COPY(buf
, i
, tid
, tid_len
, 512);
2679 rc
= snprintf(buf
+ i
, 512 - i
, "1:y1:ee"); INC(i
, rc
, 512);
2680 return dht_send(buf
, i
, 0, sa
, salen
);
2695 dht_memmem(const void *haystack
, size_t haystacklen
,
2696 const void *needle
, size_t needlelen
)
2698 return memmem(haystack
, haystacklen
, needle
, needlelen
);
2704 dht_memmem(const void *haystack
, size_t haystacklen
,
2705 const void *needle
, size_t needlelen
)
2707 const char *h
= haystack
;
2708 const char *n
= needle
;
2711 /* size_t is unsigned */
2712 if(needlelen
> haystacklen
)
2715 for(i
= 0; i
<= haystacklen
- needlelen
; i
++) {
2716 if(memcmp(h
+ i
, n
, needlelen
) == 0)
2717 return (void*)(h
+ i
);
2725 parse_message(const unsigned char *buf
, int buflen
,
2726 unsigned char *tid_return
, int *tid_len
,
2727 unsigned char *id_return
, unsigned char *info_hash_return
,
2728 unsigned char *target_return
, unsigned short *port_return
,
2729 unsigned char *token_return
, int *token_len
,
2730 unsigned char *nodes_return
, int *nodes_len
,
2731 unsigned char *nodes6_return
, int *nodes6_len
,
2732 unsigned char *values_return
, int *values_len
,
2733 unsigned char *values6_return
, int *values6_len
,
2736 const unsigned char *p
;
2738 /* This code will happily crash if the buffer is not NUL-terminated. */
2739 if(buf
[buflen
] != '\0') {
2740 debugf("Eek! parse_message with unterminated buffer.\n");
2744 #define CHECK(ptr, len) \
2745 if(((unsigned char*)ptr) + (len) > (buf) + (buflen)) goto overflow;
2748 p
= dht_memmem(buf
, buflen
, "1:t", 3);
2752 l
= strtol((char*)p
+ 3, &q
, 10);
2753 if(q
&& *q
== ':' && l
> 0 && l
< *tid_len
) {
2755 memcpy(tid_return
, q
+ 1, l
);
2762 p
= dht_memmem(buf
, buflen
, "2:id20:", 7);
2765 memcpy(id_return
, p
+ 7, 20);
2767 memset(id_return
, 0, 20);
2770 if(info_hash_return
) {
2771 p
= dht_memmem(buf
, buflen
, "9:info_hash20:", 14);
2774 memcpy(info_hash_return
, p
+ 14, 20);
2776 memset(info_hash_return
, 0, 20);
2780 p
= dht_memmem(buf
, buflen
, "porti", 5);
2784 l
= strtol((char*)p
+ 5, &q
, 10);
2785 if(q
&& *q
== 'e' && l
> 0 && l
< 0x10000)
2793 p
= dht_memmem(buf
, buflen
, "6:target20:", 11);
2796 memcpy(target_return
, p
+ 11, 20);
2798 memset(target_return
, 0, 20);
2802 p
= dht_memmem(buf
, buflen
, "5:token", 7);
2806 l
= strtol((char*)p
+ 7, &q
, 10);
2807 if(q
&& *q
== ':' && l
> 0 && l
< *token_len
) {
2809 memcpy(token_return
, q
+ 1, l
);
2818 p
= dht_memmem(buf
, buflen
, "5:nodes", 7);
2822 l
= strtol((char*)p
+ 7, &q
, 10);
2823 if(q
&& *q
== ':' && l
> 0 && l
< *nodes_len
) {
2825 memcpy(nodes_return
, q
+ 1, l
);
2834 p
= dht_memmem(buf
, buflen
, "6:nodes6", 8);
2838 l
= strtol((char*)p
+ 8, &q
, 10);
2839 if(q
&& *q
== ':' && l
> 0 && l
< *nodes6_len
) {
2841 memcpy(nodes6_return
, q
+ 1, l
);
2849 if(values_len
|| values6_len
) {
2850 p
= dht_memmem(buf
, buflen
, "6:valuesl", 9);
2852 int i
= p
- buf
+ 9;
2857 l
= strtol((char*)buf
+ i
, &q
, 10);
2858 if(q
&& *q
== ':' && l
> 0) {
2860 i
= q
+ 1 + l
- (char*)buf
;
2862 if(j
+ l
> *values_len
)
2864 memcpy((char*)values_return
+ j
, q
+ 1, l
);
2866 } else if(l
== 18) {
2867 if(j6
+ l
> *values6_len
)
2869 memcpy((char*)values6_return
+ j6
, q
+ 1, l
);
2872 debugf("Received weird value -- %d bytes.\n", (int)l
);
2878 if(i
>= buflen
|| buf
[i
] != 'e')
2879 debugf("eek... unexpected end for values.\n");
2893 p
= dht_memmem(buf
, buflen
, "4:wantl", 7);
2895 int i
= p
- buf
+ 7;
2897 while(buf
[i
] > '0' && buf
[i
] <= '9' && buf
[i
+ 1] == ':' &&
2898 i
+ 2 + buf
[i
] - '0' < buflen
) {
2899 CHECK(buf
+ i
+ 2, buf
[i
] - '0');
2900 if(buf
[i
] == '2' && memcmp(buf
+ i
+ 2, "n4", 2) == 0)
2901 *want_return
|= WANT4
;
2902 else if(buf
[i
] == '2' && memcmp(buf
+ i
+ 2, "n6", 2) == 0)
2903 *want_return
|= WANT6
;
2905 debugf("eek... unexpected want flag (%c)\n", buf
[i
]);
2906 i
+= 2 + buf
[i
] - '0';
2908 if(i
>= buflen
|| buf
[i
] != 'e')
2909 debugf("eek... unexpected end for want.\n");
2917 if(dht_memmem(buf
, buflen
, "1:y1:r", 6))
2919 if(dht_memmem(buf
, buflen
, "1:y1:e", 6))
2921 if(!dht_memmem(buf
, buflen
, "1:y1:q", 6))
2923 if(dht_memmem(buf
, buflen
, "1:q4:ping", 9))
2925 if(dht_memmem(buf
, buflen
, "1:q9:find_node", 14))
2927 if(dht_memmem(buf
, buflen
, "1:q9:get_peers", 14))
2929 if(dht_memmem(buf
, buflen
, "1:q13:announce_peer", 19))
2930 return ANNOUNCE_PEER
;
2934 debugf("Truncated message.\n");