Skip to content

Commit

Permalink
Change the interface to dht_periodic.
Browse files Browse the repository at this point in the history
Actually reading the data is now done by the caller, which allows sharing
the UDP socket, for example with uTP.
  • Loading branch information
Juliusz Chroboczek committed Nov 2, 2010
1 parent 1e43be0 commit de3705c
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 40 deletions.
24 changes: 23 additions & 1 deletion dht-example.c
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,8 @@ callback(void *closure,
printf("Received %d values.\n", (int)(data_len / 6));
}

static unsigned char buf[4096];

int
main(int argc, char **argv)
{
Expand All @@ -101,6 +103,8 @@ main(int argc, char **argv)
int quiet = 0, ipv4 = 1, ipv6 = 1;
struct sockaddr_in sin;
struct sockaddr_in6 sin6;
struct sockaddr_storage from;
socklen_t fromlen;

memset(&sin, 0, sizeof(sin));
sin.sin_family = AF_INET;
Expand Down Expand Up @@ -338,7 +342,25 @@ main(int argc, char **argv)
if(exiting)
break;

rc = dht_periodic(rc > 0, &tosleep, callback, NULL);
if(rc > 0) {
fromlen = sizeof(from);
if(FD_ISSET(s, &readfds))
rc = recvfrom(s, buf, sizeof(buf) - 1, 0,
(struct sockaddr*)&from, &fromlen);
else if(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(errno == EINTR) {
continue;
Expand Down
52 changes: 15 additions & 37 deletions dht.c
Original file line number Diff line number Diff line change
Expand Up @@ -1832,46 +1832,27 @@ bucket_maintenance(int af)
}

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)
{
int i;

gettimeofday(&now, NULL);

if(available) {
int rc, message;
if(buflen > 0) {
int message;
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 nodes_len = 256, nodes6_len = 1024;
unsigned short port;
unsigned char values[2048], values6[2048];
int values_len = 2048, values6_len = 2048;
int want, want4, want6;
struct sockaddr_storage from_storage;
struct sockaddr *from = (struct sockaddr*)&from_storage;
socklen_t fromlen = sizeof(from_storage);
unsigned short ttid;

rc = -1;
if(dht_socket >= 0) {
rc = recvfrom(dht_socket, buf, 1536, 0, from, &fromlen);
if(rc < 0 && errno != EAGAIN) {
return rc;
}
}
if(dht_socket6 >= 0 && rc < 0) {
rc = recvfrom(dht_socket6, buf, 1536, 0,
from, &fromlen);
if(rc < 0 && errno != EAGAIN) {
return rc;
}
}

if(rc < 0 || fromlen > sizeof(struct sockaddr_storage))
goto dontread;

if(is_martian(from))
goto dontread;

Expand All @@ -1882,26 +1863,23 @@ dht_periodic(int available, time_t *tosleep,
}
}

/* There's a bug in parse_message -- it will happily overflow the
buffer if it's not NUL-terminated. For now, put a NUL at the
end of buffers. */
/* See parse_message. */

if(rc < 1536) {
buf[rc] = '\0';
} else {
debugf("Overlong message.\n");
goto dontread;
if(((char*)buf)[buflen] != '\0') {
debugf("Unterminated message.\n");
errno = EINVAL;
return -1;
}

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,
nodes, &nodes_len, nodes6, &nodes6_len,
values, &values_len, values6, &values6_len,
&want);

if(message < 0 || message == ERROR || id_cmp(id, zeroes) == 0) {
debugf("Unparseable message: ");
debug_printable(buf, rc);
debug_printable(buf, buflen);
debugf("\n");
goto dontread;
}
Expand Down Expand Up @@ -1931,7 +1909,7 @@ dht_periodic(int available, time_t *tosleep,
case REPLY:
if(tid_len != 4) {
debugf("Broken node truncates transaction ids: ");
debug_printable(buf, rc);
debug_printable(buf, buflen);
debugf("\n");
/* This is really annoying, as it means that we will
time-out all our searches that go through this node.
Expand Down Expand Up @@ -2041,7 +2019,7 @@ dht_periodic(int available, time_t *tosleep,
}
} else {
debugf("Unexpected reply: ");
debug_printable(buf, rc);
debug_printable(buf, buflen);
debugf("\n");
}
break;
Expand Down
5 changes: 3 additions & 2 deletions dht.h
Original file line number Diff line number Diff line change
Expand Up @@ -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_insert_node(const unsigned char *id, struct sockaddr *sa, int salen);
int dht_ping_node(struct sockaddr *sa, int salen);
int dht_periodic(int available, time_t *tosleep,
dht_callback *callback, void *closure);
int dht_periodic(const void *buf, size_t buflen,
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,
dht_callback *callback, void *closure);
int dht_nodes(int af,
Expand Down

0 comments on commit de3705c

Please sign in to comment.