ServerName *server_name_free(ServerName *n) { if (!n) return NULL; server_name_flush_addresses(n); if (n->manager) { if (n->type == SERVER_SYSTEM) LIST_REMOVE(names, n->manager->system_servers, n); else if (n->type == SERVER_LINK) LIST_REMOVE(names, n->manager->link_servers, n); else if (n->type == SERVER_FALLBACK) LIST_REMOVE(names, n->manager->fallback_servers, n); else assert_not_reached("Unknown server type"); if (n->manager->current_server_name == n) manager_set_server_name(n->manager, NULL); } log_debug("Removed server %s.", n->string); free(n->string); return mfree(n); }
int server_name_new( Manager *m, ServerName **ret, ServerType type, const char *string) { ServerName *n, *tail; assert(m); assert(string); n = new0(ServerName, 1); if (!n) return -ENOMEM; n->type = type; n->string = strdup(string); if (!n->string) { free(n); return -ENOMEM; } if (type == SERVER_SYSTEM) { LIST_FIND_TAIL(names, m->system_servers, tail); LIST_INSERT_AFTER(names, m->system_servers, tail, n); } else if (type == SERVER_LINK) { LIST_FIND_TAIL(names, m->link_servers, tail); LIST_INSERT_AFTER(names, m->link_servers, tail, n); } else if (type == SERVER_FALLBACK) { LIST_FIND_TAIL(names, m->fallback_servers, tail); LIST_INSERT_AFTER(names, m->fallback_servers, tail, n); } else assert_not_reached("Unknown server type"); n->manager = m; if (type != SERVER_FALLBACK && m->current_server_name && m->current_server_name->type == SERVER_FALLBACK) manager_set_server_name(m, NULL); log_debug("Added new server %s.", string); if (ret) *ret = n; return 0; }
int manager_connect(Manager *m) { int r; assert(m); manager_disconnect(m); m->event_retry = sd_event_source_unref(m->event_retry); if (!ratelimit_test(&m->ratelimit)) { log_debug("Slowing down attempts to contact servers."); r = sd_event_add_time(m->event, &m->event_retry, clock_boottime_or_monotonic(), now(clock_boottime_or_monotonic()) + RETRY_USEC, 0, manager_retry_connect, m); if (r < 0) { log_error("Failed to create retry timer: %s", strerror(-r)); return r; } return 0; } /* If we already are operating on some address, switch to the * next one. */ if (m->current_server_address && m->current_server_address->addresses_next) manager_set_server_address(m, m->current_server_address->addresses_next); else { struct addrinfo hints = { .ai_flags = AI_NUMERICSERV|AI_ADDRCONFIG, .ai_socktype = SOCK_DGRAM, }; /* Hmm, we are through all addresses, let's look for the next host instead */ if (m->current_server_name && m->current_server_name->names_next) manager_set_server_name(m, m->current_server_name->names_next); else { ServerName *f; /* Our current server name list is exhausted, * let's find the next one to iterate. First * we try the system list, then the link list. * After having processed the link list we * jump back to the system list. However, if * both lists are empty, we change to the * fallback list. */ if (!m->current_server_name || m->current_server_name->type == SERVER_LINK) { f = m->system_servers; if (!f) f = m->link_servers; } else { f = m->link_servers; if (!f) f = m->system_servers; } if (!f) f = m->fallback_servers; if (!f) { manager_set_server_name(m, NULL); log_debug("No server found."); return 0; } manager_set_server_name(m, f); } /* Tell the resolver to reread /etc/resolv.conf, in * case it changed. */ res_init(); /* Flush out any previously resolved addresses */ server_name_flush_addresses(m->current_server_name); log_debug("Resolving %s...", m->current_server_name->string); r = sd_resolve_getaddrinfo(m->resolve, &m->resolve_query, m->current_server_name->string, "123", &hints, manager_resolve_handler, m); if (r < 0) { log_error("Failed to create resolver: %s", strerror(-r)); return r; } return 1; } r = manager_begin(m); if (r < 0) return r; return 1; } void manager_disconnect(Manager *m) { assert(m); m->resolve_query = sd_resolve_query_unref(m->resolve_query); m->event_timer = sd_event_source_unref(m->event_timer); m->event_receive = sd_event_source_unref(m->event_receive); m->server_socket = safe_close(m->server_socket); m->event_clock_watch = sd_event_source_unref(m->event_clock_watch); m->clock_watch_fd = safe_close(m->clock_watch_fd); m->event_timeout = sd_event_source_unref(m->event_timeout); sd_notifyf(false, "STATUS=Idle."); }