diff --git a/tools/netsource.c b/tools/netsource.c index 401c403..628ca59 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; @@ -546,7 +541,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 +637,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 +797,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; }