}
}
+static int
+newSock(const char *host, const char *port)
+{
+ struct addrinfo hints;
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_family = AF_UNSPEC;
+ hints.ai_socktype = SOCK_DGRAM;
+ struct addrinfo *res = NULL;
+ int err = getaddrinfo(host, port, &hints, &res);
+ if (err != 0) {
+ fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(err));
+ exit(1);
+ }
+ int sock = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
+ if (sock == -1) {
+ perror("socket");
+ exit(1);
+ }
+ if (bind(sock, res->ai_addr, res->ai_addrlen) != 0) {
+ perror("bind");
+ exit(1);
+ }
+ int rc = fcntl(sock, F_GETFL, 0);
+ if (rc < 0) {
+ perror("F_GETFL");
+ exit(1);
+ }
+ rc = fcntl(sock, F_SETFL, (rc | O_NONBLOCK));
+ if (rc < 0) {
+ perror("F_SETFL");
+ exit(1);
+ }
+ freeaddrinfo(res);
+ return sock;
+}
+
int
main(int argc, char **argv)
{
- int port = 6881, quiet = 0, ipv4 = 1, ipv6 = 1;
- int opt, rc, i, send4;
- unsigned char ttid[4];
+ errno = 0;
+ int quiet = 0;
+ char *ipv4addr = NULL;
+ char *ipv6addr = NULL;
+ int opt = 0;
while (1) {
- opt = getopt(argc, argv, "q46");
+ opt = getopt(argc, argv, "q4:6:");
if (opt < 0)
break;
quiet = 1;
break;
case '4':
- ipv6 = 0;
+ ipv4addr = strdup(optarg);
break;
case '6':
- ipv4 = 0;
+ ipv6addr = strdup(optarg);
break;
default:
goto usage;
}
}
- i = optind;
+ int i = optind;
if (argc < i + 1)
goto usage;
- port = atoi(argv[i++]);
- if (port <= 0 || port >= 0x10000)
- goto usage;
-
- if (ipv4) {
- dht_socket = socket(PF_INET, SOCK_DGRAM, 0);
- if (dht_socket < 0)
- perror("socket(IPv4)");
- }
+ const char *port = strdup(argv[i++]);
- if (ipv6) {
- dht_socket6 = socket(PF_INET6, SOCK_DGRAM, 0);
- if (dht_socket6 < 0)
- perror("socket(IPv6)");
+ if (ipv4addr != NULL) {
+ dht_socket = newSock(ipv4addr, port);
}
-
- if (dht_socket < 0 && dht_socket6 < 0) {
- fprintf(stderr, "Eek!\n");
- exit(1);
- }
-
- if (dht_socket >= 0) {
- struct sockaddr_in sin;
- int rc;
- memset(&sin, 0, sizeof(sin));
- sin.sin_family = AF_INET;
- sin.sin_port = htons(port);
- rc = bind(dht_socket, (struct sockaddr *)&sin, sizeof(sin));
- if (rc < 0) {
- perror("bind(IPv4)");
- exit(1);
- }
-
- rc = fcntl(dht_socket, F_GETFL, 0);
- if (rc < 0) {
- perror("F_GETFL");
- exit(1);
- }
-
- rc = fcntl(dht_socket, F_SETFL, (rc | O_NONBLOCK));
- if (rc < 0) {
- perror("F_SETFL");
- exit(1);
- }
- }
-
- if (dht_socket6 >= 0) {
- struct sockaddr_in6 sin6;
- int rc;
- int val = 1;
-
- rc = setsockopt(
- dht_socket6, IPPROTO_IPV6, IPV6_V6ONLY, (char *)&val, sizeof(val));
- if (rc < 0) {
- perror("setsockopt(IPV6_V6ONLY)");
- exit(1);
- }
-
- /* BEP-32 mandates that we should bind this socket to one of our
- global IPv6 addresses. In this program, this only happens if
- the user used the -b flag. */
-
- memset(&sin6, 0, sizeof(sin6));
- sin6.sin6_family = AF_INET6;
- sin6.sin6_port = htons(port);
- rc = bind(dht_socket6, (struct sockaddr *)&sin6, sizeof(sin6));
- if (rc < 0) {
- perror("bind(IPv6)");
- exit(1);
- }
-
- rc = fcntl(dht_socket6, F_GETFL, 0);
- if (rc < 0) {
- perror("F_GETFL");
- exit(1);
- }
-
- rc = fcntl(dht_socket6, F_SETFL, (rc | O_NONBLOCK));
- if (rc < 0) {
- perror("F_SETFL");
- exit(1);
- }
+ if (ipv6addr != NULL) {
+ dht_socket6 = newSock(ipv6addr, port);
}
+ int rc = 0;
{
- int fd;
- unsigned int seed;
-
- fd = open("/dev/urandom", O_RDONLY);
+ int fd = open("/dev/urandom", O_RDONLY);
if (fd < 0) {
perror("open(random)");
exit(1);
exit(1);
}
+ unsigned int seed;
rc = read(fd, &seed, sizeof(seed));
srandom(seed);
if (!quiet)
dht_debug = stdout;
+ unsigned char ttid[4];
+
while (i < argc) {
struct addrinfo hints, *info, *infop;
memset(&hints, 0, sizeof(hints));
token_bucket_time = time(NULL);
token_bucket_tokens = MAX_TOKEN_BUCKET_TOKENS;
+ int send4 = 0;
while (1) {
struct timeval tv;
fd_set readfds;
- int rc;
if ((dht_socket >= 0 && list_elements(&v4_confirmed) <= 16) ||
(dht_socket6 >= 0 && list_elements(&v6_confirmed) <= 16))
list_elements(&v4_new),
list_elements(&v6_new));
- rc = select(MAX(dht_socket, dht_socket6) + 1, &readfds, NULL, NULL, &tv);
+ int rc = select(MAX(dht_socket, dht_socket6) + 1, &readfds, NULL, NULL, &tv);
if (rc < 0) {
if (errno != EINTR) {
}
if (rc > 0) {
- int rc, message;
+ 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];
int tid_len = 16, token_len = 128;
return 0;
usage:
- fprintf(stderr, "dht-bootstrap [-q] [-4] [-6] port [node port...]\n");
+ fprintf(stderr, "dht-bootstrap [-q] [-4 ADDR4] [-6 ADDR6] port [node port...]\n");
exit(1);
}