Skip to content

Commit 3590353

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 3590353

File tree

1 file changed

+106
-54
lines changed

1 file changed

+106
-54
lines changed

tools/netsource.c

Lines changed: 106 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -79,10 +79,9 @@ int latency = 5;
7979
jack_nframes_t kbps = 0;
8080
int bitdepth = 0;
8181
int mtu = 1400;
82-
int reply_port = 0;
83-
int bind_port = 0;
82+
int reply_port_num = 0;
8483
int redundancy = 1;
85-
jack_client_t *client;
84+
jack_client_t *client = NULL;
8685
packet_cache * packcache = 0;
8786

8887
int state_connected = 0;
@@ -96,13 +95,8 @@ int quit = 0;
9695

9796
int outsockfd;
9897
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
98+
struct addrinfo *destaddr = NULL;
99+
struct addrinfo *bindaddr;
106100

107101
int sync_state;
108102
jack_transport_state_t last_transport_state;
@@ -296,7 +290,7 @@ process (jack_nframes_t nframes, void *arg)
296290
pkthdr_tx->transport_frame = local_trans_pos.frame;
297291
pkthdr_tx->framecnt = framecnt;
298292
pkthdr_tx->latency = latency;
299-
pkthdr_tx->reply_port = reply_port;
293+
pkthdr_tx->reply_port = reply_port_num;
300294
pkthdr_tx->sample_rate = jack_get_sample_rate (client);
301295
pkthdr_tx->period_size = nframes;
302296

