+static int manager_resolve_handler(sd_resolve_query *q, int ret, const struct addrinfo *ai, void *userdata) {
+ Manager *m = userdata;
+ ServerAddress *a, *last = NULL;
+
+ assert(q);
+ assert(m);
+ assert(m->current_server_name);
+
+ m->resolve_query = sd_resolve_query_unref(m->resolve_query);
+
+ if (ret != 0) {
+ log_info("Failed to resolve %s: %s", m->current_server_name->string, gai_strerror(ret));
+
+ /* Try next host */
+ return manager_connect(m);
+ }
+
+ server_name_flush_addresses(m->current_server_name);
+
+ for (; ai; ai = ai->ai_next) {
+ _cleanup_free_ char *pretty = NULL;
+
+ assert(ai->ai_addr);
+ assert(ai->ai_addrlen >= offsetof(struct sockaddr, sa_data));
+ assert(ai->ai_addrlen <= sizeof(union sockaddr_union));
+
+ if (!IN_SET(ai->ai_addr->sa_family, AF_INET, AF_INET6)) {
+ log_warning("Unsuitable address protocol for %s", m->current_server_name->string);
+ continue;
+ }
+
+ a = new0(ServerAddress, 1);
+ if (!a)
+ return log_oom();
+
+ memcpy(&a->sockaddr, ai->ai_addr, ai->ai_addrlen);
+ a->socklen = ai->ai_addrlen;
+
+ LIST_INSERT_AFTER(addresses, m->current_server_name->addresses, last, a);
+ last = a;
+
+ sockaddr_pretty(&a->sockaddr.sa, a->socklen, true, &pretty);
+ log_debug("Resolved address %s for %s.", pretty, m->current_server_name->string);
+ }
+
+ if (!m->current_server_name->addresses) {
+ log_error("Failed to find suitable address for host %s.", m->current_server_name->string);
+
+ /* Try next host */
+ return manager_connect(m);
+ }
+
+ m->current_server_address = m->current_server_name->addresses;
+
+ return manager_begin(m);
+}
+
+static int manager_retry(sd_event_source *source, usec_t usec, void *userdata) {
+ Manager *m = userdata;
+
+ assert(m);
+
+ return manager_connect(m);
+}
+
+static int manager_connect(Manager *m) {
+
+ struct addrinfo hints = {
+ .ai_flags = AI_NUMERICSERV|AI_ADDRCONFIG,
+ .ai_socktype = SOCK_DGRAM,
+ };