X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Ftimesync%2Ftimesyncd-server.c;h=ec3fe1fc4e891b8e8ce958715c2fa1c57d83d5c7;hb=03e8fdb34610c498e8c7fbe0ae18b53fe28cfbd1;hp=e3cb1bf1f2eadda7ba8fe52ab320b505c2946c19;hpb=84e51726a38e133ca42d2f30f0668d3921b210cb;p=elogind.git diff --git a/src/timesync/timesyncd-server.c b/src/timesync/timesyncd-server.c index e3cb1bf1f..ec3fe1fc4 100644 --- a/src/timesync/timesyncd-server.c +++ b/src/timesync/timesyncd-server.c @@ -20,3 +20,132 @@ ***/ #include "timesyncd-server.h" + +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 = new0(ServerAddress, 1); + if (!a) + return -ENOMEM; + + memcpy(&a->sockaddr, sockaddr, socklen); + a->socklen = socklen; + + LIST_FIND_TAIL(addresses, n->addresses, tail); + LIST_INSERT_AFTER(addresses, n->addresses, tail, a); + a->name = n; + + 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); + } + + free(a); + return NULL; +} + +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; +} + +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); + free(n); + + return NULL; +} + +void server_name_flush_addresses(ServerName *n) { + assert(n); + + while (n->addresses) + server_address_free(n->addresses); +}