1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
2
3 #include "alloc-util.h"
4 #include "string-table.h"
5 #include "timesyncd-server.h"
6
7 static const char * const server_type_table[_SERVER_TYPE_MAX] = {
8 [SERVER_SYSTEM] = "system",
9 [SERVER_FALLBACK] = "fallback",
10 [SERVER_LINK] = "link",
11 [SERVER_RUNTIME] = "runtime",
12 };
13
14 DEFINE_PRIVATE_STRING_TABLE_LOOKUP_TO_STRING(server_type, ServerType);
15
server_address_new(ServerName * n,ServerAddress ** ret,const union sockaddr_union * sockaddr,socklen_t socklen)16 int server_address_new(
17 ServerName *n,
18 ServerAddress **ret,
19 const union sockaddr_union *sockaddr,
20 socklen_t socklen) {
21
22 ServerAddress *a, *tail;
23
24 assert(n);
25 assert(sockaddr);
26 assert(socklen >= offsetof(struct sockaddr, sa_data));
27 assert(socklen <= sizeof(union sockaddr_union));
28
29 a = new(ServerAddress, 1);
30 if (!a)
31 return -ENOMEM;
32
33 *a = (ServerAddress) {
34 .name = n,
35 .socklen = socklen,
36 };
37
38 memcpy(&a->sockaddr, sockaddr, socklen);
39
40 LIST_FIND_TAIL(addresses, n->addresses, tail);
41 LIST_INSERT_AFTER(addresses, n->addresses, tail, a);
42
43 if (ret)
44 *ret = a;
45
46 return 0;
47 }
48
server_address_free(ServerAddress * a)49 ServerAddress* server_address_free(ServerAddress *a) {
50 if (!a)
51 return NULL;
52
53 if (a->name) {
54 LIST_REMOVE(addresses, a->name->addresses, a);
55
56 if (a->name->manager && a->name->manager->current_server_address == a)
57 manager_set_server_address(a->name->manager, NULL);
58 }
59
60 return mfree(a);
61 }
62
server_name_new(Manager * m,ServerName ** ret,ServerType type,const char * string)63 int server_name_new(
64 Manager *m,
65 ServerName **ret,
66 ServerType type,
67 const char *string) {
68
69 ServerName *n;
70
71 assert(m);
72 assert(string);
73
74 n = new(ServerName, 1);
75 if (!n)
76 return -ENOMEM;
77
78 *n = (ServerName) {
79 .manager = m,
80 .type = type,
81 .string = strdup(string),
82 };
83
84 if (!n->string) {
85 free(n);
86 return -ENOMEM;
87 }
88
89 switch (type) {
90 case SERVER_SYSTEM:
91 LIST_APPEND(names, m->system_servers, n);
92 break;
93 case SERVER_LINK:
94 LIST_APPEND(names, m->link_servers, n);
95 break;
96 case SERVER_FALLBACK:
97 LIST_APPEND(names, m->fallback_servers, n);
98 break;
99 case SERVER_RUNTIME:
100 LIST_APPEND(names, m->runtime_servers, n);
101 break;
102 default:
103 assert_not_reached();
104 }
105
106 if (type != SERVER_FALLBACK &&
107 m->current_server_name &&
108 m->current_server_name->type == SERVER_FALLBACK)
109 manager_set_server_name(m, NULL);
110
111 log_debug("Added new %s server %s.", server_type_to_string(type), string);
112
113 if (ret)
114 *ret = n;
115
116 return 0;
117 }
118
server_name_free(ServerName * n)119 ServerName *server_name_free(ServerName *n) {
120 if (!n)
121 return NULL;
122
123 server_name_flush_addresses(n);
124
125 if (n->manager) {
126 if (n->type == SERVER_SYSTEM)
127 LIST_REMOVE(names, n->manager->system_servers, n);
128 else if (n->type == SERVER_LINK)
129 LIST_REMOVE(names, n->manager->link_servers, n);
130 else if (n->type == SERVER_FALLBACK)
131 LIST_REMOVE(names, n->manager->fallback_servers, n);
132 else if (n->type == SERVER_RUNTIME)
133 LIST_REMOVE(names, n->manager->runtime_servers, n);
134 else
135 assert_not_reached();
136
137 if (n->manager->current_server_name == n)
138 manager_set_server_name(n->manager, NULL);
139 }
140
141 log_debug("Removed server %s.", n->string);
142
143 free(n->string);
144 return mfree(n);
145 }
146
server_name_flush_addresses(ServerName * n)147 void server_name_flush_addresses(ServerName *n) {
148 assert(n);
149
150 while (n->addresses)
151 server_address_free(n->addresses);
152 }
153