From: Sergey Matveev Date: Wed, 9 Nov 2022 08:45:35 +0000 (+0300) Subject: Specify bind addresses explicitly X-Git-Url: http://www.git.stargrave.org/?p=dht-bootstrap.git;a=commitdiff_plain;h=5ce75cf1b18f93fc109bf860b7ad900f7a42542d Specify bind addresses explicitly --- diff --git a/CHANGES b/CHANGES index cc31242..3e58650 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,7 @@ +2022-11-09: + + * Ability to explicitly specify IP addresses to bind to + 20 November 2011: dht-bootstrap-0.2 * Fixed a bug that could cause EAFNOSUPPORT errors. diff --git a/dht-bootstrap.c b/dht-bootstrap.c index cd6c96e..de5bb39 100644 --- a/dht-bootstrap.c +++ b/dht-bootstrap.c @@ -366,17 +366,53 @@ send_request(struct circular_list *list, int dopop, int doping, int want) } } +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) { errno = 0; int quiet = 0; - int ipv4 = 1; - int ipv6 = 1; + 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; @@ -385,10 +421,10 @@ main(int argc, char **argv) quiet = 1; break; case '4': - ipv6 = 0; + ipv4addr = strdup(optarg); break; case '6': - ipv4 = 0; + ipv6addr = strdup(optarg); break; default: goto usage; @@ -400,88 +436,13 @@ main(int argc, char **argv) if (argc < i + 1) goto usage; - port = atoi(argv[i++]); - if (port <= 0 || port >= 0x10000) - goto usage; + const char *port = strdup(argv[i++]); - if (ipv4) { - dht_socket = socket(PF_INET, SOCK_DGRAM, 0); - if (dht_socket < 0) - perror("socket(IPv4)"); + if (ipv4addr != NULL) { + dht_socket = newSock(ipv4addr, port); } - - if (ipv6) { - dht_socket6 = socket(PF_INET6, SOCK_DGRAM, 0); - if (dht_socket6 < 0) - perror("socket(IPv6)"); - } - - 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; @@ -757,7 +718,7 @@ main(int argc, char **argv) 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); }