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))
45 #define ANNOUNCE_PEER 5
50 static const unsigned char zeroes[20] = {0};
51 static const unsigned char v4prefix[16] =
52 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF, 0, 0, 0, 0};
54 static unsigned char myid[20];
55 static unsigned char my_v[9];
57 static int dht_socket = -1;
58 static int dht_socket6 = -1;
61 unsigned char id[160];
62 struct sockaddr_storage ss;
66 #define CIRCULAR_LIST_SIZE 256
68 struct circular_list {
71 struct node nodes[CIRCULAR_LIST_SIZE];
74 static struct circular_list v4_new, v6_new, v4_confirmed, v6_confirmed;
76 #define MAX_TOKEN_BUCKET_TOKENS 40
77 static time_t token_bucket_time;
78 static int token_bucket_tokens;
80 static bool verbose = true;
82 // ------------------------ >8 ------------------------
85 getAddr(const struct sockaddr *sa, const socklen_t saLen)
87 static char host[NI_MAXHOST];
88 static char port[NI_MAXSERV];
97 NI_NUMERICHOST | NI_NUMERICSERV);
99 fprintf(stderr, "getnameinfo: %s\n", gai_strerror(rc));
102 snprintf(addr, sizeof addr, "[%s]:%s", host, port);
108 const unsigned char *buf,
110 unsigned char *tid_return,
112 unsigned char *id_return,
113 unsigned char *info_hash_return,
114 unsigned char *target_return,
115 unsigned short *port_return,
116 unsigned char *token_return,
118 unsigned char *nodes_return,
120 unsigned char *nodes6_return,
122 unsigned char *values_return,
124 unsigned char *values6_return,
127 const struct sockaddr *sa,
128 const socklen_t saLen)
130 /* This code will happily crash if the buffer is not NUL-terminated. */
131 if (buf[buflen] != '\0') {
133 printf("%s : parse_message with unterminated buffer\n", getAddr(sa, saLen));
137 #define CHECK(ptr, len) \
138 if (((const unsigned char *)ptr) + (len) > (buf) + (buflen)) \
145 p = memmem(buf, buflen, "1:t", 3);
147 l = strtoul((const char *)p + 3, &q, 10);
148 if (q && *q == ':' && l > 0 && l < *tid_len) {
150 memcpy(tid_return, q + 1, l);
157 p = memmem(buf, buflen, "2:id20:", 7);
160 memcpy(id_return, p + 7, 20);
162 memset(id_return, 0, 20);
165 if (info_hash_return) {
166 p = memmem(buf, buflen, "9:info_hash20:", 14);
169 memcpy(info_hash_return, p + 14, 20);
171 memset(info_hash_return, 0, 20);
175 p = memmem(buf, buflen, "porti", 5);
177 l = strtoul((const char *)p + 5, &q, 10);
178 if (q && *q == 'e' && l > 0 && l < 0x10000)
179 *port_return = (unsigned short)l;
186 p = memmem(buf, buflen, "6:target20:", 11);
189 memcpy(target_return, p + 11, 20);
191 memset(target_return, 0, 20);
195 p = memmem(buf, buflen, "5:token", 7);
197 l = strtoul((const char *)p + 7, &q, 10);
198 if (q && *q == ':' && l > 0 && l < *token_len) {
200 memcpy(token_return, q + 1, l);
209 p = memmem(buf, buflen, "5:nodes", 7);
211 l = strtoul((const char *)p + 7, &q, 10);
212 if (q && *q == ':' && l > 0 && l < *nodes_len) {
214 memcpy(nodes_return, q + 1, l);
223 p = memmem(buf, buflen, "6:nodes6", 8);
225 l = strtoul((const char *)p + 8, &q, 10);
226 if (q && *q == ':' && l > 0 && l < *nodes6_len) {
228 memcpy(nodes6_return, q + 1, l);
236 if (values_len || values6_len) {
237 p = memmem(buf, buflen, "6:valuesl", 9);
239 size_t i = p - buf + 9;
240 unsigned long j = 0, j6 = 0;
242 l = strtoul((const char *)buf + i, &q, 10);
243 if (q && *q == ':' && l > 0) {
246 if (j + l > *values_len)
248 i = q + 1 + l - (const char *)buf;
249 memcpy((char *)values_return + j, q + 1, l);
251 } else if (l == 18) {
252 if (j6 + l > *values6_len)
254 i = q + 1 + l - (const char *)buf;
255 memcpy((char *)values6_return + j6, q + 1, l);
260 "%s : received weird value: %d bytes\n",
263 i = q + 1 + l - (const char *)buf;
269 if (i >= buflen || buf[i] != 'e')
271 printf("%s : unexpected end for values\n", getAddr(sa, saLen));
283 p = memmem(buf, buflen, "4:wantl", 7);
285 size_t i = p - buf + 7;
287 while (buf[i] > '0' && buf[i] <= '9' && buf[i + 1] == ':' &&
288 i + 2 + buf[i] - '0' < buflen) {
289 CHECK(buf + i + 2, buf[i] - '0');
290 if (buf[i] == '2' && memcmp(buf + i + 2, "n4", 2) == 0)
291 *want_return |= WANT4;
292 else if (buf[i] == '2' && memcmp(buf + i + 2, "n6", 2) == 0)
293 *want_return |= WANT6;
296 "%s : unexpected want flag: %c\n", getAddr(sa, saLen), buf[i]);
297 i += 2 + buf[i] - '0';
299 if (i >= buflen || buf[i] != 'e')
301 printf("%s : unexpected end for want\n", getAddr(sa, saLen));
309 if (memmem(buf, buflen, "1:y1:r", 6))
311 if (memmem(buf, buflen, "1:y1:e", 6))
313 if (!memmem(buf, buflen, "1:y1:q", 6))
315 if (memmem(buf, buflen, "1:q4:ping", 9))
317 if (memmem(buf, buflen, "1:q9:find_node", 14))
319 if (memmem(buf, buflen, "1:q9:get_peers", 14))
321 if (memmem(buf, buflen, "1:q13:announce_peer", 19))
322 return ANNOUNCE_PEER;
327 printf(": truncated message\n");
336 /* We could use a proper bencoding printer and parser, but the format of
337 DHT messages is fairly stylised, so this seemed simpler. */
339 #define CHECK(offset, delta, size) \
340 if (delta < 0 || offset + delta > size) \
343 #define INC(offset, delta, size) \
344 CHECK(offset, delta, size); \
347 #define COPY(buf, offset, src, delta, size) \
348 CHECK(offset, delta, size); \
349 memcpy(buf + offset, src, delta); \
352 #define ADD_V(buf, offset, size) COPY(buf, offset, my_v, (sizeof my_v), size)
355 is_martian(const struct sockaddr *sa)
357 switch (sa->sa_family) {
359 const struct sockaddr_in *sin = (const struct sockaddr_in *)sa;
360 const unsigned char *address = (const unsigned char *)&sin->sin_addr;
361 return sin->sin_port == 0 || (address[0] == 0) || (address[0] == 127) ||
362 ((address[0] & 0xE0) == 0xE0);
365 const struct sockaddr_in6 *sin6 = (const struct sockaddr_in6 *)sa;
366 const unsigned char *address = (const unsigned char *)&sin6->sin6_addr;
367 return sin6->sin6_port == 0 || (address[0] == 0xFF) ||
368 (address[0] == 0xFE && (address[1] & 0xC0) == 0x80) ||
369 (memcmp(address, zeroes, 15) == 0 &&
370 (address[15] == 0 || address[15] == 1)) ||
371 (memcmp(address, v4prefix, 12) == 0);
377 /* Forget about the ``XOR-metric''. An id is just a path from the
378 root of the tree, so bits are numbered from the start. */
381 id_cmp(const unsigned char *restrict id1, const unsigned char *restrict id2)
383 /* Memcmp is guaranteed to perform an unsigned comparison. */
384 return memcmp(id1, id2, 20);
387 /* Our transaction-ids are 4-bytes long, with the first two bytes identi-
388 fying the kind of request, and the remaining two a sequence number in
392 make_tid(unsigned char *tid_return, const char *prefix, const unsigned short seqno)
394 tid_return[0] = prefix[0] & 0xFF;
395 tid_return[1] = prefix[1] & 0xFF;
396 memcpy(tid_return + 2, &seqno, 2);
400 tid_match(const unsigned char *tid, const char *prefix, unsigned short *seqno_return)
402 if (tid[0] == (prefix[0] & 0xFF) && tid[1] == (prefix[1] & 0xFF)) {
404 memcpy(seqno_return, tid + 2, 2);
411 circular(int from, int to)
415 return x + CIRCULAR_LIST_SIZE;
420 list_elements(struct circular_list *list)
422 return circular(list->head, list->tail);
426 list_empty(struct circular_list *list)
428 return list_elements(list) == 0;
432 list_free(struct circular_list *list)
434 return circular(list->tail + 1, list->head);
438 list_pop(struct circular_list *list, struct sockaddr_storage *ss, socklen_t *sslen)
440 if (list->head == list->tail)
443 memcpy(ss, &list->nodes[list->head].ss, list->nodes[list->head].sslen);
444 *sslen = list->nodes[list->head].sslen;
445 list->head = (list->head + 1) % CIRCULAR_LIST_SIZE;
451 struct circular_list *list,
453 struct sockaddr_storage *ss,
456 if (list->head == list->tail)
459 int n = random() % (list->tail - list->head);
460 n = (list->head + n) % CIRCULAR_LIST_SIZE;
463 memcpy(id, &list->nodes[n].id, 20);
464 memcpy(ss, &list->nodes[n].ss, list->nodes[n].sslen);
465 *sslen = list->nodes[n].sslen;
469 /* We just learnt about a node, not necessarily a new one. Confirm is 1 if
470 the node sent a message, 2 if it sent us a reply. */
474 const unsigned char *id,
475 const struct sockaddr *sa,
476 const socklen_t salen,
479 struct circular_list *list;
480 if (sa->sa_family == AF_INET)
481 list = confirm >= 2 ? &v4_confirmed : &v4_new;
482 else if (sa->sa_family == AF_INET6)
483 list = confirm >= 2 ? &v6_confirmed : &v6_new;
487 /* A node that sends us a request is most probably bootstrapping.
488 We want to avoid getting our tables full of very young nodes -- only
489 include such a node if we have plenty of space. */
491 if (confirm == 1 && list_free(list) < 32)
494 for (int i = list->head; i != list->tail; i = (i + 1) % CIRCULAR_LIST_SIZE) {
495 struct node *n = &list->nodes[i];
496 if (n->sslen == salen && memcmp(&n->ss, sa, salen) == 0)
500 memcpy(&list->nodes[list->tail].id, id, 160);
501 memcpy(&list->nodes[list->tail].ss, sa, salen);
502 list->nodes[list->tail].sslen = salen;
503 list->tail = (list->tail + 1) % CIRCULAR_LIST_SIZE;
504 if (list->head == list->tail)
505 list->head = (list->head + 1) % CIRCULAR_LIST_SIZE;
507 printf("%s : new node\n", getAddr(sa, salen));
515 time_t now = time(NULL);
516 if (token_bucket_tokens == 0) {
517 token_bucket_tokens =
518 MIN(MAX_TOKEN_BUCKET_TOKENS, 4 * (now - token_bucket_time));
519 token_bucket_time = now;
521 if (token_bucket_tokens == 0)
523 token_bucket_tokens--;
531 const struct sockaddr *sa,
532 const socklen_t salen)
537 if (sa->sa_family == AF_INET)
539 else if (sa->sa_family == AF_INET6)
544 errno = EAFNOSUPPORT;
547 return sendto(s, buf, len, 0, sa, salen);
552 const struct sockaddr *sa,
553 const socklen_t salen,
554 const unsigned char *tid,
555 const size_t tid_len)
559 int rc = snprintf(buf + i, 512 - i, "d1:ad2:id20:");
561 COPY(buf, i, myid, 20, 512);
562 rc = snprintf(buf + i, 512 - i, "e1:q4:ping1:t%zu:", tid_len);
564 COPY(buf, i, tid, tid_len, 512);
566 rc = snprintf(buf + i, 512 - i, "1:y1:qe");
569 printf("%s <- PING\n", getAddr(sa, salen));
570 return dht_send(buf, (size_t)i, sa, salen);
579 const struct sockaddr *sa,
580 const socklen_t salen,
581 const unsigned char *tid,
582 const size_t tid_len)
586 int rc = snprintf(buf + i, 512 - i, "d1:rd2:id20:");
588 COPY(buf, i, myid, 20, 512);
589 rc = snprintf(buf + i, 512 - i, "e1:t%zu:", tid_len);
591 COPY(buf, i, tid, tid_len, 512);
593 rc = snprintf(buf + i, 512 - i, "1:y1:re");
596 printf("%s <- PONG\n", getAddr(sa, salen));
597 return dht_send(buf, (size_t)i, sa, salen);
606 const struct sockaddr *sa,
607 const socklen_t salen,
608 const unsigned char *tid,
609 const size_t tid_len,
610 const unsigned char *target,
615 int rc = snprintf(buf + i, 512 - i, "d1:ad2:id20:");
617 COPY(buf, i, myid, 20, 512);
618 rc = snprintf(buf + i, 512 - i, "6:target20:");
620 COPY(buf, i, target, 20, 512);
626 (want & WANT4) ? "2:n4" : "",
627 (want & WANT6) ? "2:n6" : "");
630 rc = snprintf(buf + i, 512 - i, "e1:q9:find_node1:t%zu:", tid_len);
632 COPY(buf, i, tid, tid_len, 512);
634 rc = snprintf(buf + i, 512 - i, "1:y1:qe");
637 printf("%s <- FIND_NODE\n", getAddr(sa, salen));
638 return dht_send(buf, (size_t)i, sa, salen);
647 struct circular_list *list,
652 if (list_empty(list))
655 struct sockaddr_storage ss;
659 rc = list_pop(list, &ss, &sslen);
663 rc = list_random(list, NULL, &ss, &sslen);
668 unsigned char ttid[4];
670 make_tid(ttid, "pn", 0);
671 return send_ping((struct sockaddr *)&ss, sslen, ttid, 4);
673 unsigned char id[20];
674 arc4random_buf(id, sizeof id);
675 make_tid(ttid, "fn", 0);
676 return send_find_node((struct sockaddr *)&ss, sslen, ttid, 4, id, want);
681 newSock(const char *host, const char *port)
683 struct addrinfo hints;
684 memset(&hints, 0, sizeof(hints));
685 hints.ai_family = AF_UNSPEC;
686 hints.ai_socktype = SOCK_DGRAM;
687 struct addrinfo *res = NULL;
688 int rc = getaddrinfo(host, port, &hints, &res);
690 err(EXIT_FAILURE, "getaddrinfo: %s\n", gai_strerror(rc));
691 int sock = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
693 err(EXIT_FAILURE, "socket()");
694 if (bind(sock, res->ai_addr, res->ai_addrlen) != 0)
695 err(EXIT_FAILURE, "bind()");
696 rc = fcntl(sock, F_GETFL, 0);
698 err(EXIT_FAILURE, "F_GETFL");
699 rc = fcntl(sock, F_SETFL, (rc | O_NONBLOCK));
701 err(EXIT_FAILURE, "F_SETFL");
712 if (setrlimit(res, &r) == -1) {
713 err(EXIT_FAILURE, "setrlimit()");
719 const struct sockaddr *sa,
720 const socklen_t salen,
721 const unsigned char *tid,
722 const size_t tid_len,
723 const unsigned char *nodes,
724 const size_t nodes_len,
725 const unsigned char *nodes6,
726 const size_t nodes6_len)
730 int rc = snprintf(buf + i, 2048 - i, "d1:rd2:id20:");
732 COPY(buf, i, myid, 20, 2048);
734 rc = snprintf(buf + i, 2048 - i, "5:nodes%zu:", nodes_len);
736 COPY(buf, i, nodes, nodes_len, 2048);
738 if (nodes6_len > 0) {
739 rc = snprintf(buf + i, 2048 - i, "6:nodes6%zu:", nodes6_len);
741 COPY(buf, i, nodes6, nodes6_len, 2048);
743 rc = snprintf(buf + i, 2048 - i, "e1:t%zu:", tid_len);
745 COPY(buf, i, tid, tid_len, 2048);
747 rc = snprintf(buf + i, 2048 - i, "1:y1:re");
749 return dht_send(buf, (size_t)i, sa, salen);
757 buffer_random_nodes(int af, unsigned char *nodes)
759 struct circular_list *list;
762 list = &v4_confirmed;
765 list = &v6_confirmed;
771 struct sockaddr_storage ss;
773 unsigned char id[20];
777 rc = list_random(list, id, &ss, &sslen);
782 struct sockaddr_in *sin = (struct sockaddr_in *)&ss;
783 memcpy(nodes + n * 26, id, 20);
784 memcpy(nodes + n * 26 + 20, &sin->sin_addr, 4);
785 memcpy(nodes + n * 26 + 24, &sin->sin_port, 2);
790 struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)&ss;
791 memcpy(nodes + n * 38, id, 20);
792 memcpy(nodes + n * 38 + 20, &sin6->sin6_addr, 16);
793 memcpy(nodes + n * 38 + 36, &sin6->sin6_port, 2);
806 const struct sockaddr *sa,
807 const socklen_t salen,
808 const unsigned char *tid,
809 const size_t tid_len,
812 unsigned char nodes[8 * 26];
813 unsigned char nodes6[8 * 38];
817 want = sa->sa_family == AF_INET ? WANT4 : WANT6;
819 numnodes = buffer_random_nodes(AF_INET, nodes);
821 numnodes6 = buffer_random_nodes(AF_INET6, nodes6);
823 printf("%s <- NODES (%d+%d)\n", getAddr(sa, salen), numnodes, numnodes6);
825 sa, salen, tid, tid_len, nodes, numnodes * 26, nodes6, numnodes6 * 38);
830 const struct sockaddr *sa,
831 const socklen_t salen,
832 const unsigned char *tid,
833 const size_t tid_len,
839 int rc = snprintf(buf + i, 512 - i, "d1:eli%de%d:", code, (int)strlen(message));
841 COPY(buf, i, message, (int)strlen(message), 512);
842 rc = snprintf(buf + i, 512 - i, "e1:t%zu:", tid_len);
844 COPY(buf, i, tid, tid_len, 512);
846 rc = snprintf(buf + i, 512 - i, "1:y1:ee");
848 return dht_send(buf, (size_t)i, sa, salen);
856 main(int argc, char **argv)
859 char *ipv4addr = NULL;
860 char *ipv6addr = NULL;
864 opt = getopt(argc, argv, "q4:6:");
873 ipv4addr = strdup(optarg);
876 ipv6addr = strdup(optarg);
888 const char *ourPort = strdup(argv[i++]);
889 if (ipv4addr != NULL) {
890 dht_socket = newSock(ipv4addr, ourPort);
892 if (ipv6addr != NULL) {
893 dht_socket6 = newSock(ipv6addr, ourPort);
896 arc4random_buf(myid, sizeof myid);
897 memcpy(my_v, "1:v4:JB\0\0", 9);
900 unsigned char ttid[4];
903 struct addrinfo hints, *info, *infop;
904 memset(&hints, 0, sizeof(hints));
905 hints.ai_socktype = SOCK_DGRAM;
908 hints.ai_family = AF_INET6;
909 else if (dht_socket6 < 0)
910 hints.ai_family |= AF_INET;
911 rc = getaddrinfo(argv[i], argv[i + 1], &hints, &info);
913 err(EXIT_FAILURE, "getaddrinfo: %s\n", gai_strerror(rc));
921 make_tid(ttid, "pn", 0);
922 send_ping(infop->ai_addr, infop->ai_addrlen, ttid, 4);
923 infop = infop->ai_next;
930 token_bucket_time = time(NULL);
931 token_bucket_tokens = MAX_TOKEN_BUCKET_TOKENS;
933 struct pollfd fds[2];
934 fds[0].fd = dht_socket;
935 fds[0].events = POLLIN;
936 fds[1].fd = dht_socket6;
937 fds[1].events = POLLIN;
941 close(STDOUT_FILENO);
942 rlimited(RLIMIT_NPROC);
943 rlimited(RLIMIT_FSIZE);
945 rlimited(RLIMIT_NOFILE);
946 #endif // __FreeBSD__
950 if ((dht_socket >= 0 && list_elements(&v4_confirmed) <= 16) ||
951 (dht_socket6 >= 0 && list_elements(&v6_confirmed) <= 16))
954 tv_sec = random() % 30;
955 int tv_msec = random() % 1000;
960 list_elements(&v4_confirmed),
961 list_elements(&v6_confirmed),
962 list_elements(&v4_new),
963 list_elements(&v6_new));
966 rc = poll(fds, 2, tv_sec * 1000 + tv_msec);
974 unsigned char tid[16];
975 unsigned char id[20];
976 unsigned char info_hash[20];
977 unsigned char target[20];
978 unsigned char buf[1536];
979 unsigned char nodes[256];
980 unsigned char nodes6[1024];
981 unsigned char token[128];
982 size_t tid_len = sizeof tid;
983 size_t token_len = sizeof token;
984 size_t nodes_len = sizeof nodes;
985 size_t nodes6_len = sizeof nodes6;
987 unsigned char values[2048];
988 unsigned char values6[2048];
989 size_t values_len = sizeof values;
990 size_t values6_len = sizeof values6;
992 struct sockaddr_storage source_storage;
993 struct sockaddr *source = (struct sockaddr *)&source_storage;
994 socklen_t sourcelen = sizeof(source_storage);
996 if (fds[0].revents != 0) {
997 if ((fds[0].revents & (POLLERR | POLLNVAL)) > 0) {
998 fprintf(stderr, "error in fds[0]");
1001 got = recvfrom(dht_socket, buf, 1536, 0, source, &sourcelen);
1003 } else if (fds[1].revents != 0) {
1004 if ((fds[1].revents & (POLLERR | POLLNVAL)) > 0) {
1005 fprintf(stderr, "error in fds[1]");
1008 got = recvfrom(dht_socket6, buf, 1536, 0, source, &sourcelen);
1012 if (got < 0 || sourcelen > sizeof(struct sockaddr_storage))
1015 if (is_martian(source))
1018 /* There's a bug in parse_message -- it will happily overflow the
1019 buffer if it's not NUL-terminated. For now, put a NUL at the
1026 printf("%s : overlong message\n", getAddr(source, sourcelen));
1030 message = parse_message(
1053 if (id_cmp(id, myid) == 0) {
1056 "%s : received message from self\n",
1057 getAddr(source, sourcelen));
1061 if (message > REPLY) {
1062 /* Rate limit requests. */
1063 if (!token_bucket()) {
1066 "%s : dropping request due to rate limiting.\n",
1067 getAddr(source, sourcelen));
1077 "%s : broken node truncates transaction ids\n",
1078 getAddr(source, sourcelen));
1081 if (tid_match(tid, "pn", NULL)) {
1083 printf("%s -> PONG\n", getAddr(source, sourcelen));
1084 new_node(id, source, sourcelen, 2);
1085 } else if (tid_match(tid, "fn", NULL)) {
1088 "%s -> NODES (%zu+%zu)\n",
1089 getAddr(source, sourcelen),
1092 if (nodes_len % 26 != 0 || nodes6_len % 38 != 0) {
1095 "%s : unexpected length for node info\n",
1096 getAddr(source, sourcelen));
1098 new_node(id, source, sourcelen, 2);
1100 for (n = 0; n < nodes_len / 26; n++) {
1101 unsigned char *ni = nodes + n * 26;
1102 struct sockaddr_in sin;
1103 if (id_cmp(ni, myid) == 0)
1105 memset(&sin, 0, sizeof(sin));
1106 sin.sin_family = AF_INET;
1107 memcpy(&sin.sin_addr, ni + 20, 4);
1108 memcpy(&sin.sin_port, ni + 24, 2);
1109 new_node(ni, (struct sockaddr *)&sin, sizeof(sin), 0);
1111 for (n = 0; n < nodes6_len / 38; n++) {
1112 unsigned char *ni = nodes6 + n * 38;
1113 struct sockaddr_in6 sin6;
1114 if (id_cmp(ni, myid) == 0)
1116 memset(&sin6, 0, sizeof(sin6));
1117 sin6.sin6_family = AF_INET6;
1118 memcpy(&sin6.sin6_addr, ni + 20, 16);
1119 memcpy(&sin6.sin6_port, ni + 36, 2);
1120 new_node(ni, (struct sockaddr *)&sin6, sizeof(sin6), 0);
1125 printf("%s : unexpected reply\n", getAddr(source, sourcelen));
1131 printf("%s -> PING (%zu)\n", getAddr(source, sourcelen), tid_len);
1132 new_node(id, source, sourcelen, 1);
1133 send_pong(source, sourcelen, tid, tid_len);
1139 if (message == FIND_NODE)
1140 printf("%s -> FIND_NODE\n", getAddr(source, sourcelen));
1142 printf("%s -> GET_PEERS\n", getAddr(source, sourcelen));
1144 new_node(id, source, sourcelen, 1);
1145 send_random_nodes(source, sourcelen, tid, tid_len, want);
1149 printf("%s -> ANNOUNCE_PEER\n", getAddr(source, sourcelen));
1156 "This node doesn't accept announces");
1163 /* We need to be careful to avoid a positive feedback loop. Make
1164 sure we send at most one packet each time through the select
1167 if (dht_socket6 < 0)
1169 else if (dht_socket < 0)
1172 send4 = (random() % 2) == 1;
1175 int want = dht_socket6 >= 0 && list_free(&v6_new) > 8 ? (WANT4 | WANT6) : 0;
1176 if (!list_empty(&v4_new))
1177 send_request(&v4_new, true, list_free(&v4_new) < 8, want);
1178 else if (!list_empty(&v4_confirmed))
1179 send_request(&v4_confirmed, false, false, want);
1181 int want = dht_socket >= 0 && list_free(&v4_new) > 8 ? (WANT4 | WANT6) : 0;
1182 if (!list_empty(&v6_new))
1183 send_request(&v6_new, true, list_free(&v6_new) < 8, want);
1184 else if (!list_empty(&v6_confirmed))
1185 send_request(&v6_confirmed, false, false, want);
1190 fprintf(stderr, "dht-bootstrap [-q] [-4 ADDR4] [-6 ADDR6] port [node port...]\n");