@@ -79,10 +79,9 @@ int latency = 5;
7979jack_nframes_t kbps = 0 ;
8080int bitdepth = 0 ;
8181int mtu = 1400 ;
82- int reply_port = 0 ;
83- int bind_port = 0 ;
82+ int reply_port_num = 0 ;
8483int redundancy = 1 ;
85- jack_client_t * client ;
84+ jack_client_t * client = NULL ;
8685packet_cache * packcache = 0 ;
8786
8887int state_connected = 0 ;
@@ -96,13 +95,8 @@ int quit = 0;
9695
9796int outsockfd ;
9897int 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
107101int sync_state ;
108102jack_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-
499472void
500473printUsage ()
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