From 797f7528453766831585b81546422fa76969ff41 Mon Sep 17 00:00:00 2001 From: Nils Philippsen Date: Mon, 13 Nov 2023 23:46:41 +0100 Subject: [PATCH] =?UTF-8?q?Don=E2=80=99t=20use=20gethostbyname()?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use getaddrinfo() instead, which can do IPv6 and multiple addresses. Signed-off-by: Nils Philippsen --- tools/netsource.c | 129 ++++++++++++++++++++++++++++++---------------- 1 file changed, 86 insertions(+), 43 deletions(-) diff --git a/tools/netsource.c b/tools/netsource.c index 401c403..a14d7fc 100644 --- a/tools/netsource.c +++ b/tools/netsource.c @@ -82,7 +82,7 @@ int mtu = 1400; int reply_port = 0; int bind_port = 0; int redundancy = 1; -jack_client_t *client; +jack_client_t *client = NULL; packet_cache * packcache = 0; int state_connected = 0; @@ -96,13 +96,8 @@ int quit = 0; int outsockfd; int insockfd; -#ifdef WIN32 -struct sockaddr_in destaddr; -struct sockaddr_in bindaddr; -#else -struct sockaddr destaddr; -struct sockaddr bindaddr; -#endif +struct addrinfo *destaddr = NULL; +struct addrinfo *bindaddr; int sync_state; jack_transport_state_t last_transport_state; @@ -475,27 +470,6 @@ jack_shutdown (void *arg) exit (1); } -void -init_sockaddr_in (struct sockaddr_in *name , const char *hostname , uint16_t port) -{ - name->sin_family = AF_INET ; - name->sin_port = htons (port); - if (hostname) { - struct hostent *hostinfo = gethostbyname (hostname); - if (hostinfo == NULL) { - fprintf (stderr, "init_sockaddr_in: unknown host: %s.\n", hostname); - fflush( stderr ); - } -#ifdef WIN32 - name->sin_addr.s_addr = inet_addr( hostname ); -#else - name->sin_addr = *(struct in_addr *) hostinfo->h_addr ; -#endif - } else - name->sin_addr.s_addr = htonl (INADDR_ANY) ; - -} - void printUsage () { @@ -546,7 +520,8 @@ main (int argc, char *argv[]) /* Argument parsing stuff */ extern char *optarg; extern int optind, optopt; - int errflg = 0, c; + int errflg = 0, c, e, retval = 0; + struct addrinfo hints, *rp; if (argc < 3) { printUsage (); @@ -641,25 +616,85 @@ main (int argc, char *argv[]) capture_channels = capture_channels_audio + capture_channels_midi; playback_channels = playback_channels_audio + playback_channels_midi; - outsockfd = socket (AF_INET, SOCK_DGRAM, 0); - insockfd = socket (AF_INET, SOCK_DGRAM, 0); - if ((outsockfd == -1) || (insockfd == -1)) { fprintf (stderr, "can not open sockets\n" ); return 1; } - init_sockaddr_in ((struct sockaddr_in *) &destaddr, peer_ip, peer_port); + memset(&hints, '\0', sizeof(hints)); + hints.ai_socktype = SOCK_STREAM; + hints.ai_flags = AI_ADDRCONFIG; + + e = getaddrinfo (peer_ip, peer_port, &hints, &destaddr); + if (e) { + retval = 1; + fprintf (stderr, "getaddrinfo(\"%s\", \"%s\", ...) failed: %s\n", peer_ip, peer_port, gai_strerror (e)); + goto cleanup; + } + if (bind_port) { - init_sockaddr_in ((struct sockaddr_in *) &bindaddr, NULL, bind_port); - if( bind (outsockfd, &bindaddr, sizeof (bindaddr)) ) { - fprintf (stderr, "bind failure\n" ); + e = getaddrinfo (NULL, bind_port, &hints, &bindaddr); + if (e) { + retval = 1; + fprintf (stderr, "getaddrinfo(NULL, \"%s\", ...) failed: %s\n", peer_port, gai_strerror (e)); + goto cleanup; + } + + for (rp = bindaddr; rp != NULL; rp = rp->ai_next) { + outsockfd = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol); + + if (outsockfd == -1) { + fprintf (stderr, "Can't open socket: %s", gai_strerror(errno)); + continue; + } + + if (bind (outsockfd, rp->ai_addr, rp->ai_addrlen) == 0) { + break; + } + + close (outsockfd); + } + + freeaddrinfo (bindaddr); + + if (rp == NULL) { + /* No address succeeded */ + retval = 1; + fprintf (stderr, "bind failure: %s\n", gai_strerror (errno)); + goto cleanup; } } + if (reply_port) { - init_sockaddr_in ((struct sockaddr_in *) &bindaddr, NULL, reply_port); - if( bind (insockfd, &bindaddr, sizeof (bindaddr)) ) { - fprintf (stderr, "bind failure\n" ); + e = getaddrinfo (NULL, reply_port, &hints, &bindaddr); + if (e) { + retval = 1; + fprintf (stderr, "getaddrinfo(NULL, \"%s\", ...) failed: %s\n", peer_port, gai_strerror (e)); + goto cleanup; + } + + for (rp = bindaddr; rp != NULL; rp = rp->ai_next) { + insockfd = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol); + + if (outsockfd == -1) { + fprintf (stderr, "Can't open socket: %s", gai_strerror(errno)); + continue; + } + + if (bind (outsockfd, rp->ai_addr, rp->ai_addrlen) == 0) { + break; + } + + close (insockfd); + } + + freeaddrinfo (bindaddr); + + if (rp == NULL) { + /* No address succeeded */ + retval = 1; + fprintf (stderr, "bind failure: %s\n", gai_strerror (errno)); + goto cleanup; } } @@ -741,7 +776,15 @@ main (int argc, char *argv[]) } } - jack_client_close (client); - packet_cache_free (packcache); - exit (0); +cleanup: + if (destaddr) { + freeaddrinfo(destaddr); + } + if (client) { + jack_client_close (client); + } + if (packcache) { + packet_cache_free (packcache); + } + return retval; }