/* SPDX-License-Identifier: LGPL-2.1-or-later */ #include "alloc-util.h" #include "string-table.h" #include "timesyncd-server.h" static const char * const server_type_table[_SERVER_TYPE_MAX] = { [SERVER_SYSTEM] = "system", [SERVER_FALLBACK] = "fallback", [SERVER_LINK] = "link", [SERVER_RUNTIME] = "runtime", }; DEFINE_PRIVATE_STRING_TABLE_LOOKUP_TO_STRING(server_type, ServerType); int server_address_new( ServerName *n, ServerAddress **ret, const union sockaddr_union *sockaddr, socklen_t socklen) { ServerAddress *a, *tail; assert(n); assert(sockaddr); assert(socklen >= offsetof(struct sockaddr, sa_data)); assert(socklen <= sizeof(union sockaddr_union)); a = new(ServerAddress, 1); if (!a) return -ENOMEM; *a = (ServerAddress) { .name = n, .socklen = socklen, }; memcpy(&a->sockaddr, sockaddr, socklen); tail = LIST_FIND_TAIL(addresses, n->addresses); LIST_INSERT_AFTER(addresses, n->addresses, tail, a); if (ret) *ret = a; return 0; } ServerAddress* server_address_free(ServerAddress *a) { if (!a) return NULL; if (a->name) { LIST_REMOVE(addresses, a->name->addresses, a); if (a->name->manager && a->name->manager->current_server_address == a) manager_set_server_address(a->name->manager, NULL); } return mfree(a); } static int enable_ntp_server_defer_event(Manager *m, ServerType type) { int r; assert(m); assert((type >= 0) && (type < _SERVER_TYPE_MAX)); m->ntp_server_change_mask |= 1U << type; r = bus_manager_emit_ntp_server_changed(m); if (r < 0) return r; return 1; } int server_name_new( Manager *m, ServerName **ret, ServerType type, const char *string) { int r; ServerName *n; assert(m); assert(string); n = new(ServerName, 1); if (!n) return -ENOMEM; *n = (ServerName) { .manager = m, .type = type, .string = strdup(string), }; if (!n->string) { free(n); return -ENOMEM; } switch (type) { case SERVER_SYSTEM: LIST_APPEND(names, m->system_servers, n); break; case SERVER_LINK: LIST_APPEND(names, m->link_servers, n); break; case SERVER_FALLBACK: LIST_APPEND(names, m->fallback_servers, n); break; case SERVER_RUNTIME: LIST_APPEND(names, m->runtime_servers, n); break; default: assert_not_reached(); } r = enable_ntp_server_defer_event(m, type); if (r < 0) log_debug_errno(r, "Failed to enable ntp server defer event, ignoring: %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 %s server %s.", server_type_to_string(type), string); if (ret) *ret = n; return 0; } ServerName *server_name_free(ServerName *n) { int r; 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 if (n->type == SERVER_RUNTIME) LIST_REMOVE(names, n->manager->runtime_servers, n); else assert_not_reached(); r = enable_ntp_server_defer_event(n->manager, n->type); if (r < 0) log_debug_errno(r, "Failed to enable ntp server defer event, ignoring: %m"); 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); } void server_name_flush_addresses(ServerName *n) { assert(n); while (n->addresses) server_address_free(n->addresses); }