Import dht-0.16.

This commit is contained in:
Juliusz Chroboczek 2011-01-09 21:48:40 +00:00
parent abcd56c034
commit 3d25f2dc7e
6 changed files with 108 additions and 103 deletions

View File

@ -1,3 +1,7 @@
23 December 2010: dht-0.16:
* Change the interface to allow sharing of the UDP socket e.g. with uTP.
1 July 2010: dht-0.15 1 July 2010: dht-0.15
* Port to Windows, for the needs of Transmission. * Port to Windows, for the needs of Transmission.

View File

@ -1,4 +1,4 @@
Copyright (c) 2009 by Juliusz Chroboczek Copyright (c) 2009, 2010 by Juliusz Chroboczek
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal

View File

@ -86,9 +86,8 @@ dht_periodic should be called if no data is available is returned in the
parameter tosleep. (You do not need to be particularly accurate; actually, parameter tosleep. (You do not need to be particularly accurate; actually,
it is a good idea to be late by a random value.) it is a good idea to be late by a random value.)
The parameter available indicates whether any data is available on the The parameters buf, buflen, from and fromlen optionally carry a received
socket. If it is 0, dht_periodic will not try to read data; if it is 1, it message. If buflen is 0, then no message was received.
will.
Dht_periodic also takes a callback, which will be called whenever something Dht_periodic also takes a callback, which will be called whenever something
interesting happens (see below). interesting happens (see below).

View File

