X-Git-Url: http://www.git.stargrave.org/?a=blobdiff_plain;f=dht-bootstrap.c;h=e8c0b2c7bd87dc7bc40359e4f8223af248cf006c;hb=edafb8f875c64908ed78077330375e97869d2892;hp=e98cd6ea6bd5f2e4c9be46d714e6bf54bf56d851;hpb=1462580556aa27a98819e58f74264cd00d8cd5d6;p=dht-bootstrap.git diff --git a/dht-bootstrap.c b/dht-bootstrap.c index e98cd6e..e8c0b2c 100644 --- a/dht-bootstrap.c +++ b/dht-bootstrap.c @@ -20,6 +20,7 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +#include #include #include #include @@ -29,6 +30,7 @@ THE SOFTWARE. #include #include #include +#include #include #include #include @@ -131,24 +133,22 @@ struct circular_list { 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))) -#endif static void debugf(const char *format, ...) { + if (dht_debug == NULL) + return; va_list args; va_start(args, format); - if (dht_debug) - vfprintf(dht_debug, format, args); + vfprintf(dht_debug, format, args); va_end(args); fflush(dht_debug); } @@ -354,9 +354,7 @@ send_request(struct circular_list *list, int dopop, int doping, int want) 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); @@ -371,34 +369,35 @@ newSock(const char *host, const char *port) 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 rc = getaddrinfo(host, port, &hints, &res); + if (rc != 0) + err(EXIT_FAILURE, "getaddrinfo: %s\n", gai_strerror(rc)); 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); - } + if (sock == -1) + err(EXIT_FAILURE, "socket()"); + if (bind(sock, res->ai_addr, res->ai_addrlen) != 0) + err(EXIT_FAILURE, "bind()"); + rc = fcntl(sock, F_GETFL, 0); + if (rc < 0) + err(EXIT_FAILURE, "F_GETFL"); rc = fcntl(sock, F_SETFL, (rc | O_NONBLOCK)); - if (rc < 0) { - perror("F_SETFL"); - exit(1); - } + if (rc < 0) + err(EXIT_FAILURE, "F_SETFL"); freeaddrinfo(res); return sock; } +static void +rlimited(int res) +{ + struct rlimit r; + r.rlim_cur = 0; + r.rlim_max = 0; + if (setrlimit(res, &r) == -1) { + err(EXIT_FAILURE, "can not setrlimit()"); + } +} + int main(int argc, char **argv) { @@ -433,35 +432,15 @@ main(int argc, char **argv) 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; @@ -469,6 +448,7 @@ main(int argc, char **argv) if (!quiet) dht_debug = stdout; + int rc = 0; unsigned char ttid[4]; while (i < argc) { @@ -481,10 +461,8 @@ main(int argc, char **argv) else if (dht_socket6 < 0) hints.ai_family |= AF_INET; rc = getaddrinfo(argv[i], argv[i + 1], &hints, &info); - if (rc != 0) { - fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rc)); - exit(1); - } + if (rc != 0) + err(EXIT_FAILURE, "getaddrinfo: %s\n", gai_strerror(rc)); i++; if (i >= argc) @@ -511,6 +489,15 @@ main(int argc, char **argv) fds[1].fd = dht_socket6; fds[1].events = POLLIN; + close(STDIN_FILENO); + if (quiet) + close(STDOUT_FILENO); + rlimited(RLIMIT_NPROC); + rlimited(RLIMIT_FSIZE); +#if __FreeBSD__ + rlimited(RLIMIT_NOFILE); +#endif // __FreeBSD__ + while (1) { int tv_sec = 0; if ((dht_socket >= 0 && list_elements(&v4_confirmed) <= 16) || @@ -528,15 +515,13 @@ main(int argc, char **argv) list_elements(&v4_new), list_elements(&v6_new)); - int rc = poll(fds, 2, tv_sec * 1000 + tv_msec); - + rc = poll(fds, 2, tv_sec * 1000 + tv_msec); if (rc < 0) { 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]; @@ -562,7 +547,7 @@ main(int argc, char **argv) rc = -1; } else { rc = recvfrom(dht_socket6, buf, 1536, 0, source, &sourcelen); - }; + } } if (rc < 0 || sourcelen > sizeof(struct sockaddr_storage)) @@ -717,11 +702,9 @@ main(int argc, char **argv) } } - return 0; - usage: fprintf(stderr, "dht-bootstrap [-q] [-4 ADDR4] [-6 ADDR6] port [node port...]\n"); - exit(1); + exit(EXIT_FAILURE); } /* We could use a proper bencoding printer and parser, but the format of