Skip to content

Commit fa2ae54

Browse files
committed
Don’t use gethostbyname()
Use getaddrinfo() instead, which can do IPv6 and multiple addresses. Signed-off-by: Nils Philippsen <nils@tiptoe.de>
1 parent 7cf014d commit fa2ae54

1 file changed

Lines changed: 86 additions & 22 deletions

File tree

tools/netsource.c

Lines changed: 86 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ int mtu = 1400;
8282
int reply_port = 0;
8383
int bind_port = 0;
8484
int redundancy = 1;
85-
jack_client_t *client;
85+
jack_client_t *client = NULL;
8686
packet_cache * packcache = 0;
8787

8888
int state_connected = 0;
@@ -96,13 +96,8 @@ int quit = 0;
9696

9797
int outsockfd;
9898
int insockfd;
99-
#ifdef WIN32
100-
struct sockaddr_in destaddr;
101-
struct sockaddr_in bindaddr;
102-
#else
103-
struct sockaddr destaddr;
104-
struct sockaddr bindaddr;
105-
#endif
99+
struct addrinfo *destaddr = NULL;
100+
struct addrinfo *bindaddr;
106101

107102
int sync_state;
108103
jack_transport_state_t last_transport_state;
@@ -546,7 +541,8 @@ main (int argc, char *argv[])
546541
/* Argument parsing stuff */
547542
extern char *optarg;
548543
extern int optind, optopt;
549-
int errflg = 0, c;
544+
int errflg = 0, c, e, retval = 0;
545+
struct addrinfo hints, *rp;
550546

551547
if (argc < 3) {
552548
printUsage ();
@@ -641,25 +637,85 @@ main (int argc, char *argv[])
641637
capture_channels = capture_channels_audio + capture_channels_midi;
642638
playback_channels = playback_channels_audio + playback_channels_midi;
643639

644-
outsockfd = socket (AF_INET, SOCK_DGRAM, 0);
645-
insockfd = socket (AF_INET, SOCK_DGRAM, 0);
646-
647640
if ((outsockfd == -1) || (insockfd == -1)) {
648641
fprintf (stderr, "can not open sockets\n" );
649642
return 1;
650643
}
651644

652-
init_sockaddr_in ((struct sockaddr_in *) &destaddr, peer_ip, peer_port);
645+
memset(&hints, '\0', sizeof(hints));
646+
hints.ai_socktype = SOCK_STREAM;
647+
hints.ai_flags = AI_ADDRCONFIG;
648+
649+
e = getaddrinfo (peer_ip, peer_port, &hints, &destaddr);
650+
if (e) {
651+
retval = 1;
652+
fprintf (stderr, "getaddrinfo(\"%s\", \"%s\", ...) failed: %s\n", peer_ip, peer_port, gai_strerror (e));
653+
goto cleanup;
654+
}
655+
653656
if (bind_port) {
654-
init_sockaddr_in ((struct sockaddr_in *) &bindaddr, NULL, bind_port);
655-
if( bind (outsockfd, &bindaddr, sizeof (bindaddr)) ) {
656-
fprintf (stderr, "bind failure\n" );
657+
e = getaddrinfo (NULL, bind_port, &hints, &bindaddr);
658+
if (e) {
659+
retval = 1;
660+
fprintf (stderr, "getaddrinfo(NULL, \"%s\", ...) failed: %s\n", peer_port, gai_strerror (e));
661+
goto cleanup;
662+
}
663+
664+
for (rp = bindaddr; rp != NULL; rp = rp->ai_next) {
665+
outsockfd = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);
666+
667+
if (outsockfd == -1) {
668+
fprintf (stderr, "Can't open socket: %s", gai_strerror(errno));
669+
continue;
670+
}
671+
672+
if (bind (outsockfd, rp->ai_addr, rp->ai_addrlen) == 0) {
673+
break;
674+
}
675+
676+
close (outsockfd);
677+
}
678+
679+
freeaddrinfo (bindaddr);
680+
681+
if (rp == NULL) {
682+
/* No address succeeded */
683+
retval = 1;
684+
fprintf (stderr, "bind failure: %s\n", gai_strerror (errno));
685+
goto cleanup;
657686
}
658687
}
688+
659689
if (reply_port) {
660-
init_sockaddr_in ((struct sockaddr_in *) &bindaddr, NULL, reply_port);
661-
if( bind (insockfd, &bindaddr, sizeof (bindaddr)) ) {
662-
fprintf (stderr, "bind failure\n" );
690+
e = getaddrinfo (NULL, reply_port, &hints, &bindaddr);
691+
if (e) {
692+
retval = 1;
693+
fprintf (stderr, "getaddrinfo(NULL, \"%s\", ...) failed: %s\n", peer_port, gai_strerror (e));
694+
goto cleanup;
695+
}
696+
697+
for (rp = bindaddr; rp != NULL; rp = rp->ai_next) {
698+
insockfd = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);
699+
700+
if (outsockfd == -1) {
701+
fprintf (stderr, "Can't open socket: %s", gai_strerror(errno));
702+
continue;
703+
}
704+
705+
if (bind (outsockfd, rp->ai_addr, rp->ai_addrlen) == 0) {
706+
break;
707+
}
708+
709+
close (insockfd);
710+
}
711+
712+
freeaddrinfo (bindaddr);
713+
714+
if (rp == NULL) {
715+
/* No address succeeded */
716+
retval = 1;
717+
fprintf (stderr, "bind failure: %s\n", gai_strerror (errno));
718+
goto cleanup;
663719
}
664720
}
665721

@@ -741,7 +797,15 @@ main (int argc, char *argv[])
741797
}
742798
}
743799

744-
jack_client_close (client);
745-
packet_cache_free (packcache);
746-
exit (0);
800+
cleanup:
801+
if (destaddr) {
802+
freeaddrinfo(destaddr);
803+
}
804+
if (client) {
805+
jack_client_close (client);
806+
}
807+
if (packcache) {
808+
packet_cache_free (packcache);
809+
}
810+
return retval;
747811
}

0 commit comments

Comments
 (0)