@ -88,6 +88,8 @@ callback(void *closure,
printf("Received %d values.\n", (int)(data_len / 6)); printf("Received %d values.\n", (int)(data_len / 6));
} }
static unsigned char buf[4096];
int int
main(int argc, char **argv) main(int argc, char **argv)
{ {
@ -101,6 +103,8 @@ main(int argc, char **argv)
int quiet = 0, ipv4 = 1, ipv6 = 1; int quiet = 0, ipv4 = 1, ipv6 = 1;
struct sockaddr_in sin; struct sockaddr_in sin;
struct sockaddr_in6 sin6; struct sockaddr_in6 sin6;
struct sockaddr_storage from;
socklen_t fromlen;
memset(&sin, 0, sizeof(sin)); memset(&sin, 0, sizeof(sin));
sin.sin_family = AF_INET; sin.sin_family = AF_INET;
@ -338,7 +342,25 @@ main(int argc, char **argv)
if(exiting) if(exiting)
break; break;
rc = dht_periodic(rc > 0, &tosleep, callback, NULL); if(rc > 0) {
fromlen = sizeof(from);
if(s >= 0 && FD_ISSET(s, &readfds))
rc = recvfrom(s, buf, sizeof(buf) - 1, 0,
(struct sockaddr*)&from, &fromlen);
else if(s6 >= 0 && FD_ISSET(s6, &readfds))
rc = recvfrom(s6, buf, sizeof(buf) - 1, 0,
(struct sockaddr*)&from, &fromlen);
else
abort();
}
if(rc > 0) {
buf[rc] = '\0';
rc = dht_periodic(buf, rc, (struct sockaddr*)&from, fromlen,
&tosleep, callback, NULL);
} else {
rc = dht_periodic(NULL, 0, NULL, 0, &tosleep, callback, NULL);
}
if(rc < 0) { if(rc < 0) {
if(errno == EINTR) { if(errno == EINTR) {
continue; continue;

169
third-party/dht/dht.c vendored
View File

@ -1,5 +1,5 @@
/* /*
Copyright (c) 2010 by Juliusz Chroboczek Copyright (c) 2009, 2010 by Juliusz Chroboczek
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal
@ -66,7 +66,6 @@ THE SOFTWARE.
#ifdef WIN32 #ifdef WIN32
#define EAFNOSUPPORT WSAEAFNOSUPPORT #define EAFNOSUPPORT WSAEAFNOSUPPORT
#define EAGAIN WSAEWOULDBLOCK
static int static int
set_nonblocking(int fd, int nonblocking) set_nonblocking(int fd, int nonblocking)
{ {
@ -213,34 +212,34 @@ struct storage {
struct storage *next; struct storage *next;
}; };
static int send_ping(struct sockaddr *sa, int salen, static int send_ping(const struct sockaddr *sa, int salen,
const unsigned char *tid, int tid_len); const unsigned char *tid, int tid_len);
static int send_pong(struct sockaddr *sa, int salen, static int send_pong(const struct sockaddr *sa, int salen,
const unsigned char *tid, int tid_len); const unsigned char *tid, int tid_len);
static int send_find_node(struct sockaddr *sa, int salen, static int send_find_node(const struct sockaddr *sa, int salen,
const unsigned char *tid, int tid_len, const unsigned char *tid, int tid_len,
const unsigned char *target, int want, int confirm); const unsigned char *target, int want, int confirm);
static int send_nodes_peers(struct sockaddr *sa, int salen, static int send_nodes_peers(const struct sockaddr *sa, int salen,
const unsigned char *tid, int tid_len, const unsigned char *tid, int tid_len,
const unsigned char *nodes, int nodes_len, const unsigned char *nodes, int nodes_len,
const unsigned char *nodes6, int nodes6_len, const unsigned char *nodes6, int nodes6_len,
int af, struct storage *st, int af, struct storage *st,
const unsigned char *token, int token_len); const unsigned char *token, int token_len);
static int send_closest_nodes(struct sockaddr *sa, int salen, static int send_closest_nodes(const struct sockaddr *sa, int salen,
const unsigned char *tid, int tid_len, const unsigned char *tid, int tid_len,
const unsigned char *id, int want, const unsigned char *id, int want,
int af, struct storage *st, int af, struct storage *st,
const unsigned char *token, int token_len); const unsigned char *token, int token_len);
static int send_get_peers(struct sockaddr *sa, int salen, static int send_get_peers(const struct sockaddr *sa, int salen,
unsigned char *tid, int tid_len, unsigned char *tid, int tid_len,
unsigned char *infohash, int want, int confirm); unsigned char *infohash, int want, int confirm);
static int send_announce_peer(struct sockaddr *sa, int salen, static int send_announce_peer(const struct sockaddr *sa, int salen,
unsigned char *tid, int tid_len, unsigned char *tid, int tid_len,
unsigned char *infohas, unsigned short port, unsigned char *infohas, unsigned short port,
unsigned char *token, int token_len, int confirm); unsigned char *token, int token_len, int confirm);
static int send_peer_announced(struct sockaddr *sa, int salen, static int send_peer_announced(const struct sockaddr *sa, int salen,
unsigned char *tid, int tid_len); unsigned char *tid, int tid_len);
static int send_error(struct sockaddr *sa, int salen, static int send_error(const struct sockaddr *sa, int salen,
unsigned char *tid, int tid_len, unsigned char *tid, int tid_len,
int code, const char *message); int code, const char *message);
@ -350,7 +349,7 @@ print_hex(FILE *f, const unsigned char *buf, int buflen)
} }
static int static int
is_martian(struct sockaddr *sa) is_martian(const struct sockaddr *sa)
{ {
switch(sa->sa_family) { switch(sa->sa_family) {
case AF_INET: { case AF_INET: {
@ -688,7 +687,8 @@ pinged(struct node *n, struct bucket *b)
/* We just learnt about a node, not necessarily a new one. Confirm is 1 if /* We just learnt about a node, not necessarily a new one. Confirm is 1 if
the node sent a message, 2 if it sent us a reply. */ the node sent a message, 2 if it sent us a reply. */
static struct node * static struct node *
new_node(const unsigned char *id, struct sockaddr *sa, int salen, int confirm) new_node(const unsigned char *id, const struct sockaddr *sa, int salen,
int confirm)
{ {
struct bucket *b = find_bucket(id, sa->sa_family); struct bucket *b = find_bucket(id, sa->sa_family);
struct node *n; struct node *n;
@ -790,7 +790,7 @@ new_node(const unsigned char *id, struct sockaddr *sa, int salen, int confirm)
if(split) { if(split) {
debugf("Splitting.\n"); debugf("Splitting.\n");
split_bucket(b); b = split_bucket(b);
return new_node(id, sa, salen, confirm); return new_node(id, sa, salen, confirm);
} }
@ -880,7 +880,7 @@ find_search(unsigned short tid, int af)
static int static int
insert_search_node(unsigned char *id, insert_search_node(unsigned char *id,
struct sockaddr *sa, int salen, const struct sockaddr *sa, int salen,
struct search *sr, int replied, struct search *sr, int replied,
unsigned char *token, int token_len) unsigned char *token, int token_len)
{ {
@ -1221,7 +1221,7 @@ find_storage(const unsigned char *id)
} }
static int static int
storage_store(const unsigned char *id, struct sockaddr *sa) storage_store(const unsigned char *id, const struct sockaddr *sa)
{ {
int i, len; int i, len;
struct storage *st; struct storage *st;
@ -1332,7 +1332,7 @@ expire_storage(void)
/* We've just found out that a node is buggy. */ /* We've just found out that a node is buggy. */
static void static void
broken_node(const unsigned char *id, struct sockaddr *sa, int salen) broken_node(const unsigned char *id, const struct sockaddr *sa, int salen)
{ {
int i; int i;
@ -1382,7 +1382,7 @@ rotate_secrets(void)
#endif #endif
static void static void
make_token(struct sockaddr *sa, int old, unsigned char *token_return) make_token(const struct sockaddr *sa, int old, unsigned char *token_return)
{ {
void *ip; void *ip;
int iplen; int iplen;
@ -1407,7 +1407,8 @@ make_token(struct sockaddr *sa, int old, unsigned char *token_return)
ip, iplen, (unsigned char*)&port, 2); ip, iplen, (unsigned char*)&port, 2);
} }
static int static int
token_match(unsigned char *token, int token_len, struct sockaddr *sa) token_match(const unsigned char *token, int token_len,
const struct sockaddr *sa)
{ {
unsigned char t[TOKEN_SIZE]; unsigned char t[TOKEN_SIZE];
if(token_len != TOKEN_SIZE) if(token_len != TOKEN_SIZE)
@ -1831,68 +1832,46 @@ bucket_maintenance(int af)
} }
int int
dht_periodic(int available, time_t *tosleep, dht_periodic(const void *buf, size_t buflen,
const struct sockaddr *from, int fromlen,
time_t *tosleep,
dht_callback *callback, void *closure) dht_callback *callback, void *closure)
{ {
int i; int i;
gettimeofday(&now, NULL); gettimeofday(&now, NULL);
if(available) { if(buflen > 0) {
int rc, message; int message;
unsigned char tid[16], id[20], info_hash[20], target[20]; unsigned char tid[16], id[20], info_hash[20], target[20];
unsigned char buf[1536], nodes[256], nodes6[1024], token[128]; unsigned char nodes[256], nodes6[1024], token[128];
int tid_len = 16, token_len = 128; int tid_len = 16, token_len = 128;
int nodes_len = 256, nodes6_len = 1024; int nodes_len = 256, nodes6_len = 1024;
unsigned short port; unsigned short port;
unsigned char values[2048], values6[2048]; unsigned char values[2048], values6[2048];
int values_len = 2048, values6_len = 2048; int values_len = 2048, values6_len = 2048;
int want; int want;
struct sockaddr_storage source_storage;
struct sockaddr *source = (struct sockaddr*)&source_storage;
socklen_t sourcelen = sizeof(source_storage);
unsigned short ttid; unsigned short ttid;
rc = -1; if(is_martian(from))
if(dht_socket >= 0) {
rc = recvfrom(dht_socket, buf, 1536, 0, source, &sourcelen);
if(rc < 0 && errno != EAGAIN) {
return rc;
}
}
if(dht_socket6 >= 0 && rc < 0) {
rc = recvfrom(dht_socket6, buf, 1536, 0,
source, &sourcelen);
if(rc < 0 && errno != EAGAIN) {
return rc;
}
}
if(rc < 0 || sourcelen > sizeof(struct sockaddr_storage))
goto dontread;
if(is_martian(source))
goto dontread; goto dontread;
for(i = 0; i < DHT_MAX_BLACKLISTED; i++) { for(i = 0; i < DHT_MAX_BLACKLISTED; i++) {
if(memcmp(&blacklist[i], source, sourcelen) == 0) { if(memcmp(&blacklist[i], from, fromlen) == 0) {
debugf("Received packet from blacklisted node.\n"); debugf("Received packet from blacklisted node.\n");
goto dontread; goto dontread;
} }
} }
/* There's a bug in parse_message -- it will happily overflow the /* See parse_message. */
buffer if it's not NUL-terminated. For now, put a NUL at the
end of buffers. */
if(rc < 1536) { if(((char*)buf)[buflen] != '\0') {
buf[rc] = '\0'; debugf("Unterminated message.\n");
} else { errno = EINVAL;
debugf("Overlong message.\n"); return -1;
goto dontread;
} }
message = parse_message(buf, rc, tid, &tid_len, id, info_hash, message = parse_message(buf, buflen, tid, &tid_len, id, info_hash,
target, &port, token, &token_len, target, &port, token, &token_len,
nodes, &nodes_len, nodes6, &nodes6_len, nodes, &nodes_len, nodes6, &nodes6_len,
values, &values_len, values6, &values6_len, values, &values_len, values6, &values6_len,
@ -1900,7 +1879,7 @@ dht_periodic(int available, time_t *tosleep,
if(message < 0 || message == ERROR || id_cmp(id, zeroes) == 0) { if(message < 0 || message == ERROR || id_cmp(id, zeroes) == 0) {
debugf("Unparseable message: "); debugf("Unparseable message: ");
debug_printable(buf, rc); debug_printable(buf, buflen);
debugf("\n"); debugf("\n");
goto dontread; goto dontread;
} }
@ -1922,36 +1901,36 @@ dht_periodic(int available, time_t *tosleep,
case REPLY: case REPLY:
if(tid_len != 4) { if(tid_len != 4) {
debugf("Broken node truncates transaction ids: "); debugf("Broken node truncates transaction ids: ");
debug_printable(buf, rc); debug_printable(buf, buflen);
debugf("\n"); debugf("\n");
/* This is really annoying, as it means that we will /* This is really annoying, as it means that we will
time-out all our searches that go through this node. time-out all our searches that go through this node.
Kill it. */ Kill it. */
broken_node(id, source, sourcelen); broken_node(id, from, fromlen);
goto dontread; goto dontread;
} }
if(tid_match(tid, "pn", NULL)) { if(tid_match(tid, "pn", NULL)) {
debugf("Pong!\n"); debugf("Pong!\n");
new_node(id, source, sourcelen, 2); new_node(id, from, fromlen, 2);
} else if(tid_match(tid, "fn", NULL) || } else if(tid_match(tid, "fn", NULL) ||
tid_match(tid, "gp", NULL)) { tid_match(tid, "gp", NULL)) {
int gp = 0; int gp = 0;
struct search *sr = NULL; struct search *sr = NULL;
if(tid_match(tid, "gp", &ttid)) { if(tid_match(tid, "gp", &ttid)) {
gp = 1; gp = 1;
sr = find_search(ttid, source->sa_family); sr = find_search(ttid, from->sa_family);
} }
debugf("Nodes found (%d+%d)%s!\n", nodes_len/26, nodes6_len/38, debugf("Nodes found (%d+%d)%s!\n", nodes_len/26, nodes6_len/38,
gp ? " for get_peers" : ""); gp ? " for get_peers" : "");
if(nodes_len % 26 != 0 || nodes6_len % 38 != 0) { if(nodes_len % 26 != 0 || nodes6_len % 38 != 0) {
debugf("Unexpected length for node info!\n"); debugf("Unexpected length for node info!\n");
broken_node(id, source, sourcelen); broken_node(id, from, fromlen);
} else if(gp && sr == NULL) { } else if(gp && sr == NULL) {
debugf("Unknown search!\n"); debugf("Unknown search!\n");
new_node(id, source, sourcelen, 1); new_node(id, from, fromlen, 1);
} else { } else {
int i; int i;
new_node(id, source, sourcelen, 2); new_node(id, from, fromlen, 2);
for(i = 0; i < nodes_len / 26; i++) { for(i = 0; i < nodes_len / 26; i++) {
unsigned char *ni = nodes + i * 26; unsigned char *ni = nodes + i * 26;
struct sockaddr_in sin; struct sockaddr_in sin;
@ -1993,7 +1972,7 @@ dht_periodic(int available, time_t *tosleep,
search_send_get_peers(sr, NULL); search_send_get_peers(sr, NULL);
} }
if(sr) { if(sr) {
insert_search_node(id, source, sourcelen, sr, insert_search_node(id, from, fromlen, sr,
1, token, token_len); 1, token, token_len);
if(values_len > 0 || values6_len > 0) { if(values_len > 0 || values6_len > 0) {
debugf("Got values (%d+%d)!\n", debugf("Got values (%d+%d)!\n",
@ -2012,13 +1991,13 @@ dht_periodic(int available, time_t *tosleep,
} else if(tid_match(tid, "ap", &ttid)) { } else if(tid_match(tid, "ap", &ttid)) {
struct search *sr; struct search *sr;
debugf("Got reply to announce_peer.\n"); debugf("Got reply to announce_peer.\n");
sr = find_search(ttid, source->sa_family); sr = find_search(ttid, from->sa_family);
if(!sr) { if(!sr) {
debugf("Unknown search!\n"); debugf("Unknown search!\n");
new_node(id, source, sourcelen, 1); new_node(id, from, fromlen, 1);
} else { } else {
int i; int i;
new_node(id, source, sourcelen, 2); new_node(id, from, fromlen, 2);
for(i = 0; i < sr->numnodes; i++) for(i = 0; i < sr->numnodes; i++)
if(id_cmp(sr->nodes[i].id, id) == 0) { if(id_cmp(sr->nodes[i].id, id) == 0) {
sr->nodes[i].request_time = 0; sr->nodes[i].request_time = 0;
@ -2032,47 +2011,47 @@ dht_periodic(int available, time_t *tosleep,
} }
} else { } else {
debugf("Unexpected reply: "); debugf("Unexpected reply: ");
debug_printable(buf, rc); debug_printable(buf, buflen);
debugf("\n"); debugf("\n");
} }
break; break;
case PING: case PING:
debugf("Ping (%d)!\n", tid_len); debugf("Ping (%d)!\n", tid_len);
new_node(id, source, sourcelen, 1); new_node(id, from, fromlen, 1);
debugf("Sending pong.\n"); debugf("Sending pong.\n");
send_pong(source, sourcelen, tid, tid_len); send_pong(from, fromlen, tid, tid_len);
break; break;
case FIND_NODE: case FIND_NODE:
debugf("Find node!\n"); debugf("Find node!\n");
new_node(id, source, sourcelen, 1); new_node(id, from, fromlen, 1);
debugf("Sending closest nodes (%d).\n", want); debugf("Sending closest nodes (%d).\n", want);
send_closest_nodes(source, sourcelen, send_closest_nodes(from, fromlen,
tid, tid_len, target, want, tid, tid_len, target, want,
0, NULL, NULL, 0); 0, NULL, NULL, 0);
break; break;
case GET_PEERS: case GET_PEERS:
debugf("Get_peers!\n"); debugf("Get_peers!\n");
new_node(id, source, sourcelen, 1); new_node(id, from, fromlen, 1);
if(id_cmp(info_hash, zeroes) == 0) { if(id_cmp(info_hash, zeroes) == 0) {
debugf("Eek! Got get_peers with no info_hash.\n"); debugf("Eek! Got get_peers with no info_hash.\n");
send_error(source, sourcelen, tid, tid_len, send_error(from, fromlen, tid, tid_len,
203, "Get_peers with no info_hash"); 203, "Get_peers with no info_hash");
break; break;
} else { } else {
struct storage *st = find_storage(info_hash); struct storage *st = find_storage(info_hash);
unsigned char token[TOKEN_SIZE]; unsigned char token[TOKEN_SIZE];
make_token(source, 0, token); make_token(from, 0, token);
if(st && st->numpeers > 0) { if(st && st->numpeers > 0) {
debugf("Sending found%s peers.\n", debugf("Sending found%s peers.\n",
source->sa_family == AF_INET6 ? " IPv6" : ""); from->sa_family == AF_INET6 ? " IPv6" : "");
send_closest_nodes(source, sourcelen, send_closest_nodes(from, fromlen,
tid, tid_len, tid, tid_len,
info_hash, want, info_hash, want,
source->sa_family, st, from->sa_family, st,
token, TOKEN_SIZE); token, TOKEN_SIZE);
} else { } else {
debugf("Sending nodes for get_peers.\n"); debugf("Sending nodes for get_peers.\n");
send_closest_nodes(source, sourcelen, send_closest_nodes(from, fromlen,
tid, tid_len, info_hash, want, tid, tid_len, info_hash, want,
0, NULL, token, TOKEN_SIZE); 0, NULL, token, TOKEN_SIZE);
} }
@ -2080,31 +2059,31 @@ dht_periodic(int available, time_t *tosleep,
break; break;
case ANNOUNCE_PEER: case ANNOUNCE_PEER:
debugf("Announce peer!\n"); debugf("Announce peer!\n");
new_node(id, source, sourcelen, 1); new_node(id, from, fromlen, 1);
if(id_cmp(info_hash, zeroes) == 0) { if(id_cmp(info_hash, zeroes) == 0) {
debugf("Announce_peer with no info_hash.\n"); debugf("Announce_peer with no info_hash.\n");
send_error(source, sourcelen, tid, tid_len, send_error(from, fromlen, tid, tid_len,
203, "Announce_peer with no info_hash"); 203, "Announce_peer with no info_hash");
break; break;
} }
if(!token_match(token, token_len, source)) { if(!token_match(token, token_len, from)) {
debugf("Incorrect token for announce_peer.\n"); debugf("Incorrect token for announce_peer.\n");
send_error(source, sourcelen, tid, tid_len, send_error(from, fromlen, tid, tid_len,
203, "Announce_peer with wrong token"); 203, "Announce_peer with wrong token");
break; break;
} }
if(port == 0) { if(port == 0) {
debugf("Announce_peer with forbidden port %d.\n", port); debugf("Announce_peer with forbidden port %d.\n", port);
send_error(source, sourcelen, tid, tid_len, send_error(from, fromlen, tid, tid_len,
203, "Announce_peer with forbidden port number"); 203, "Announce_peer with forbidden port number");
break; break;
} }
storage_store(info_hash, source); storage_store(info_hash, from);
/* Note that if storage_store failed, we lie to the requestor. /* Note that if storage_store failed, we lie to the requestor.
This is to prevent them from backtracking, and hence This is to prevent them from backtracking, and hence
polluting the DHT. */ polluting the DHT. */
debugf("Sending peer announced.\n"); debugf("Sending peer announced.\n");
send_peer_announced(source, sourcelen, tid, tid_len); send_peer_announced(from, fromlen, tid, tid_len);
} }
} }
@ -2328,7 +2307,7 @@ dht_send(const void *buf, size_t len, int flags,
} }
int int
send_ping(struct sockaddr *sa, int salen, send_ping(const struct sockaddr *sa, int salen,
const unsigned char *tid, int tid_len) const unsigned char *tid, int tid_len)
{ {
char buf[512]; char buf[512];
@ -2348,7 +2327,7 @@ send_ping(struct sockaddr *sa, int salen,
} }
int int
send_pong(struct sockaddr *sa, int salen, send_pong(const struct sockaddr *sa, int salen,
const unsigned char *tid, int tid_len) const unsigned char *tid, int tid_len)
{ {
char buf[512]; char buf[512];
@ -2367,7 +2346,7 @@ send_pong(struct sockaddr *sa, int salen,
} }
int int
send_find_node(struct sockaddr *sa, int salen, send_find_node(const struct sockaddr *sa, int salen,
const unsigned char *tid, int tid_len, const unsigned char *tid, int tid_len,
const unsigned char *target, int want, int confirm) const unsigned char *target, int want, int confirm)
{ {
@ -2396,7 +2375,7 @@ send_find_node(struct sockaddr *sa, int salen,
} }
int int
send_nodes_peers(struct sockaddr *sa, int salen, send_nodes_peers(const struct sockaddr *sa, int salen,
const unsigned char *tid, int tid_len, const unsigned char *tid, int tid_len,
const unsigned char *nodes, int nodes_len, const unsigned char *nodes, int nodes_len,
const unsigned char *nodes6, int nodes6_len, const unsigned char *nodes6, int nodes6_len,
@ -2523,7 +2502,7 @@ buffer_closest_nodes(unsigned char *nodes, int numnodes,
} }
int int
send_closest_nodes(struct sockaddr *sa, int salen, send_closest_nodes(const struct sockaddr *sa, int salen,
const unsigned char *tid, int tid_len, const unsigned char *tid, int tid_len,
const unsigned char *id, int want, const unsigned char *id, int want,
int af, struct storage *st, int af, struct storage *st,
@ -2570,7 +2549,7 @@ send_closest_nodes(struct sockaddr *sa, int salen,
} }
int int
send_get_peers(struct sockaddr *sa, int salen, send_get_peers(const struct sockaddr *sa, int salen,
unsigned char *tid, int tid_len, unsigned char *infohash, unsigned char *tid, int tid_len, unsigned char *infohash,
int want, int confirm) int want, int confirm)
{ {
@ -2600,7 +2579,7 @@ send_get_peers(struct sockaddr *sa, int salen,
} }
int int
send_announce_peer(struct sockaddr *sa, int salen, send_announce_peer(const struct sockaddr *sa, int salen,
unsigned char *tid, int tid_len, unsigned char *tid, int tid_len,
unsigned char *infohash, unsigned short port, unsigned char *infohash, unsigned short port,
unsigned char *token, int token_len, int confirm) unsigned char *token, int token_len, int confirm)
@ -2630,7 +2609,7 @@ send_announce_peer(struct sockaddr *sa, int salen,
} }
static int static int
send_peer_announced(struct sockaddr *sa, int salen, send_peer_announced(const struct sockaddr *sa, int salen,
unsigned char *tid, int tid_len) unsigned char *tid, int tid_len)
{ {
char buf[512]; char buf[512];
@ -2651,7 +2630,7 @@ send_peer_announced(struct sockaddr *sa, int salen,
} }
static int static int
send_error(struct sockaddr *sa, int salen, send_error(const struct sockaddr *sa, int salen,
unsigned char *tid, int tid_len, unsigned char *tid, int tid_len,
int code, const char *message) int code, const char *message)
{ {

View File

@ -1,5 +1,5 @@
/* /*
Copyright (c) 2009 by Juliusz Chroboczek Copyright (c) 2009, 2010 by Juliusz Chroboczek
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal
@ -36,8 +36,9 @@ extern FILE *dht_debug;
int dht_init(int s, int s6, const unsigned char *id, const unsigned char *v); int dht_init(int s, int s6, const unsigned char *id, const unsigned char *v);
int dht_insert_node(const unsigned char *id, struct sockaddr *sa, int salen); int dht_insert_node(const unsigned char *id, struct sockaddr *sa, int salen);
int dht_ping_node(struct sockaddr *sa, int salen); int dht_ping_node(struct sockaddr *sa, int salen);
int dht_periodic(int available, time_t *tosleep, int dht_periodic(const void *buf, size_t buflen,
dht_callback *callback, void *closure); const struct sockaddr *from, int fromlen,
time_t *tosleep, dht_callback *callback, void *closure);
int dht_search(const unsigned char *id, int port, int af, int dht_search(const unsigned char *id, int port, int af,
dht_callback *callback, void *closure); dht_callback *callback, void *closure);
int dht_nodes(int af, int dht_nodes(int af,