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))
42 void setproctitle_fast(const char *_fmt, ...) {}
47 send_ping(struct sockaddr *sa, int salen, const unsigned char *tid, int tid_len);
49 send_pong(struct sockaddr *sa, int salen, const unsigned char *tid, int tid_len);
54 const unsigned char *tid,
56 const unsigned char *target,
62 const unsigned char *tid,
64 const unsigned char *nodes,
66 const unsigned char *nodes6,
72 const unsigned char *tid,
74 const unsigned char *id,
90 #define ANNOUNCE_PEER 5
97 const unsigned char *buf,
99 unsigned char *tid_return,
101 unsigned char *id_return,
102 unsigned char *info_hash_return,
103 unsigned char *target_return,
104 unsigned short *port_return,
105 unsigned char *token_return,
107 unsigned char *nodes_return,
109 unsigned char *nodes6_return,
111 unsigned char *values_return,
113 unsigned char *values6_return,
117 static const unsigned char zeroes[20] = {0};
118 static const unsigned char v4prefix[16] =
119 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF, 0, 0, 0, 0};
121 static unsigned char myid[20];
122 static int have_v = 0;
123 static unsigned char my_v[9];
125 static int dht_socket = -1;
126 static int dht_socket6 = -1;
129 unsigned char id[160];
130 struct sockaddr_storage ss;
134 #define CIRCULAR_LIST_SIZE 256
136 struct circular_list {
139 struct node nodes[CIRCULAR_LIST_SIZE];
142 static struct circular_list v4_new, v6_new, v4_confirmed, v6_confirmed;
144 #define MAX_TOKEN_BUCKET_TOKENS 40
145 static time_t token_bucket_time;
146 static int token_bucket_tokens;
148 static FILE *dht_debug = NULL;
151 debugf(const char *format, ...)
153 if (dht_debug == NULL)
156 va_start(args, format);
157 vfprintf(dht_debug, format, args);
163 is_martian(struct sockaddr *sa)
165 switch (sa->sa_family) {
167 struct sockaddr_in *sin = (struct sockaddr_in *)sa;
168 const unsigned char *address = (const unsigned char *)&sin->sin_addr;
169 return sin->sin_port == 0 || (address[0] == 0) || (address[0] == 127) ||
170 ((address[0] & 0xE0) == 0xE0);
173 struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sa;
174 const unsigned char *address = (const unsigned char *)&sin6->sin6_addr;
175 return sin6->sin6_port == 0 || (address[0] == 0xFF) ||
176 (address[0] == 0xFE && (address[1] & 0xC0) == 0x80) ||
177 (memcmp(address, zeroes, 15) == 0 &&
178 (address[15] == 0 || address[15] == 1)) ||
179 (memcmp(address, v4prefix, 12) == 0);
187 /* Forget about the ``XOR-metric''. An id is just a path from the
188 root of the tree, so bits are numbered from the start. */
191 id_cmp(const unsigned char *restrict id1, const unsigned char *restrict id2)
193 /* Memcmp is guaranteed to perform an unsigned comparison. */
194 return memcmp(id1, id2, 20);
197 /* Our transaction-ids are 4-bytes long, with the first two bytes identi-
198 fying the kind of request, and the remaining two a sequence number in
202 make_tid(unsigned char *tid_return, const char *prefix, unsigned short seqno)
204 tid_return[0] = prefix[0] & 0xFF;
205 tid_return[1] = prefix[1] & 0xFF;
206 memcpy(tid_return + 2, &seqno, 2);
210 tid_match(const unsigned char *tid, const char *prefix, unsigned short *seqno_return)
212 if (tid[0] == (prefix[0] & 0xFF) && tid[1] == (prefix[1] & 0xFF)) {
214 memcpy(seqno_return, tid + 2, 2);
221 circular(int from, int to)
225 return x + CIRCULAR_LIST_SIZE;
230 list_elements(struct circular_list *list)
232 return circular(list->head, list->tail);
236 list_empty(struct circular_list *list)
238 return list_elements(list) == 0;
242 list_free(struct circular_list *list)
244 return circular(list->tail + 1, list->head);
248 list_pop(struct circular_list *list, struct sockaddr_storage *ss, socklen_t *sslen)
250 if (list->head == list->tail)
253 memcpy(ss, &list->nodes[list->head].ss, list->nodes[list->head].sslen);
254 *sslen = list->nodes[list->head].sslen;
255 list->head = (list->head + 1) % CIRCULAR_LIST_SIZE;
261 struct circular_list *list,
263 struct sockaddr_storage *ss,
267 if (list->head == list->tail)
270 n = random() % (list->tail - list->head);
271 n = (list->head + n) % CIRCULAR_LIST_SIZE;
274 memcpy(id, &list->nodes[n].id, 20);
275 memcpy(ss, &list->nodes[n].ss, list->nodes[n].sslen);
276 *sslen = list->nodes[n].sslen;
280 /* We just learnt about a node, not necessarily a new one. Confirm is 1 if
281 the node sent a message, 2 if it sent us a reply. */
284 new_node(unsigned char *id, struct sockaddr *sa, socklen_t salen, int confirm)
286 struct circular_list *list;
289 if (sa->sa_family == AF_INET)
290 list = confirm >= 2 ? &v4_confirmed : &v4_new;
291 else if (sa->sa_family == AF_INET6)
292 list = confirm >= 2 ? &v6_confirmed : &v6_new;
296 /* A node that sends us a request is most probably bootstrapping.
297 We want to avoid getting our tables full of very young nodes -- only
298 include such a node if we have plenty of space. */
300 if (confirm == 1 && list_free(list) < 32)
303 for (i = list->head; i != list->tail; i = (i + 1) % CIRCULAR_LIST_SIZE) {
304 struct node *n = &list->nodes[i];
305 if (n->sslen == salen && memcmp(&n->ss, sa, salen) == 0)
309 memcpy(&list->nodes[list->tail].id, id, 160);
310 memcpy(&list->nodes[list->tail].ss, sa, salen);
311 list->nodes[list->tail].sslen = salen;
312 list->tail = (list->tail + 1) % CIRCULAR_LIST_SIZE;
313 if (list->head == list->tail)
314 list->head = (list->head + 1) % CIRCULAR_LIST_SIZE;
322 time_t now = time(NULL);
323 if (token_bucket_tokens == 0) {
324 token_bucket_tokens =
325 MIN(MAX_TOKEN_BUCKET_TOKENS, 4 * (now - token_bucket_time));
326 token_bucket_time = now;
329 if (token_bucket_tokens == 0)
332 token_bucket_tokens--;
337 send_request(struct circular_list *list, int dopop, int doping, int want)
339 unsigned char ttid[4];
340 struct sockaddr_storage ss;
344 if (list_empty(list))
348 rc = list_pop(list, &ss, &sslen);
352 rc = list_random(list, NULL, &ss, &sslen);
358 make_tid(ttid, "pn", 0);
359 debugf("Sending ping.\n");
360 return send_ping((struct sockaddr *)&ss, sslen, ttid, 4);
362 unsigned char id[20];
363 arc4random_buf(id, sizeof id);
364 make_tid(ttid, "fn", 0);
365 debugf("Sending find_node.\n");
366 return send_find_node((struct sockaddr *)&ss, sslen, ttid, 4, id, want);
371 newSock(const char *host, const char *port)
373 struct addrinfo hints;
374 memset(&hints, 0, sizeof(hints));
375 hints.ai_family = AF_UNSPEC;
376 hints.ai_socktype = SOCK_DGRAM;
377 struct addrinfo *res = NULL;
378 int rc = getaddrinfo(host, port, &hints, &res);
380 err(EXIT_FAILURE, "getaddrinfo: %s\n", gai_strerror(rc));
381 int sock = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
383 err(EXIT_FAILURE, "socket()");
384 if (bind(sock, res->ai_addr, res->ai_addrlen) != 0)
385 err(EXIT_FAILURE, "bind()");
386 rc = fcntl(sock, F_GETFL, 0);
388 err(EXIT_FAILURE, "F_GETFL");
389 rc = fcntl(sock, F_SETFL, (rc | O_NONBLOCK));
391 err(EXIT_FAILURE, "F_SETFL");
402 if (setrlimit(res, &r) == -1) {
403 err(EXIT_FAILURE, "can not setrlimit()");
408 main(int argc, char **argv)
412 char *ipv4addr = NULL;
413 char *ipv6addr = NULL;
417 opt = getopt(argc, argv, "q4:6:");
426 ipv4addr = strdup(optarg);
429 ipv6addr = strdup(optarg);
441 const char *ourPort = strdup(argv[i++]);
442 if (ipv4addr != NULL) {
443 dht_socket = newSock(ipv4addr, ourPort);
445 if (ipv6addr != NULL) {
446 dht_socket6 = newSock(ipv6addr, ourPort);
449 arc4random_buf(myid, sizeof myid);
451 memcpy(my_v, "1:v4:JB\0\0", 9);
458 unsigned char ttid[4];
461 struct addrinfo hints, *info, *infop;
462 memset(&hints, 0, sizeof(hints));
463 hints.ai_socktype = SOCK_DGRAM;
466 hints.ai_family = AF_INET6;
467 else if (dht_socket6 < 0)
468 hints.ai_family |= AF_INET;
469 rc = getaddrinfo(argv[i], argv[i + 1], &hints, &info);
471 err(EXIT_FAILURE, "getaddrinfo: %s\n", gai_strerror(rc));
479 make_tid(ttid, "pn", 0);
480 debugf("Sending ping.\n");
481 send_ping(infop->ai_addr, infop->ai_addrlen, ttid, 4);
482 infop = infop->ai_next;
489 token_bucket_time = time(NULL);
490 token_bucket_tokens = MAX_TOKEN_BUCKET_TOKENS;
492 struct pollfd fds[2];
493 fds[0].fd = dht_socket;
494 fds[0].events = POLLIN;
495 fds[1].fd = dht_socket6;
496 fds[1].events = POLLIN;
500 close(STDOUT_FILENO);
501 rlimited(RLIMIT_NPROC);
502 rlimited(RLIMIT_FSIZE);
504 rlimited(RLIMIT_NOFILE);
505 #endif // __FreeBSD__
509 if ((dht_socket >= 0 && list_elements(&v4_confirmed) <= 16) ||
510 (dht_socket6 >= 0 && list_elements(&v6_confirmed) <= 16))
513 tv_sec = random() % 30;
514 int tv_msec = random() % 1000;
518 list_elements(&v4_confirmed),
519 list_elements(&v6_confirmed),
520 list_elements(&v4_new),
521 list_elements(&v6_new));
523 rc = poll(fds, 2, tv_sec * 1000 + tv_msec);
531 unsigned char tid[16], id[20], info_hash[20], target[20];
532 unsigned char buf[1536], nodes[256], nodes6[1024], token[128];
533 int tid_len = 16, token_len = 128;
534 int nodes_len = 256, nodes6_len = 1024;
536 unsigned char values[2048], values6[2048];
537 int values_len = 2048, values6_len = 2048;
539 struct sockaddr_storage source_storage;
540 struct sockaddr *source = (struct sockaddr *)&source_storage;
541 socklen_t sourcelen = sizeof(source_storage);
542 if (fds[0].revents != 0) {
543 if ((fds[0].revents & (POLLERR | POLLNVAL)) > 0) {
544 fprintf(stderr, "error in fds[0]");
547 rc = recvfrom(dht_socket, buf, 1536, 0, source, &sourcelen);
549 } else if (fds[1].revents != 0) {
550 if ((fds[1].revents & (POLLERR | POLLNVAL)) > 0) {
551 fprintf(stderr, "error in fds[1]");
554 rc = recvfrom(dht_socket6, buf, 1536, 0, source, &sourcelen);
558 if (rc < 0 || sourcelen > sizeof(struct sockaddr_storage))
561 if (is_martian(source))
564 /* There's a bug in parse_message -- it will happily overflow the
565 buffer if it's not NUL-terminated. For now, put a NUL at the
571 debugf("Overlong message.\n");
575 message = parse_message(
596 if (id_cmp(id, myid) == 0) {
597 debugf("Received message from self.\n");
601 if (message > REPLY) {
602 /* Rate limit requests. */
603 if (!token_bucket()) {
604 debugf("Dropping request due to rate limiting.\n");
612 debugf("Broken node truncates transaction ids.\n");
615 if (tid_match(tid, "pn", NULL)) {
617 new_node(id, source, sourcelen, 2);
618 } else if (tid_match(tid, "fn", NULL)) {
619 debugf("Nodes found!\n");
620 if (nodes_len % 26 != 0 || nodes6_len % 38 != 0) {
621 debugf("Unexpected length for node info!\n");
623 new_node(id, source, sourcelen, 2);
624 for (i = 0; i < nodes_len / 26; i++) {
625 unsigned char *ni = nodes + i * 26;
626 struct sockaddr_in sin;
627 if (id_cmp(ni, myid) == 0)
629 memset(&sin, 0, sizeof(sin));
630 sin.sin_family = AF_INET;
631 memcpy(&sin.sin_addr, ni + 20, 4);
632 memcpy(&sin.sin_port, ni + 24, 2);
633 new_node(ni, (struct sockaddr *)&sin, sizeof(sin), 0);
635 for (i = 0; i < nodes6_len / 38; i++) {
636 unsigned char *ni = nodes6 + i * 38;
637 struct sockaddr_in6 sin6;
638 if (id_cmp(ni, myid) == 0)
640 memset(&sin6, 0, sizeof(sin6));
641 sin6.sin6_family = AF_INET6;
642 memcpy(&sin6.sin6_addr, ni + 20, 16);
643 memcpy(&sin6.sin6_port, ni + 36, 2);
644 new_node(ni, (struct sockaddr *)&sin6, sizeof(sin6), 0);
648 debugf("Unexpected reply!\n");
653 debugf("Ping (%d)!\n", tid_len);
654 new_node(id, source, sourcelen, 1);
655 debugf("Sending pong.\n");
656 send_pong(source, sourcelen, tid, tid_len);
661 if (message == FIND_NODE)
662 debugf("Find node!\n");
664 debugf("Get peers!\n");
665 new_node(id, source, sourcelen, 1);
666 debugf("Sending nodes (%d).\n", want);
667 send_random_nodes(source, sourcelen, tid, tid_len, target, want);
670 debugf("Announce peer!\n");
677 "This node doesn't accept announces");
684 /* We need to be careful to avoid a positive feedback loop. Make
685 sure we send at most one packet each time through the select
690 else if (dht_socket < 0)
693 send4 = random() % 2;
696 int want = dht_socket6 >= 0 && list_free(&v6_new) > 8 ? (WANT4 | WANT6) : 0;
697 if (!list_empty(&v4_new))
698 send_request(&v4_new, 1, list_free(&v4_new) < 8, want);
699 else if (!list_empty(&v4_confirmed))
700 send_request(&v4_confirmed, 0, 0, want);
702 int want = dht_socket >= 0 && list_free(&v4_new) > 8 ? (WANT4 | WANT6) : 0;
703 if (!list_empty(&v6_new))
704 send_request(&v6_new, 1, list_free(&v6_new) < 8, want);
705 else if (!list_empty(&v6_confirmed))
706 send_request(&v6_confirmed, 0, 0, want);
711 fprintf(stderr, "dht-bootstrap [-q] [-4 ADDR4] [-6 ADDR6] port [node port...]\n");
715 /* We could use a proper bencoding printer and parser, but the format of
716 DHT messages is fairly stylised, so this seemed simpler. */
718 #define CHECK(offset, delta, size) \
719 if (delta < 0 || offset + delta > size) \
722 #define INC(offset, delta, size) \
723 CHECK(offset, delta, size); \
726 #define COPY(buf, offset, src, delta, size) \
727 CHECK(offset, delta, size); \
728 memcpy(buf + offset, src, delta); \
731 #define ADD_V(buf, offset, size) \
733 COPY(buf, offset, my_v, sizeof(my_v), size); \
737 dht_send(const void *buf, size_t len, int flags, const struct sockaddr *sa, int salen)
744 if (sa->sa_family == AF_INET)
746 else if (sa->sa_family == AF_INET6)
752 errno = EAFNOSUPPORT;
756 return sendto(s, buf, len, flags, sa, salen);
760 send_ping(struct sockaddr *sa, int salen, const unsigned char *tid, int tid_len)
764 rc = snprintf(buf + i, 512 - i, "d1:ad2:id20:");
766 COPY(buf, i, myid, 20, 512);
767 rc = snprintf(buf + i, 512 - i, "e1:q4:ping1:t%d:", tid_len);
769 COPY(buf, i, tid, tid_len, 512);
771 rc = snprintf(buf + i, 512 - i, "1:y1:qe");
773 return dht_send(buf, i, 0, sa, salen);
781 send_pong(struct sockaddr *sa, int salen, const unsigned char *tid, int tid_len)
785 rc = snprintf(buf + i, 512 - i, "d1:rd2:id20:");
787 COPY(buf, i, myid, 20, 512);
788 rc = snprintf(buf + i, 512 - i, "e1:t%d:", tid_len);
790 COPY(buf, i, tid, tid_len, 512);
792 rc = snprintf(buf + i, 512 - i, "1:y1:re");
794 return dht_send(buf, i, 0, sa, salen);
805 const unsigned char *tid,
807 const unsigned char *target,
812 rc = snprintf(buf + i, 512 - i, "d1:ad2:id20:");
814 COPY(buf, i, myid, 20, 512);
815 rc = snprintf(buf + i, 512 - i, "6:target20:");
817 COPY(buf, i, target, 20, 512);
823 (want & WANT4) ? "2:n4" : "",
824 (want & WANT6) ? "2:n6" : "");
827 rc = snprintf(buf + i, 512 - i, "e1:q9:find_node1:t%d:", tid_len);
829 COPY(buf, i, tid, tid_len, 512);
831 rc = snprintf(buf + i, 512 - i, "1:y1:qe");
833 return dht_send(buf, i, 0, sa, salen);
844 const unsigned char *tid,
846 const unsigned char *nodes,
848 const unsigned char *nodes6,
854 rc = snprintf(buf + i, 2048 - i, "d1:rd2:id20:");
856 COPY(buf, i, myid, 20, 2048);
858 rc = snprintf(buf + i, 2048 - i, "5:nodes%d:", nodes_len);
860 COPY(buf, i, nodes, nodes_len, 2048);
862 if (nodes6_len > 0) {
863 rc = snprintf(buf + i, 2048 - i, "6:nodes6%d:", nodes6_len);
865 COPY(buf, i, nodes6, nodes6_len, 2048);
868 rc = snprintf(buf + i, 2048 - i, "e1:t%d:", tid_len);
870 COPY(buf, i, tid, tid_len, 2048);
872 rc = snprintf(buf + i, 2048 - i, "1:y1:re");
875 return dht_send(buf, i, 0, sa, salen);
883 buffer_random_nodes(int af, unsigned char *nodes)
885 struct circular_list *list;
886 struct sockaddr_storage ss;
888 unsigned char id[20];
894 list = &v4_confirmed;
897 list = &v6_confirmed;
905 rc = list_random(list, id, &ss, &sslen);
910 struct sockaddr_in *sin = (struct sockaddr_in *)&ss;
911 memcpy(nodes + n * 26, id, 20);
912 memcpy(nodes + n * 26 + 20, &sin->sin_addr, 4);
913 memcpy(nodes + n * 26 + 24, &sin->sin_port, 2);
918 struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)&ss;
919 memcpy(nodes + n * 38, id, 20);
920 memcpy(nodes + n * 38 + 20, &sin6->sin6_addr, 16);
921 memcpy(nodes + n * 38 + 36, &sin6->sin6_port, 2);
936 const unsigned char *tid,
938 const unsigned char *id,
941 unsigned char nodes[8 * 26];
942 unsigned char nodes6[8 * 38];
943 int numnodes = 0, numnodes6 = 0;
946 want = sa->sa_family == AF_INET ? WANT4 : WANT6;
949 numnodes = buffer_random_nodes(AF_INET, nodes);
952 numnodes6 = buffer_random_nodes(AF_INET6, nodes6);
955 sa, salen, tid, tid_len, nodes, numnodes * 26, nodes6, numnodes6 * 38);
970 rc = snprintf(buf + i, 512 - i, "d1:eli%de%d:", code, (int)strlen(message));
972 COPY(buf, i, message, (int)strlen(message), 512);
973 rc = snprintf(buf + i, 512 - i, "e1:t%d:", tid_len);
975 COPY(buf, i, tid, tid_len, 512);
977 rc = snprintf(buf + i, 512 - i, "1:y1:ee");
979 return dht_send(buf, i, 0, sa, salen);
993 const unsigned char *buf,
995 unsigned char *tid_return,
997 unsigned char *id_return,
998 unsigned char *info_hash_return,
999 unsigned char *target_return,
1000 unsigned short *port_return,
1001 unsigned char *token_return,
1003 unsigned char *nodes_return,
1005 unsigned char *nodes6_return,
1007 unsigned char *values_return,
1009 unsigned char *values6_return,
1013 const unsigned char *p;
1015 /* This code will happily crash if the buffer is not NUL-terminated. */
1016 if (buf[buflen] != '\0') {
1017 debugf("Eek! parse_message with unterminated buffer.\n");
1021 #define CHECK(ptr, len) \
1022 if (((unsigned char *)ptr) + (len) > (buf) + (buflen)) \
1026 p = memmem(buf, buflen, "1:t", 3);
1030 l = strtol((char *)p + 3, &q, 10);
1031 if (q && *q == ':' && l > 0 && l < *tid_len) {
1033 memcpy(tid_return, q + 1, l);
1040 p = memmem(buf, buflen, "2:id20:", 7);
1043 memcpy(id_return, p + 7, 20);
1045 memset(id_return, 0, 20);
1048 if (info_hash_return) {
1049 p = memmem(buf, buflen, "9:info_hash20:", 14);
1052 memcpy(info_hash_return, p + 14, 20);
1054 memset(info_hash_return, 0, 20);
1058 p = memmem(buf, buflen, "porti", 5);
1062 l = strtol((char *)p + 5, &q, 10);
1063 if (q && *q == 'e' && l > 0 && l < 0x10000)
1070 if (target_return) {
1071 p = memmem(buf, buflen, "6:target20:", 11);
1074 memcpy(target_return, p + 11, 20);
1076 memset(target_return, 0, 20);
1080 p = memmem(buf, buflen, "5:token", 7);
1084 l = strtol((char *)p + 7, &q, 10);
1085 if (q && *q == ':' && l > 0 && l < *token_len) {
1087 memcpy(token_return, q + 1, l);
1096 p = memmem(buf, buflen, "5:nodes", 7);
1100 l = strtol((char *)p + 7, &q, 10);
1101 if (q && *q == ':' && l > 0 && l < *nodes_len) {
1103 memcpy(nodes_return, q + 1, l);
1112 p = memmem(buf, buflen, "6:nodes6", 8);
1116 l = strtol((char *)p + 8, &q, 10);
1117 if (q && *q == ':' && l > 0 && l < *nodes6_len) {
1119 memcpy(nodes6_return, q + 1, l);
1127 if (values_len || values6_len) {
1128 p = memmem(buf, buflen, "6:valuesl", 9);
1130 int i = p - buf + 9;
1135 l = strtol((char *)buf + i, &q, 10);
1136 if (q && *q == ':' && l > 0) {
1139 if (j + l > *values_len)
1141 i = q + 1 + l - (char *)buf;
1142 memcpy((char *)values_return + j, q + 1, l);
1144 } else if (l == 18) {
1145 if (j6 + l > *values6_len)
1147 i = q + 1 + l - (char *)buf;
1148 memcpy((char *)values6_return + j6, q + 1, l);
1151 debugf("Received weird value -- %d bytes.\n", (int)l);
1152 i = q + 1 + l - (char *)buf;
1158 if (i >= buflen || buf[i] != 'e')
1159 debugf("eek... unexpected end for values.\n");
1171 p = memmem(buf, buflen, "4:wantl", 7);
1173 int i = p - buf + 7;
1175 while (buf[i] > '0' && buf[i] <= '9' && buf[i + 1] == ':' &&
1176 i + 2 + buf[i] - '0' < buflen) {
1177 CHECK(buf + i + 2, buf[i] - '0');
1178 if (buf[i] == '2' && memcmp(buf + i + 2, "n4", 2) == 0)
1179 *want_return |= WANT4;
1180 else if (buf[i] == '2' && memcmp(buf + i + 2, "n6", 2) == 0)
1181 *want_return |= WANT6;
1183 debugf("eek... unexpected want flag (%c)\n", buf[i]);
1184 i += 2 + buf[i] - '0';
1186 if (i >= buflen || buf[i] != 'e')
1187 debugf("eek... unexpected end for want.\n");
1195 if (memmem(buf, buflen, "1:y1:r", 6))
1197 if (memmem(buf, buflen, "1:y1:e", 6))
1199 if (!memmem(buf, buflen, "1:y1:q", 6))
1201 if (memmem(buf, buflen, "1:q4:ping", 9))
1203 if (memmem(buf, buflen, "1:q9:find_node", 14))
1205 if (memmem(buf, buflen, "1:q9:get_peers", 14))
1207 if (memmem(buf, buflen, "1:q13:announce_peer", 19))
1208 return ANNOUNCE_PEER;
1212 debugf("Truncated message.\n");