@@ -426,6 +426,9 @@ int manager_connect(Manager *m) {
426426
427427 assert (m );
428428
429+ if (m -> resolving )
430+ return 0 ;
431+
429432 manager_disconnect (m );
430433
431434 log_debug ("Connecting network ..." );
@@ -469,6 +472,8 @@ void manager_disconnect(Manager *m) {
469472
470473 log_debug ("Disconnecting network ..." );
471474
475+ m -> resolve_query = sd_resolve_query_unref (m -> resolve_query );
476+
472477 close_journal_input (m );
473478
474479 manager_close_network_socket (m );
@@ -481,6 +486,59 @@ void manager_disconnect(Manager *m) {
481486 sd_notifyf (false, "STATUS=Idle." );
482487}
483488
489+ int manager_resolve_handler (sd_resolve_query * q , int ret , const struct addrinfo * ai , void * userdata ) {
490+ Manager * m = userdata ;
491+
492+ assert (q );
493+ assert (m );
494+ assert (m -> server_name );
495+
496+ log_debug ("Resolve %s: %s" , m -> server_name , gai_strerror (ret ));
497+
498+ m -> resolve_query = sd_resolve_query_unref (m -> resolve_query );
499+
500+ if (ret != 0 ) {
501+ log_debug ("Failed to resolve %s: %s" , m -> server_name , gai_strerror (ret ));
502+
503+ /* Try next host */
504+ return manager_connect (m );
505+ }
506+
507+ for (; ai ; ai = ai -> ai_next ) {
508+ _cleanup_free_ char * pretty = NULL ;
509+
510+ assert (ai -> ai_addr );
511+ assert (ai -> ai_addrlen >= offsetof(struct sockaddr , sa_data ));
512+
513+ if (!IN_SET (ai -> ai_addr -> sa_family , AF_INET , AF_INET6 )) {
514+ log_warning ("Unsuitable address protocol for %s" , m -> server_name );
515+ continue ;
516+ }
517+
518+ m -> socklen = ai -> ai_addrlen ;
519+ memcpy (& m -> address .sockaddr , (const union sockaddr_union * ) ai -> ai_addr , ai -> ai_addrlen );
520+
521+ if (ai -> ai_addr -> sa_family == AF_INET6 )
522+ m -> address .sockaddr .in6 .sin6_port = htobe16 ((uint16_t ) m -> port );
523+ else
524+ m -> address .sockaddr .in .sin_port = htobe16 ((uint16_t ) m -> port );
525+
526+ sockaddr_pretty (& m -> address .sockaddr .sa , m -> socklen , true, true, & pretty );
527+ m -> resolving = false;
528+
529+ log_debug ("Resolved address %s for %s." , pretty , m -> server_name );
530+ }
531+
532+ if (!IN_SET (m -> address .sockaddr .sa .sa_family , AF_INET , AF_INET6 )) {
533+ log_error ("Failed to find suitable address for host %s." , m -> server_name );
534+
535+ /* Try next host */
536+ return manager_connect (m );
537+ }
538+
539+ return manager_connect (m );
540+ }
541+
484542static int manager_network_event_handler (sd_event_source * s , int fd , uint32_t revents , void * userdata ) {
485543 Manager * m = userdata ;
486544 bool connected , online ;
@@ -551,6 +609,8 @@ void manager_free(Manager *m) {
551609 free (m -> dir );
552610 free (m -> namespace );
553611
612+ sd_resolve_unref (m -> resolve );
613+
554614 sd_event_source_unref (m -> network_event_source );
555615 sd_network_monitor_unref (m -> network_monitor );
556616
@@ -586,7 +646,7 @@ int manager_new(const char *state_file, const char *cursor, Manager **ret) {
586646 },
587647 };
588648
589- socket_address_parse (& m -> address , "239.0.0.1:6000" );
649+ ( void ) socket_address_parse (& m -> address , "239.0.0.1:6000" );
590650
591651 if (!m -> state_file )
592652 return log_oom ();
@@ -607,6 +667,14 @@ int manager_new(const char *state_file, const char *cursor, Manager **ret) {
607667
608668 sd_event_set_watchdog (m -> event , true);
609669
670+ r = sd_resolve_default (& m -> resolve );
671+ if (r < 0 )
672+ return r ;
673+
674+ r = sd_resolve_attach_event (m -> resolve , m -> event , 0 );
675+ if (r < 0 )
676+ return r ;
677+
610678 r = manager_network_monitor_listen (m );
611679 if (r < 0 )
612680 return r ;
0 commit comments