host.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456
  1. // SPDX-License-Identifier: GPL-2.0-or-later
  2. /*
  3. * Copyright (C) 2022 Felix Fietkau <nbd@nbd.name>
  4. */
  5. #include <libubox/avl-cmp.h>
  6. #include <libubox/blobmsg_json.h>
  7. #include "unetd.h"
  8. static LIST_HEAD(old_hosts);
  9. static struct blob_buf b;
  10. static int avl_key_cmp(const void *k1, const void *k2, void *ptr)
  11. {
  12. return memcmp(k1, k2, CURVE25519_KEY_SIZE);
  13. }
  14. static bool
  15. network_peer_equal(struct network_peer *p1, struct network_peer *p2)
  16. {
  17. return !memcmp(&p1->local_addr, &p2->local_addr, sizeof(p1->local_addr)) &&
  18. blob_attr_equal(p1->ipaddr, p2->ipaddr) &&
  19. blob_attr_equal(p1->subnet, p2->subnet) &&
  20. p1->port == p2->port;
  21. }
  22. static void
  23. network_peer_update(struct vlist_tree *tree,
  24. struct vlist_node *node_new,
  25. struct vlist_node *node_old)
  26. {
  27. struct network *net = container_of(tree, struct network, peers);
  28. struct network_peer *h_new = container_of_safe(node_new, struct network_peer, node);
  29. struct network_peer *h_old = container_of_safe(node_old, struct network_peer, node);
  30. int ret;
  31. if (h_new && h_old) {
  32. memcpy(&h_new->state, &h_old->state, sizeof(h_new->state));
  33. if (network_peer_equal(h_new, h_old))
  34. return;
  35. }
  36. if ((h_new ? h_new : h_old)->indirect)
  37. return;
  38. if (h_new)
  39. ret = wg_peer_update(net, h_new, h_old ? WG_PEER_UPDATE : WG_PEER_CREATE);
  40. else
  41. ret = wg_peer_update(net, h_old, WG_PEER_DELETE);
  42. if (ret)
  43. fprintf(stderr, "Failed to %s peer on network %s: %s\n",
  44. h_new ? "update" : "delete", network_name(net),
  45. strerror(-ret));
  46. }
  47. static struct network_group *
  48. network_group_get(struct network *net, const char *name)
  49. {
  50. struct network_group *group;
  51. char *name_buf;
  52. group = avl_find_element(&net->groups, name, group, node);
  53. if (group)
  54. return group;
  55. group = calloc_a(sizeof(*group), &name_buf, strlen(name) + 1);
  56. group->node.key = strcpy(name_buf, name);
  57. avl_insert(&net->groups, &group->node);
  58. return group;
  59. }
  60. static void
  61. network_host_add_group(struct network *net, struct network_host *host,
  62. const char *name)
  63. {
  64. struct network_group *group;
  65. int i;
  66. group = network_group_get(net, name);
  67. for (i = 0; i < group->n_members; i++)
  68. if (group->members[i] == host)
  69. return;
  70. group->n_members++;
  71. group->members = realloc(group->members, group->n_members * sizeof(*group->members));
  72. group->members[group->n_members - 1] = host;
  73. }
  74. enum {
  75. NETWORK_HOST_KEY,
  76. NETWORK_HOST_GROUPS,
  77. NETWORK_HOST_IPADDR,
  78. NETWORK_HOST_SUBNET,
  79. NETWORK_HOST_PORT,
  80. NETWORK_HOST_PEX_PORT,
  81. NETWORK_HOST_ENDPOINT,
  82. NETWORK_HOST_GATEWAY,
  83. __NETWORK_HOST_MAX
  84. };
  85. static const struct blobmsg_policy host_policy[__NETWORK_HOST_MAX] = {
  86. [NETWORK_HOST_KEY] = { "key", BLOBMSG_TYPE_STRING },
  87. [NETWORK_HOST_GROUPS] = { "groups", BLOBMSG_TYPE_ARRAY },
  88. [NETWORK_HOST_IPADDR] = { "ipaddr", BLOBMSG_TYPE_ARRAY },
  89. [NETWORK_HOST_SUBNET] = { "subnet", BLOBMSG_TYPE_ARRAY },
  90. [NETWORK_HOST_PORT] = { "port", BLOBMSG_TYPE_INT32 },
  91. [NETWORK_HOST_PEX_PORT] = { "peer-exchange-port", BLOBMSG_TYPE_INT32 },
  92. [NETWORK_HOST_ENDPOINT] = { "endpoint", BLOBMSG_TYPE_STRING },
  93. [NETWORK_HOST_GATEWAY] = { "gateway", BLOBMSG_TYPE_STRING },
  94. };
  95. static void
  96. network_host_create(struct network *net, struct blob_attr *attr, bool dynamic)
  97. {
  98. struct blob_attr *tb[__NETWORK_HOST_MAX];
  99. struct blob_attr *cur, *ipaddr, *subnet;
  100. uint8_t key[CURVE25519_KEY_SIZE];
  101. struct network_host *host = NULL;
  102. struct network_peer *peer;
  103. int ipaddr_len, subnet_len;
  104. const char *endpoint, *gateway;
  105. char *endpoint_buf, *gateway_buf;
  106. int rem;
  107. blobmsg_parse(host_policy, __NETWORK_HOST_MAX, tb, blobmsg_data(attr), blobmsg_len(attr));
  108. if (!tb[NETWORK_HOST_KEY])
  109. return;
  110. ipaddr_len = tb[NETWORK_HOST_IPADDR] ? blob_pad_len(tb[NETWORK_HOST_IPADDR]) : 0;
  111. if (ipaddr_len &&
  112. blobmsg_check_array(tb[NETWORK_HOST_IPADDR], BLOBMSG_TYPE_STRING) < 0)
  113. ipaddr_len = 0;
  114. subnet_len = tb[NETWORK_HOST_SUBNET] ? blob_pad_len(tb[NETWORK_HOST_SUBNET]) : 0;
  115. if (subnet_len &&
  116. blobmsg_check_array(tb[NETWORK_HOST_SUBNET], BLOBMSG_TYPE_STRING) < 0)
  117. subnet_len = 0;
  118. if ((cur = tb[NETWORK_HOST_ENDPOINT]) != NULL)
  119. endpoint = blobmsg_get_string(cur);
  120. else
  121. endpoint = NULL;
  122. if (!dynamic && (cur = tb[NETWORK_HOST_GATEWAY]) != NULL)
  123. gateway = blobmsg_get_string(cur);
  124. else
  125. gateway = NULL;
  126. if (b64_decode(blobmsg_get_string(tb[NETWORK_HOST_KEY]), key,
  127. sizeof(key)) != sizeof(key))
  128. return;
  129. if (dynamic) {
  130. struct network_dynamic_peer *dyn_peer;
  131. /* don't override/alter hosts configured via network data */
  132. peer = vlist_find(&net->peers, key, peer, node);
  133. if (peer && !peer->dynamic &&
  134. peer->node.version == net->peers.version)
  135. return;
  136. dyn_peer = calloc_a(sizeof(*dyn_peer),
  137. &ipaddr, ipaddr_len,
  138. &subnet, subnet_len,
  139. &endpoint_buf, endpoint ? strlen(endpoint) + 1 : 0);
  140. list_add_tail(&dyn_peer->list, &net->dynamic_peers);
  141. peer = &dyn_peer->peer;
  142. } else {
  143. const char *name;
  144. char *name_buf;
  145. name = blobmsg_name(attr);
  146. host = avl_find_element(&net->hosts, name, host, node);
  147. if (host)
  148. return;
  149. host = calloc_a(sizeof(*host),
  150. &name_buf, strlen(name) + 1,
  151. &ipaddr, ipaddr_len,
  152. &subnet, subnet_len,
  153. &endpoint_buf, endpoint ? strlen(endpoint) + 1 : 0,
  154. &gateway_buf, gateway ? strlen(gateway) + 1 : 0);
  155. host->node.key = strcpy(name_buf, name);
  156. peer = &host->peer;
  157. }
  158. peer->dynamic = dynamic;
  159. if ((cur = tb[NETWORK_HOST_IPADDR]) != NULL && ipaddr_len)
  160. peer->ipaddr = memcpy(ipaddr, cur, ipaddr_len);
  161. if ((cur = tb[NETWORK_HOST_SUBNET]) != NULL && subnet_len)
  162. peer->subnet = memcpy(subnet, cur, subnet_len);
  163. if ((cur = tb[NETWORK_HOST_PORT]) != NULL)
  164. peer->port = blobmsg_get_u32(cur);
  165. else
  166. peer->port = net->net_config.port;
  167. if ((cur = tb[NETWORK_HOST_PEX_PORT]) != NULL)
  168. peer->pex_port = blobmsg_get_u32(cur);
  169. else
  170. peer->pex_port = net->net_config.pex_port;
  171. if (endpoint)
  172. peer->endpoint = strcpy(endpoint_buf, endpoint);
  173. memcpy(peer->key, key, sizeof(key));
  174. memcpy(&peer->local_addr.network_id,
  175. &net->net_config.addr.network_id,
  176. sizeof(peer->local_addr.network_id));
  177. network_fill_host_addr(&peer->local_addr, peer->key);
  178. if (!host)
  179. return;
  180. if (gateway)
  181. host->gateway = strcpy(gateway_buf, gateway);
  182. blobmsg_for_each_attr(cur, tb[NETWORK_HOST_GROUPS], rem) {
  183. if (!blobmsg_check_attr(cur, false) ||
  184. blobmsg_type(cur) != BLOBMSG_TYPE_STRING)
  185. continue;
  186. network_host_add_group(net, host, blobmsg_get_string(cur));
  187. }
  188. avl_insert(&net->hosts, &host->node);
  189. if (!memcmp(peer->key, net->config.pubkey, sizeof(key))) {
  190. if (!net->prev_local_host ||
  191. !network_peer_equal(&net->prev_local_host->peer, &host->peer))
  192. net->net_config.local_host_changed = true;
  193. net->net_config.local_host = host;
  194. }
  195. }
  196. static void
  197. network_hosts_load_dynamic_file(struct network *net, const char *file)
  198. {
  199. struct blob_attr *cur;
  200. int rem;
  201. blob_buf_init(&b, 0);
  202. if (!blobmsg_add_json_from_file(&b, file))
  203. return;
  204. blob_for_each_attr(cur, b.head, rem)
  205. network_host_create(net, cur, true);
  206. }
  207. static void
  208. network_hosts_load_dynamic_peers(struct network *net)
  209. {
  210. struct network_dynamic_peer *dyn;
  211. struct blob_attr *cur;
  212. int rem;
  213. if (!net->config.peer_data)
  214. return;
  215. blobmsg_for_each_attr(cur, net->config.peer_data, rem)
  216. network_hosts_load_dynamic_file(net, blobmsg_get_string(cur));
  217. blob_buf_free(&b);
  218. list_for_each_entry(dyn, &net->dynamic_peers, list)
  219. vlist_add(&net->peers, &dyn->peer.node, &dyn->peer.key);
  220. }
  221. static void
  222. network_host_free_dynamic_peers(struct list_head *list)
  223. {
  224. struct network_dynamic_peer *dyn, *dyn_tmp;
  225. list_for_each_entry_safe(dyn, dyn_tmp, list, list) {
  226. list_del(&dyn->list);
  227. free(dyn);
  228. }
  229. }
  230. void network_hosts_reload_dynamic_peers(struct network *net)
  231. {
  232. struct network_peer *peer;
  233. LIST_HEAD(old_entries);
  234. if (!net->config.peer_data)
  235. return;
  236. list_splice_init(&net->dynamic_peers, &old_entries);
  237. vlist_for_each_element(&net->peers, peer, node)
  238. if (peer->dynamic)
  239. peer->node.version = net->peers.version - 1;
  240. network_hosts_load_dynamic_peers(net);
  241. vlist_flush(&net->peers);
  242. network_host_free_dynamic_peers(&old_entries);
  243. }
  244. void network_hosts_update_start(struct network *net)
  245. {
  246. struct network_host *host, *htmp;
  247. struct network_group *group, *gtmp;
  248. avl_remove_all_elements(&net->hosts, host, node, htmp)
  249. list_add_tail(&host->node.list, &old_hosts);
  250. avl_remove_all_elements(&net->groups, group, node, gtmp) {
  251. free(group->members);
  252. free(group);
  253. }
  254. vlist_update(&net->peers);
  255. }
  256. static void
  257. __network_hosts_update_done(struct network *net, bool free_net)
  258. {
  259. struct network_host *local, *host, *tmp;
  260. LIST_HEAD(old_dynamic);
  261. const char *local_name;
  262. list_splice_init(&net->dynamic_peers, &old_dynamic);
  263. if (free_net)
  264. goto out;
  265. local = net->net_config.local_host;
  266. if (!local)
  267. goto out;
  268. local_name = network_host_name(local);
  269. if (net->net_config.local_host_changed)
  270. wg_init_local(net, &local->peer);
  271. avl_for_each_element(&net->hosts, host, node) {
  272. if (host == local)
  273. continue;
  274. host->peer.indirect = false;
  275. if (host->gateway && strcmp(host->gateway, local_name) != 0)
  276. host->peer.indirect = true;
  277. if (local->gateway && strcmp(local->gateway, network_host_name(host)) != 0)
  278. host->peer.indirect = true;
  279. vlist_add(&net->peers, &host->peer.node, host->peer.key);
  280. }
  281. network_hosts_load_dynamic_peers(net);
  282. out:
  283. vlist_flush(&net->peers);
  284. network_host_free_dynamic_peers(&old_dynamic);
  285. list_for_each_entry_safe(host, tmp, &old_hosts, node.list) {
  286. list_del(&host->node.list);
  287. free(host);
  288. }
  289. }
  290. void network_hosts_update_done(struct network *net)
  291. {
  292. return __network_hosts_update_done(net, false);
  293. }
  294. static union network_endpoint *
  295. network_peer_next_endpoint(struct network_peer *peer)
  296. {
  297. union network_endpoint *ep;
  298. int i;
  299. for (i = 0; i < __ENDPOINT_TYPE_MAX; i++) {
  300. int cur = peer->state.next_endpoint_idx;
  301. if (++peer->state.next_endpoint_idx == __ENDPOINT_TYPE_MAX)
  302. peer->state.next_endpoint_idx = 0;
  303. ep = &peer->state.next_endpoint[cur];
  304. if (cur == ENDPOINT_TYPE_STATIC &&
  305. (!peer->endpoint ||
  306. network_get_endpoint(ep, AF_UNSPEC, peer->endpoint, peer->port,
  307. peer->state.connect_attempt++)))
  308. continue;
  309. if (!ep->sa.sa_family)
  310. continue;
  311. return ep;
  312. }
  313. return NULL;
  314. }
  315. static void
  316. network_hosts_connect_cb(struct uloop_timeout *t)
  317. {
  318. struct network *net = container_of(t, struct network, connect_timer);
  319. struct network_host *host;
  320. struct network_peer *peer;
  321. union network_endpoint *ep;
  322. avl_for_each_element(&net->hosts, host, node)
  323. host->peer.state.num_net_queries = 0;
  324. net->num_net_queries = 0;
  325. if (!net->net_config.keepalive || !net->net_config.local_host)
  326. return;
  327. wg_peer_refresh(net);
  328. vlist_for_each_element(&net->peers, peer, node) {
  329. if (peer->state.connected || peer->indirect)
  330. continue;
  331. ep = network_peer_next_endpoint(peer);
  332. if (!ep)
  333. continue;
  334. if (memcmp(ep, &peer->state.endpoint, sizeof(*ep)) != 0 &&
  335. !network_skip_endpoint_route(net, ep))
  336. unetd_ubus_netifd_add_route(net, ep);
  337. wg_peer_connect(net, peer, ep);
  338. }
  339. network_pex_event(net, NULL, PEX_EV_QUERY);
  340. uloop_timeout_set(t, 1000);
  341. }
  342. void network_hosts_add(struct network *net, struct blob_attr *hosts)
  343. {
  344. struct blob_attr *cur;
  345. int rem;
  346. blobmsg_for_each_attr(cur, hosts, rem)
  347. network_host_create(net, cur, false);
  348. }
  349. void network_hosts_init(struct network *net)
  350. {
  351. INIT_LIST_HEAD(&net->dynamic_peers);
  352. avl_init(&net->hosts, avl_strcmp, false, NULL);
  353. vlist_init(&net->peers, avl_key_cmp, network_peer_update);
  354. avl_init(&net->groups, avl_strcmp, false, NULL);
  355. net->connect_timer.cb = network_hosts_connect_cb;
  356. }
  357. void network_hosts_free(struct network *net)
  358. {
  359. uloop_timeout_cancel(&net->connect_timer);
  360. network_hosts_update_start(net);
  361. __network_hosts_update_done(net, true);
  362. }