THE SOFTWARE.
*/
-#include <arpa/inet.h>
#include <errno.h>
#include <fcntl.h>
#include <netdb.h>
#include <netinet/in.h>
+#include <poll.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
-#include <sys/time.h>
-#include <sys/types.h>
#include <time.h>
#include <unistd.h>
-#define MAX(x, y) ((x) >= (y) ? (x) : (y))
#define MIN(x, y) ((x) <= (y) ? (x) : (y))
static int
struct node nodes[CIRCULAR_LIST_SIZE];
};
-struct circular_list v4_new, v6_new, v4_confirmed, v6_confirmed;
+static struct circular_list v4_new, v6_new, v4_confirmed, v6_confirmed;
#define MAX_TOKEN_BUCKET_TOKENS 40
static time_t token_bucket_time;
static int token_bucket_tokens;
-FILE *dht_debug = NULL;
+static FILE *dht_debug = NULL;
#ifdef __GNUC__
__attribute__((format(printf, 1, 2)))
return send_ping((struct sockaddr *)&ss, sslen, ttid, 4);
} else {
unsigned char id[20];
- int i;
- for (i = 0; i < 20; i++)
- id[i] = random() & 0xFF;
+ arc4random_buf(id, sizeof id);
make_tid(ttid, "fn", 0);
debugf("Sending find_node.\n");
return send_find_node((struct sockaddr *)&ss, sslen, ttid, 4, id, want);
if (argc < i + 1)
goto usage;
- const char *port = strdup(argv[i++]);
-
+ const char *ourPort = strdup(argv[i++]);
if (ipv4addr != NULL) {
- dht_socket = newSock(ipv4addr, port);
+ dht_socket = newSock(ipv4addr, ourPort);
}
if (ipv6addr != NULL) {
- dht_socket6 = newSock(ipv6addr, port);
+ dht_socket6 = newSock(ipv6addr, ourPort);
}
- int rc = 0;
- {
- int fd = open("/dev/urandom", O_RDONLY);
- if (fd < 0) {
- perror("open(random)");
- exit(1);
- }
-
- rc = read(fd, myid, 20);
- if (rc < 20) {
- perror("open(random)");
- exit(1);
- }
-
- unsigned int seed;
- rc = read(fd, &seed, sizeof(seed));
- srandom(seed);
-
- close(fd);
- }
+ arc4random_buf(myid, sizeof myid);
memcpy(my_v, "1:v4:JB\0\0", 9);
have_v = 1;
if (!quiet)
dht_debug = stdout;
+ int rc = 0;
unsigned char ttid[4];
while (i < argc) {
token_bucket_time = time(NULL);
token_bucket_tokens = MAX_TOKEN_BUCKET_TOKENS;
int send4 = 0;
+ struct pollfd fds[2];
+ fds[0].fd = dht_socket;
+ fds[0].events = POLLIN;
+ fds[1].fd = dht_socket6;
+ fds[1].events = POLLIN;
while (1) {
- struct timeval tv;
- fd_set readfds;
-
+ int tv_sec = 0;
if ((dht_socket >= 0 && list_elements(&v4_confirmed) <= 16) ||
(dht_socket6 >= 0 && list_elements(&v6_confirmed) <= 16))
- tv.tv_sec = 0;
+ tv_sec = 0;
else
- tv.tv_sec = random() % 30;
- tv.tv_usec = random() % 1000000;
-
- FD_ZERO(&readfds);
- if (dht_socket >= 0)
- FD_SET(dht_socket, &readfds);
- if (dht_socket6 >= 0)
- FD_SET(dht_socket6, &readfds);
+ tv_sec = random() % 30;
+ int tv_msec = random() % 1000;
if (dht_debug)
debugf(
list_elements(&v4_new),
list_elements(&v6_new));
- int rc = select(MAX(dht_socket, dht_socket6) + 1, &readfds, NULL, NULL, &tv);
-
+ rc = poll(fds, 2, tv_sec * 1000 + tv_msec);
if (rc < 0) {
- if (errno != EINTR) {
- perror("select");
- sleep(1);
- }
+ perror("poll");
+ sleep(1);
}
if (rc > 0) {
- int rc = 0;
int message;
unsigned char tid[16], id[20], info_hash[20], target[20];
unsigned char buf[1536], nodes[256], nodes6[1024], token[128];
struct sockaddr_storage source_storage;
struct sockaddr *source = (struct sockaddr *)&source_storage;
socklen_t sourcelen = sizeof(source_storage);
- if (dht_socket >= 0 && FD_ISSET(dht_socket, &readfds)) {
- rc = recvfrom(dht_socket, buf, 1536, 0, source, &sourcelen);
- } else if (dht_socket6 >= 0 && FD_ISSET(dht_socket6, &readfds)) {
- rc = recvfrom(dht_socket6, buf, 1536, 0, source, &sourcelen);
+ if (fds[0].revents != 0) {
+ if ((fds[0].revents & (POLLERR | POLLNVAL)) > 0) {
+ fprintf(stderr, "error in fds[0]");
+ rc = -1;
+ } else {
+ rc = recvfrom(dht_socket, buf, 1536, 0, source, &sourcelen);
+ }
+ } else if (fds[1].revents != 0) {
+ if ((fds[1].revents & (POLLERR | POLLNVAL)) > 0) {
+ fprintf(stderr, "error in fds[1]");
+ rc = -1;
+ } else {
+ rc = recvfrom(dht_socket6, buf, 1536, 0, source, &sourcelen);
+ }
}
if (rc < 0 || sourcelen > sizeof(struct sockaddr_storage))
}
}
- return 0;
-
usage:
fprintf(stderr, "dht-bootstrap [-q] [-4 ADDR4] [-6 ADDR6] port [node port...]\n");
exit(1);