2 Copyright (c) 2009-2011 by Juliusz Chroboczek
4 Permission is hereby granted, free of charge, to any person obtaining a copy
5 of this software and associated documentation files (the "Software"), to deal
6 in the Software without restriction, including without limitation the rights
7 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 copies of the Software, and to permit persons to whom the Software is
9 furnished to do so, subject to the following conditions:
11 The above copyright notice and this permission notice shall be included in
12 all copies or substantial portions of the Software.
14 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
27 #include <netinet/in.h>
33 #include <sys/resource.h>
34 #include <sys/socket.h>
38 #define MIN(x, y) ((x) <= (y) ? (x) : (y))
41 send_ping(struct sockaddr *sa, int salen, const unsigned char *tid, int tid_len);
43 send_pong(struct sockaddr *sa, int salen, const unsigned char *tid, int tid_len);
48 const unsigned char *tid,
50 const unsigned char *target,
56 const unsigned char *tid,
58 const unsigned char *nodes,
60 const unsigned char *nodes6,
66 const unsigned char *tid,
68 const unsigned char *id,
84 #define ANNOUNCE_PEER 5
91 const unsigned char *buf,
93 unsigned char *tid_return,
95 unsigned char *id_return,
96 unsigned char *info_hash_return,
97 unsigned char *target_return,
98 unsigned short *port_return,
99 unsigned char *token_return,
101 unsigned char *nodes_return,
103 unsigned char *nodes6_return,
105 unsigned char *values_return,
107 unsigned char *values6_return,
111 static const unsigned char zeroes[20] = {0};
112 static const unsigned char v4prefix[16] =
113 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF, 0, 0, 0, 0};
115 static unsigned char myid[20];
116 static int have_v = 0;
117 static unsigned char my_v[9];
119 static int dht_socket = -1;
120 static int dht_socket6 = -1;
123 unsigned char id[160];
124 struct sockaddr_storage ss;
128 #define CIRCULAR_LIST_SIZE 256
130 struct circular_list {
133 struct node nodes[CIRCULAR_LIST_SIZE];
136 static struct circular_list v4_new, v6_new, v4_confirmed, v6_confirmed;
138 #define MAX_TOKEN_BUCKET_TOKENS 40
139 static time_t token_bucket_time;
140 static int token_bucket_tokens;
142 static FILE *dht_debug = NULL;
145 debugf(const char *format, ...)
147 if (dht_debug == NULL)
150 va_start(args, format);
151 vfprintf(dht_debug, format, args);
157 is_martian(struct sockaddr *sa)
159 switch (sa->sa_family) {
161 struct sockaddr_in *sin = (struct sockaddr_in *)sa;
162 const unsigned char *address = (const unsigned char *)&sin->sin_addr;
163 return sin->sin_port == 0 || (address[0] == 0) || (address[0] == 127) ||
164 ((address[0] & 0xE0) == 0xE0);
167 struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sa;
168 const unsigned char *address = (const unsigned char *)&sin6->sin6_addr;
169 return sin6->sin6_port == 0 || (address[0] == 0xFF) ||
170 (address[0] == 0xFE && (address[1] & 0xC0) == 0x80) ||
171 (memcmp(address, zeroes, 15) == 0 &&
172 (address[15] == 0 || address[15] == 1)) ||
173 (memcmp(address, v4prefix, 12) == 0);
181 /* Forget about the ``XOR-metric''. An id is just a path from the
182 root of the tree, so bits are numbered from the start. */
185 id_cmp(const unsigned char *restrict id1, const unsigned char *restrict id2)
187 /* Memcmp is guaranteed to perform an unsigned comparison. */
188 return memcmp(id1, id2, 20);
191 /* Our transaction-ids are 4-bytes long, with the first two bytes identi-
192 fying the kind of request, and the remaining two a sequence number in
196 make_tid(unsigned char *tid_return, const char *prefix, unsigned short seqno)
198 tid_return[0] = prefix[0] & 0xFF;
199 tid_return[1] = prefix[1] & 0xFF;
200 memcpy(tid_return + 2, &seqno, 2);
204 tid_match(const unsigned char *tid, const char *prefix, unsigned short *seqno_return)
206 if (tid[0] == (prefix[0] & 0xFF) && tid[1] == (prefix[1] & 0xFF)) {
208 memcpy(seqno_return, tid + 2, 2);
215 circular(int from, int to)
219 return x + CIRCULAR_LIST_SIZE;
224 list_elements(struct circular_list *list)
226 return circular(list->head, list->tail);
230 list_empty(struct circular_list *list)
232 return list_elements(list) == 0;
236 list_free(struct circular_list *list)
238 return circular(list->tail + 1, list->head);
242 list_pop(struct circular_list *list, struct sockaddr_storage *ss, socklen_t *sslen)
244 if (list->head == list->tail)
247 memcpy(ss, &list->nodes[list->head].ss, list->nodes[list->head].sslen);
248 *sslen = list->nodes[list->head].sslen;
249 list->head = (list->head + 1) % CIRCULAR_LIST_SIZE;
255 struct circular_list *list,
257 struct sockaddr_storage *ss,
261 if (list->head == list->tail)
264 n = random() % (list->tail - list->head);
265 n = (list->head + n) % CIRCULAR_LIST_SIZE;
268 memcpy(id, &list->nodes[n].id, 20);
269 memcpy(ss, &list->nodes[n].ss, list->nodes[n].sslen);
270 *sslen = list->nodes[n].sslen;
274 /* We just learnt about a node, not necessarily a new one. Confirm is 1 if
275 the node sent a message, 2 if it sent us a reply. */
278 new_node(unsigned char *id, struct sockaddr *sa, socklen_t salen, int confirm)
280 struct circular_list *list;
283 if (sa->sa_family == AF_INET)
284 list = confirm >= 2 ? &v4_confirmed : &v4_new;
285 else if (sa->sa_family == AF_INET6)
286 list = confirm >= 2 ? &v6_confirmed : &v6_new;
290 /* A node that sends us a request is most probably bootstrapping.
291 We want to avoid getting our tables full of very young nodes -- only
292 include such a node if we have plenty of space. */
294 if (confirm == 1 && list_free(list) < 32)
297 for (i = list->head; i != list->tail; i = (i + 1) % CIRCULAR_LIST_SIZE) {
298 struct node *n = &list->nodes[i];
299 if (n->sslen == salen && memcmp(&n->ss, sa, salen) == 0)
303 memcpy(&list->nodes[list->tail].id, id, 160);
304 memcpy(&list->nodes[list->tail].ss, sa, salen);
305 list->nodes[list->tail].sslen = salen;
306 list->tail = (list->tail + 1) % CIRCULAR_LIST_SIZE;
307 if (list->head == list->tail)
308 list->head = (list->head + 1) % CIRCULAR_LIST_SIZE;
316 time_t now = time(NULL);
317 if (token_bucket_tokens == 0) {
318 token_bucket_tokens =
319 MIN(MAX_TOKEN_BUCKET_TOKENS, 4 * (now - token_bucket_time));
320 token_bucket_time = now;
323 if (token_bucket_tokens == 0)
326 token_bucket_tokens--;
331 send_request(struct circular_list *list, int dopop, int doping, int want)
333 unsigned char ttid[4];
334 struct sockaddr_storage ss;
338 if (list_empty(list))
342 rc = list_pop(list, &ss, &sslen);
346 rc = list_random(list, NULL, &ss, &sslen);
352 make_tid(ttid, "pn", 0);
353 debugf("Sending ping.\n");
354 return send_ping((struct sockaddr *)&ss, sslen, ttid, 4);
356 unsigned char id[20];
357 arc4random_buf(id, sizeof id);
358 make_tid(ttid, "fn", 0);
359 debugf("Sending find_node.\n");
360 return send_find_node((struct sockaddr *)&ss, sslen, ttid, 4, id, want);
365 newSock(const char *host, const char *port)
367 struct addrinfo hints;
368 memset(&hints, 0, sizeof(hints));
369 hints.ai_family = AF_UNSPEC;
370 hints.ai_socktype = SOCK_DGRAM;
371 struct addrinfo *res = NULL;
372 int rc = getaddrinfo(host, port, &hints, &res);
374 err(EXIT_FAILURE, "getaddrinfo: %s\n", gai_strerror(rc));
375 int sock = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
377 err(EXIT_FAILURE, "socket()");
378 if (bind(sock, res->ai_addr, res->ai_addrlen) != 0)
379 err(EXIT_FAILURE, "bind()");
380 rc = fcntl(sock, F_GETFL, 0);
382 err(EXIT_FAILURE, "F_GETFL");
383 rc = fcntl(sock, F_SETFL, (rc | O_NONBLOCK));
385 err(EXIT_FAILURE, "F_SETFL");
396 if (setrlimit(res, &r) == -1) {
397 err(EXIT_FAILURE, "can not setrlimit()");
402 main(int argc, char **argv)
406 char *ipv4addr = NULL;
407 char *ipv6addr = NULL;
411 opt = getopt(argc, argv, "q4:6:");
420 ipv4addr = strdup(optarg);
423 ipv6addr = strdup(optarg);
435 const char *ourPort = strdup(argv[i++]);
436 if (ipv4addr != NULL) {
437 dht_socket = newSock(ipv4addr, ourPort);
439 if (ipv6addr != NULL) {
440 dht_socket6 = newSock(ipv6addr, ourPort);
443 arc4random_buf(myid, sizeof myid);
445 memcpy(my_v, "1:v4:JB\0\0", 9);
452 unsigned char ttid[4];
455 struct addrinfo hints, *info, *infop;
456 memset(&hints, 0, sizeof(hints));
457 hints.ai_socktype = SOCK_DGRAM;
460 hints.ai_family = AF_INET6;
461 else if (dht_socket6 < 0)
462 hints.ai_family |= AF_INET;
463 rc = getaddrinfo(argv[i], argv[i + 1], &hints, &info);
465 err(EXIT_FAILURE, "getaddrinfo: %s\n", gai_strerror(rc));
473 make_tid(ttid, "pn", 0);
474 debugf("Sending ping.\n");
475 send_ping(infop->ai_addr, infop->ai_addrlen, ttid, 4);
476 infop = infop->ai_next;
483 token_bucket_time = time(NULL);
484 token_bucket_tokens = MAX_TOKEN_BUCKET_TOKENS;
486 struct pollfd fds[2];
487 fds[0].fd = dht_socket;
488 fds[0].events = POLLIN;
489 fds[1].fd = dht_socket6;
490 fds[1].events = POLLIN;
494 close(STDOUT_FILENO);
495 rlimited(RLIMIT_NPROC);
496 rlimited(RLIMIT_FSIZE);
498 rlimited(RLIMIT_NOFILE);
499 #endif // __FreeBSD__
503 if ((dht_socket >= 0 && list_elements(&v4_confirmed) <= 16) ||
504 (dht_socket6 >= 0 && list_elements(&v6_confirmed) <= 16))
507 tv_sec = random() % 30;
508 int tv_msec = random() % 1000;
513 list_elements(&v4_confirmed),
514 list_elements(&v6_confirmed),
515 list_elements(&v4_new),
516 list_elements(&v6_new));
518 rc = poll(fds, 2, tv_sec * 1000 + tv_msec);
526 unsigned char tid[16], id[20], info_hash[20], target[20];
527 unsigned char buf[1536], nodes[256], nodes6[1024], token[128];
528 int tid_len = 16, token_len = 128;
529 int nodes_len = 256, nodes6_len = 1024;
531 unsigned char values[2048], values6[2048];
532 int values_len = 2048, values6_len = 2048;
534 struct sockaddr_storage source_storage;
535 struct sockaddr *source = (struct sockaddr *)&source_storage;
536 socklen_t sourcelen = sizeof(source_storage);
537 if (fds[0].revents != 0) {
538 if ((fds[0].revents & (POLLERR | POLLNVAL)) > 0) {
539 fprintf(stderr, "error in fds[0]");
542 rc = recvfrom(dht_socket, buf, 1536, 0, source, &sourcelen);
544 } else if (fds[1].revents != 0) {
545 if ((fds[1].revents & (POLLERR | POLLNVAL)) > 0) {
546 fprintf(stderr, "error in fds[1]");
549 rc = recvfrom(dht_socket6, buf, 1536, 0, source, &sourcelen);
553 if (rc < 0 || sourcelen > sizeof(struct sockaddr_storage))
556 if (is_martian(source))
559 /* There's a bug in parse_message -- it will happily overflow the
560 buffer if it's not NUL-terminated. For now, put a NUL at the
566 debugf("Overlong message.\n");
570 message = parse_message(
591 if (id_cmp(id, myid) == 0) {
592 debugf("Received message from self.\n");
596 if (message > REPLY) {
597 /* Rate limit requests. */
598 if (!token_bucket()) {
599 debugf("Dropping request due to rate limiting.\n");
607 debugf("Broken node truncates transaction ids.\n");
610 if (tid_match(tid, "pn", NULL)) {
612 new_node(id, source, sourcelen, 2);
613 } else if (tid_match(tid, "fn", NULL)) {
614 debugf("Nodes found!\n");
615 if (nodes_len % 26 != 0 || nodes6_len % 38 != 0) {
616 debugf("Unexpected length for node info!\n");
618 new_node(id, source, sourcelen, 2);
619 for (i = 0; i < nodes_len / 26; i++) {
620 unsigned char *ni = nodes + i * 26;
621 struct sockaddr_in sin;
622 if (id_cmp(ni, myid) == 0)
624 memset(&sin, 0, sizeof(sin));
625 sin.sin_family = AF_INET;
626 memcpy(&sin.sin_addr, ni + 20, 4);
627 memcpy(&sin.sin_port, ni + 24, 2);
628 new_node(ni, (struct sockaddr *)&sin, sizeof(sin), 0);
630 for (i = 0; i < nodes6_len / 38; i++) {
631 unsigned char *ni = nodes6 + i * 38;
632 struct sockaddr_in6 sin6;
633 if (id_cmp(ni, myid) == 0)
635 memset(&sin6, 0, sizeof(sin6));
636 sin6.sin6_family = AF_INET6;
637 memcpy(&sin6.sin6_addr, ni + 20, 16);
638 memcpy(&sin6.sin6_port, ni + 36, 2);
639 new_node(ni, (struct sockaddr *)&sin6, sizeof(sin6), 0);
643 debugf("Unexpected reply!\n");
648 debugf("Ping (%d)!\n", tid_len);
649 new_node(id, source, sourcelen, 1);
650 debugf("Sending pong.\n");
651 send_pong(source, sourcelen, tid, tid_len);
656 if (message == FIND_NODE)
657 debugf("Find node!\n");
659 debugf("Get peers!\n");
660 new_node(id, source, sourcelen, 1);
661 debugf("Sending nodes (%d).\n", want);
662 send_random_nodes(source, sourcelen, tid, tid_len, target, want);
665 debugf("Announce peer!\n");
672 "This node doesn't accept announces");
679 /* We need to be careful to avoid a positive feedback loop. Make
680 sure we send at most one packet each time through the select
685 else if (dht_socket < 0)
688 send4 = random() % 2;
691 int want = dht_socket6 >= 0 && list_free(&v6_new) > 8 ? (WANT4 | WANT6) : 0;
692 if (!list_empty(&v4_new))
693 send_request(&v4_new, 1, list_free(&v4_new) < 8, want);
694 else if (!list_empty(&v4_confirmed))
695 send_request(&v4_confirmed, 0, 0, want);
697 int want = dht_socket >= 0 && list_free(&v4_new) > 8 ? (WANT4 | WANT6) : 0;
698 if (!list_empty(&v6_new))
699 send_request(&v6_new, 1, list_free(&v6_new) < 8, want);
700 else if (!list_empty(&v6_confirmed))
701 send_request(&v6_confirmed, 0, 0, want);
706 fprintf(stderr, "dht-bootstrap [-q] [-4 ADDR4] [-6 ADDR6] port [node port...]\n");
710 /* We could use a proper bencoding printer and parser, but the format of
711 DHT messages is fairly stylised, so this seemed simpler. */
713 #define CHECK(offset, delta, size) \
714 if (delta < 0 || offset + delta > size) \
717 #define INC(offset, delta, size) \
718 CHECK(offset, delta, size); \
721 #define COPY(buf, offset, src, delta, size) \
722 CHECK(offset, delta, size); \
723 memcpy(buf + offset, src, delta); \
726 #define ADD_V(buf, offset, size) \
728 COPY(buf, offset, my_v, sizeof(my_v), size); \
732 dht_send(const void *buf, size_t len, int flags, const struct sockaddr *sa, int salen)
739 if (sa->sa_family == AF_INET)
741 else if (sa->sa_family == AF_INET6)
747 errno = EAFNOSUPPORT;
751 return sendto(s, buf, len, flags, sa, salen);
755 send_ping(struct sockaddr *sa, int salen, const unsigned char *tid, int tid_len)
759 rc = snprintf(buf + i, 512 - i, "d1:ad2:id20:");
761 COPY(buf, i, myid, 20, 512);
762 rc = snprintf(buf + i, 512 - i, "e1:q4:ping1:t%d:", tid_len);
764 COPY(buf, i, tid, tid_len, 512);
766 rc = snprintf(buf + i, 512 - i, "1:y1:qe");
768 return dht_send(buf, i, 0, sa, salen);
776 send_pong(struct sockaddr *sa, int salen, const unsigned char *tid, int tid_len)
780 rc = snprintf(buf + i, 512 - i, "d1:rd2:id20:");
782 COPY(buf, i, myid, 20, 512);
783 rc = snprintf(buf + i, 512 - i, "e1:t%d:", tid_len);
785 COPY(buf, i, tid, tid_len, 512);
787 rc = snprintf(buf + i, 512 - i, "1:y1:re");
789 return dht_send(buf, i, 0, sa, salen);
800 const unsigned char *tid,
802 const unsigned char *target,
807 rc = snprintf(buf + i, 512 - i, "d1:ad2:id20:");
809 COPY(buf, i, myid, 20, 512);
810 rc = snprintf(buf + i, 512 - i, "6:target20:");
812 COPY(buf, i, target, 20, 512);
818 (want & WANT4) ? "2:n4" : "",
819 (want & WANT6) ? "2:n6" : "");
822 rc = snprintf(buf + i, 512 - i, "e1:q9:find_node1:t%d:", tid_len);
824 COPY(buf, i, tid, tid_len, 512);
826 rc = snprintf(buf + i, 512 - i, "1:y1:qe");
828 return dht_send(buf, i, 0, sa, salen);
839 const unsigned char *tid,
841 const unsigned char *nodes,
843 const unsigned char *nodes6,
849 rc = snprintf(buf + i, 2048 - i, "d1:rd2:id20:");
851 COPY(buf, i, myid, 20, 2048);
853 rc = snprintf(buf + i, 2048 - i, "5:nodes%d:", nodes_len);
855 COPY(buf, i, nodes, nodes_len, 2048);
857 if (nodes6_len > 0) {
858 rc = snprintf(buf + i, 2048 - i, "6:nodes6%d:", nodes6_len);
860 COPY(buf, i, nodes6, nodes6_len, 2048);
863 rc = snprintf(buf + i, 2048 - i, "e1:t%d:", tid_len);
865 COPY(buf, i, tid, tid_len, 2048);
867 rc = snprintf(buf + i, 2048 - i, "1:y1:re");
870 return dht_send(buf, i, 0, sa, salen);
878 buffer_random_nodes(int af, unsigned char *nodes)
880 struct circular_list *list;
881 struct sockaddr_storage ss;
883 unsigned char id[20];
889 list = &v4_confirmed;
892 list = &v6_confirmed;
900 rc = list_random(list, id, &ss, &sslen);
905 struct sockaddr_in *sin = (struct sockaddr_in *)&ss;
906 memcpy(nodes + n * 26, id, 20);
907 memcpy(nodes + n * 26 + 20, &sin->sin_addr, 4);
908 memcpy(nodes + n * 26 + 24, &sin->sin_port, 2);
913 struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)&ss;
914 memcpy(nodes + n * 38, id, 20);
915 memcpy(nodes + n * 38 + 20, &sin6->sin6_addr, 16);
916 memcpy(nodes + n * 38 + 36, &sin6->sin6_port, 2);
931 const unsigned char *tid,
933 const unsigned char *id,
936 unsigned char nodes[8 * 26];
937 unsigned char nodes6[8 * 38];
938 int numnodes = 0, numnodes6 = 0;
941 want = sa->sa_family == AF_INET ? WANT4 : WANT6;
944 numnodes = buffer_random_nodes(AF_INET, nodes);
947 numnodes6 = buffer_random_nodes(AF_INET6, nodes6);
950 sa, salen, tid, tid_len, nodes, numnodes * 26, nodes6, numnodes6 * 38);
965 rc = snprintf(buf + i, 512 - i, "d1:eli%de%d:", code, (int)strlen(message));
967 COPY(buf, i, message, (int)strlen(message), 512);
968 rc = snprintf(buf + i, 512 - i, "e1:t%d:", tid_len);
970 COPY(buf, i, tid, tid_len, 512);
972 rc = snprintf(buf + i, 512 - i, "1:y1:ee");
974 return dht_send(buf, i, 0, sa, salen);
988 const unsigned char *buf,
990 unsigned char *tid_return,
992 unsigned char *id_return,
993 unsigned char *info_hash_return,
994 unsigned char *target_return,
995 unsigned short *port_return,
996 unsigned char *token_return,
998 unsigned char *nodes_return,
1000 unsigned char *nodes6_return,
1002 unsigned char *values_return,
1004 unsigned char *values6_return,
1008 const unsigned char *p;
1010 /* This code will happily crash if the buffer is not NUL-terminated. */
1011 if (buf[buflen] != '\0') {
1012 debugf("Eek! parse_message with unterminated buffer.\n");
1016 #define CHECK(ptr, len) \
1017 if (((unsigned char *)ptr) + (len) > (buf) + (buflen)) \
1021 p = memmem(buf, buflen, "1:t", 3);
1025 l = strtol((char *)p + 3, &q, 10);
1026 if (q && *q == ':' && l > 0 && l < *tid_len) {
1028 memcpy(tid_return, q + 1, l);
1035 p = memmem(buf, buflen, "2:id20:", 7);
1038 memcpy(id_return, p + 7, 20);
1040 memset(id_return, 0, 20);
1043 if (info_hash_return) {
1044 p = memmem(buf, buflen, "9:info_hash20:", 14);
1047 memcpy(info_hash_return, p + 14, 20);
1049 memset(info_hash_return, 0, 20);
1053 p = memmem(buf, buflen, "porti", 5);
1057 l = strtol((char *)p + 5, &q, 10);
1058 if (q && *q == 'e' && l > 0 && l < 0x10000)
1065 if (target_return) {
1066 p = memmem(buf, buflen, "6:target20:", 11);
1069 memcpy(target_return, p + 11, 20);
1071 memset(target_return, 0, 20);
1075 p = memmem(buf, buflen, "5:token", 7);
1079 l = strtol((char *)p + 7, &q, 10);
1080 if (q && *q == ':' && l > 0 && l < *token_len) {
1082 memcpy(token_return, q + 1, l);
1091 p = memmem(buf, buflen, "5:nodes", 7);
1095 l = strtol((char *)p + 7, &q, 10);
1096 if (q && *q == ':' && l > 0 && l < *nodes_len) {
1098 memcpy(nodes_return, q + 1, l);
1107 p = memmem(buf, buflen, "6:nodes6", 8);
1111 l = strtol((char *)p + 8, &q, 10);
1112 if (q && *q == ':' && l > 0 && l < *nodes6_len) {
1114 memcpy(nodes6_return, q + 1, l);
1122 if (values_len || values6_len) {
1123 p = memmem(buf, buflen, "6:valuesl", 9);
1125 int i = p - buf + 9;
1130 l = strtol((char *)buf + i, &q, 10);
1131 if (q && *q == ':' && l > 0) {
1134 if (j + l > *values_len)
1136 i = q + 1 + l - (char *)buf;
1137 memcpy((char *)values_return + j, q + 1, l);
1139 } else if (l == 18) {
1140 if (j6 + l > *values6_len)
1142 i = q + 1 + l - (char *)buf;
1143 memcpy((char *)values6_return + j6, q + 1, l);
1146 debugf("Received weird value -- %d bytes.\n", (int)l);
1147 i = q + 1 + l - (char *)buf;
1153 if (i >= buflen || buf[i] != 'e')
1154 debugf("eek... unexpected end for values.\n");
1166 p = memmem(buf, buflen, "4:wantl", 7);
1168 int i = p - buf + 7;
1170 while (buf[i] > '0' && buf[i] <= '9' && buf[i + 1] == ':' &&
1171 i + 2 + buf[i] - '0' < buflen) {
1172 CHECK(buf + i + 2, buf[i] - '0');
1173 if (buf[i] == '2' && memcmp(buf + i + 2, "n4", 2) == 0)
1174 *want_return |= WANT4;
1175 else if (buf[i] == '2' && memcmp(buf + i + 2, "n6", 2) == 0)
1176 *want_return |= WANT6;
1178 debugf("eek... unexpected want flag (%c)\n", buf[i]);
1179 i += 2 + buf[i] - '0';
1181 if (i >= buflen || buf[i] != 'e')
1182 debugf("eek... unexpected end for want.\n");
1190 if (memmem(buf, buflen, "1:y1:r", 6))
1192 if (memmem(buf, buflen, "1:y1:e", 6))
1194 if (!memmem(buf, buflen, "1:y1:q", 6))
1196 if (memmem(buf, buflen, "1:q4:ping", 9))
1198 if (memmem(buf, buflen, "1:q9:find_node", 14))
1200 if (memmem(buf, buflen, "1:q9:get_peers", 14))
1202 if (memmem(buf, buflen, "1:q13:announce_peer", 19))
1203 return ANNOUNCE_PEER;
1207 debugf("Truncated message.\n");