@@ -316,7 +310,7 @@ process (jack_nframes_t nframes, void *arg)
316310
if (cont_miss < 3 * latency + 5) {
317311
int r;
318312
for( r = 0; r < redundancy; r++ )
319-
netjack_sendto (outsockfd, (char *) packet_buf_tx, tx_bufsize, 0, &destaddr, sizeof (destaddr), mtu);
313+
netjack_sendto (outsockfd, (char *) packet_buf_tx, tx_bufsize, 0, destaddr->ai_addr, sizeof (destaddr->ai_addr), mtu);
320314
} else if (cont_miss > 50 + 5 * latency) {
321315
state_connected = 0;
322316
packet_cache_reset_master_address( packcache );
@@ -331,7 +325,7 @@ process (jack_nframes_t nframes, void *arg)
331325
*/
332326

333327

334-
if( reply_port )
328+
if( reply_port_num )
335329
input_fd = insockfd;
336330
else
337331
input_fd = outsockfd;
@@ -429,7 +423,7 @@ process (jack_nframes_t nframes, void *arg)
429423
pkthdr_tx->transport_frame = local_trans_pos.frame;
430424
pkthdr_tx->framecnt = framecnt;
431425
pkthdr_tx->latency = latency;
432-
pkthdr_tx->reply_port = reply_port;
426+
pkthdr_tx->reply_port = reply_port_num;
433427
pkthdr_tx->sample_rate = jack_get_sample_rate (client);
434428
pkthdr_tx->period_size = nframes;
435429

@@ -449,7 +443,7 @@ process (jack_nframes_t nframes, void *arg)
449443
if (cont_miss < 3 * latency + 5) {
450444
int r;
451445
for( r = 0; r < redundancy; r++ )
452-
netjack_sendto (outsockfd, (char *) packet_buf_tx, tx_bufsize, 0, &destaddr, sizeof (destaddr), mtu);
446+
netjack_sendto (outsockfd, (char *) packet_buf_tx, tx_bufsize, 0, destaddr->ai_addr, sizeof (destaddr->ai_addr), mtu);
453447
} else if (cont_miss > 50 + 5 * latency) {
454448
state_connected = 0;
455449
packet_cache_reset_master_address( packcache );
@@ -475,27 +469,6 @@ jack_shutdown (void *arg)
475469
exit (1);
476470
}
477471

478-
void
479-
init_sockaddr_in (struct sockaddr_in *name , const char *hostname , uint16_t port)
480-
{
481-
name->sin_family = AF_INET ;
482-
name->sin_port = htons (port);
483-
if (hostname) {
484-
struct hostent *hostinfo = gethostbyname (hostname);
485-
if (hostinfo == NULL) {
486-
fprintf (stderr, "init_sockaddr_in: unknown host: %s.\n", hostname);
487-
fflush( stderr );
488-
}
489-
#ifdef WIN32
490-
name->sin_addr.s_addr = inet_addr( hostname );
491-
#else
492-
name->sin_addr = *(struct in_addr *) hostinfo->h_addr ;
493-
#endif
494-
} else
495-
name->sin_addr.s_addr = htonl (INADDR_ANY) ;
496-
497-
}
498-
499472
void
500473
printUsage ()
501474
{
@@ -532,7 +505,9 @@ main (int argc, char *argv[])
532505
{
533506
/* Some startup related basics */
534507
char *client_name, *server_name = NULL, *peer_ip;
535-
int peer_port = 3000;
508+
char *peer_port = NULL;
509+
char *reply_port = NULL;
510+
char *bind_port = NULL;
536511
jack_options_t options = JackNullOption;
537512
jack_status_t status;
538513
#ifdef WIN32
@@ -546,7 +521,8 @@ main (int argc, char *argv[])
546521
/* Argument parsing stuff */
547522
extern char *optarg;
548523
extern int optind, optopt;
549-
int errflg = 0, c;
524+
int errflg = 0, c, e, retval = 0;
525+
struct addrinfo hints, *rp;
550526

551527
if (argc < 3) {
552528
printUsage ();
@@ -585,13 +561,16 @@ main (int argc, char *argv[])
585561
latency = atoi (optarg);
586562
break;
587563
case 'p':
588-
peer_port = atoi (optarg);
564+
peer_port = malloc (strlen (optarg));
565+
strcpy (peer_port, optarg);
589566
break;
590567
case 'r':
591-
reply_port = atoi (optarg);
568+
reply_port = malloc (strlen (optarg));
569+
strcpy (reply_port, optarg);
592570
break;
593571
case 'B':
594-
bind_port = atoi (optarg);
572+
bind_port = malloc (strlen (optarg));
573+
strcpy (bind_port, optarg);
595574
break;
596575
case 'b':
597576
bitdepth = atoi (optarg);
@@ -641,25 +620,90 @@ main (int argc, char *argv[])
641620
capture_channels = capture_channels_audio + capture_channels_midi;
642621
playback_channels = playback_channels_audio + playback_channels_midi;
643622

644-
outsockfd = socket (AF_INET, SOCK_DGRAM, 0);
645-
insockfd = socket (AF_INET, SOCK_DGRAM, 0);
646-
647623
if ((outsockfd == -1) || (insockfd == -1)) {
648624
fprintf (stderr, "can not open sockets\n" );
649625
return 1;
650626
}
651627

652-
init_sockaddr_in ((struct sockaddr_in *) &destaddr, peer_ip, peer_port);
628+
memset(&hints, '\0', sizeof(hints));
629+
hints.ai_socktype = SOCK_STREAM;
630+
hints.ai_flags = AI_ADDRCONFIG;
631+
632+
e = getaddrinfo (peer_ip, peer_port, &hints, &destaddr);
633+
if (e) {
634+
retval = 1;
635+
fprintf (stderr, "getaddrinfo(\"%s\", \"%s\", ...) failed: %s\n", peer_ip, peer_port, gai_strerror (e));
636+
goto cleanup;
637+
}
638+
653639
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" );
640+
e = getaddrinfo (NULL, bind_port, &hints, &bindaddr);
641+
if (e) {
642+
retval = 1;
643+
fprintf (stderr, "getaddrinfo(NULL, \"%s\", ...) failed: %s\n", peer_port, gai_strerror (e));
644+
goto cleanup;
645+
}
646+
647+
for (rp = bindaddr; rp != NULL; rp = rp->ai_next) {
648+
outsockfd = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);
649+
650+
if (outsockfd == -1) {
651+
fprintf (stderr, "Can't open socket: %s", gai_strerror(errno));
652+
continue;
653+
}
654+
655+
if (bind (outsockfd, rp->ai_addr, rp->ai_addrlen) == 0) {
656+
break;
657+
}
658+
659+
close (outsockfd);
660+
}
661+
662+
freeaddrinfo (bindaddr);
663+
664+
if (rp == NULL) {
665+
/* No address succeeded */
666+
retval = 1;
667+
fprintf (stderr, "bind failure: %s\n", gai_strerror (errno));
668+
goto cleanup;
657669
}
658670
}
671+
659672
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" );
673+
e = getaddrinfo (NULL, reply_port, &hints, &bindaddr);
674+
if (e) {
675+
retval = 1;
676+
fprintf (stderr, "getaddrinfo(NULL, \"%s\", ...) failed: %s\n", peer_port, gai_strerror (e));
677+
goto cleanup;
678+
}
679+
680+
for (rp = bindaddr; rp != NULL; rp = rp->ai_next) {
681+
insockfd = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);
682+
683+
if (outsockfd == -1) {
684+
fprintf (stderr, "Can't open socket: %s", gai_strerror(errno));
685+
continue;
686+
}
687+
688+
if (bind (outsockfd, rp->ai_addr, rp->ai_addrlen) == 0) {
689+
if (rp->ai_addr->sa_family == AF_INET) {
690+
reply_port_num = ntohs (((struct sockaddr_in *) rp->ai_addr)->sin_port);
691+
} else if (rp->ai_addr->sa_family == AF_INET6) {
692+
reply_port_num = ntohs (((struct sockaddr_in6 *) rp->ai_addr)->sin6_port);
693+
}
694+
break;
695+
}
696+
697+
close (insockfd);
698+
}
699+
700+
freeaddrinfo (bindaddr);
701+
702+
if (rp == NULL) {
703+
/* No address succeeded */
704+
retval = 1;
705+
fprintf (stderr, "bind failure: %s\n", gai_strerror (errno));
706+
goto cleanup;
663707
}
664708
}
665709

@@ -741,7 +785,15 @@ main (int argc, char *argv[])
741785
}
742786
}
743787

744-
jack_client_close (client);
745-
packet_cache_free (packcache);
746-
exit (0);
788+
cleanup:
789+
if (destaddr) {
790+
freeaddrinfo(destaddr);
791+
}
792+
if (client) {
793+
jack_client_close (client);
794+
}
795+
if (packcache) {
796+
packet_cache_free (packcache);
797+
}
798+
return retval;
747799
}

0 commit comments

Comments
 (0)