pex: after receiving data update req, notify peer of local address/port
[project/unetd.git] / pex.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3 * Copyright (C) 2022 Felix Fietkau <nbd@nbd.name>
4 */
5 #include <sys/types.h>
6 #include <sys/socket.h>
7 #include <arpa/inet.h>
8 #include <netinet/in.h>
9 #include <netinet/ip.h>
10 #include <netinet/ip6.h>
11 #include <netinet/udp.h>
12 #include <fcntl.h>
13 #include <stdlib.h>
14 #include <inttypes.h>
15 #include "unetd.h"
16 #include "pex-msg.h"
17
18 static const char *pex_peer_id_str(const uint8_t *key)
19 {
20 static char str[20];
21 int i;
22
23 for (i = 0; i < 8; i++)
24 sprintf(str + i * 2, "%02x", key[i]);
25
26 return str;
27 }
28
29 static struct pex_hdr *
30 pex_msg_init(struct network *net, uint8_t opcode)
31 {
32 return __pex_msg_init(net->config.pubkey, opcode);
33 }
34
35 static struct pex_hdr *
36 pex_msg_init_ext(struct network *net, uint8_t opcode, bool ext)
37 {
38 return __pex_msg_init_ext(net->config.pubkey, net->config.auth_key, opcode, ext);
39 }
40
41 static struct network_peer *
42 pex_msg_peer(struct network *net, const uint8_t *id)
43 {
44 struct network_peer *peer;
45 uint8_t key[WG_KEY_LEN] = {};
46
47 memcpy(key, id, PEX_ID_LEN);
48 peer = avl_find_ge_element(&net->peers.avl, key, peer, node.avl);
49 if (!peer || memcmp(peer->key, key, PEX_ID_LEN) != 0) {
50 D_NET(net, "can't find peer %s", pex_peer_id_str(id));
51 return NULL;
52 }
53
54 return peer;
55 }
56
57 static void
58 pex_get_peer_addr(struct sockaddr_in6 *sin6, struct network *net,
59 struct network_peer *peer)
60 {
61 *sin6 = (struct sockaddr_in6){
62 .sin6_family = AF_INET6,
63 .sin6_addr = peer->local_addr.in6,
64 .sin6_port = htons(peer->pex_port),
65 };
66 }
67
68 static void pex_msg_send(struct network *net, struct network_peer *peer)
69 {
70 struct sockaddr_in6 sin6 = {};
71
72 if (!peer || peer == &net->net_config.local_host->peer ||
73 !peer->pex_port)
74 return;
75
76 pex_get_peer_addr(&sin6, net, peer);
77 if (__pex_msg_send(net->pex.fd.fd, &sin6, NULL, 0) < 0)
78 D_PEER(net, peer, "pex_msg_send failed: %s", strerror(errno));
79 }
80
81 static void pex_msg_send_ext(struct network *net, struct network_peer *peer,
82 struct sockaddr_in6 *addr)
83 {
84 char addrbuf[INET6_ADDRSTRLEN];
85
86 if (!addr)
87 return pex_msg_send(net, peer);
88
89 if (__pex_msg_send(-1, addr, NULL, 0) < 0)
90 D_NET(net, "pex_msg_send_ext(%s) failed: %s",
91 inet_ntop(addr->sin6_family, (const void *)&addr->sin6_addr, addrbuf,
92 sizeof(addrbuf)),
93 strerror(errno));
94 }
95
96 static void
97 pex_send_hello(struct network *net, struct network_peer *peer)
98 {
99 struct pex_hello *data;
100
101 pex_msg_init(net, PEX_MSG_HELLO);
102 data = pex_msg_append(sizeof(*data));
103 if (peer->state.endpoint.sa.sa_family == AF_INET6)
104 data->flags |= htons(PEER_EP_F_IPV6);
105 if (network_get_local_addr(&data->local_addr, &peer->state.endpoint))
106 return;
107
108 pex_msg_send(net, peer);
109 }
110
111 static int
112 pex_msg_add_peer_endpoint(struct network *net, struct network_peer *peer,
113 struct network_peer *receiver)
114 {
115 struct pex_peer_endpoint *data;
116 uint16_t flags = 0;
117 const void *addr;
118 int port;
119 int len;
120
121 addr = network_endpoint_addr(&peer->state.endpoint, &len);
122 port = peer->state.endpoint.in.sin_port;
123 if (len > 4)
124 flags |= PEER_EP_F_IPV6;
125 if (network_endpoint_addr_equal(&peer->state.endpoint,
126 &receiver->state.endpoint)) {
127 if (!peer->state.has_local_ep_addr) {
128 D_PEER(net, peer, "can't send peer to %s, missing local address",
129 network_peer_name(receiver));
130 return -1;
131 }
132
133 addr = &peer->state.local_ep_addr;
134 port = htons(peer->port);
135 flags |= PEER_EP_F_LOCAL;
136 }
137
138 data = pex_msg_append(sizeof(*data));
139 if (!data)
140 return -1;
141
142 memcpy(data->peer_id, peer->key, sizeof(data->peer_id));
143 memcpy(data->addr, addr, len);
144 data->port = port;
145 data->flags = htons(flags);
146 D_PEER(net, peer, "send endpoint to %s", network_peer_name(receiver));
147
148 return 0;
149 }
150
151 static void
152 network_pex_handle_endpoint_change(struct network *net, struct network_peer *peer)
153 {
154 struct network_peer *cur;
155
156 vlist_for_each_element(&net->peers, cur, node) {
157 if (cur == peer || !cur->state.connected)
158 continue;
159
160 pex_msg_init(net, PEX_MSG_NOTIFY_PEERS);
161 if (pex_msg_add_peer_endpoint(net, peer, cur))
162 continue;
163
164 pex_msg_send(net, cur);
165 }
166 }
167
168 static void
169 network_pex_host_send_endpoint_notify(struct network *net, struct network_pex_host *host)
170 {
171 union {
172 struct {
173 struct ip ip;
174 struct udphdr udp;
175 } ipv4;
176 struct {
177 struct ip6_hdr ip;
178 struct udphdr udp;
179 } ipv6;
180 } packet = {};
181 struct udphdr *udp;
182 union network_endpoint dest_ep;
183 union network_addr local_addr = {};
184 int len;
185
186 pex_msg_init_ext(net, PEX_MSG_ENDPOINT_NOTIFY, true);
187
188 memcpy(&dest_ep, &host->endpoint, sizeof(dest_ep));
189
190 /* work around issue with local address lookup for local broadcast */
191 if (host->endpoint.sa.sa_family == AF_INET) {
192 uint8_t *data = (uint8_t *)&dest_ep.in.sin_addr;
193
194 if (data[3] == 0xff)
195 data[3] = 0xfe;
196 }
197 network_get_local_addr(&local_addr, &dest_ep);
198
199 memset(&dest_ep, 0, sizeof(dest_ep));
200 dest_ep.sa.sa_family = host->endpoint.sa.sa_family;
201 if (host->endpoint.sa.sa_family == AF_INET) {
202 packet.ipv4.ip = (struct ip){
203 .ip_hl = 5,
204 .ip_v = 4,
205 .ip_ttl = 64,
206 .ip_p = IPPROTO_UDP,
207 .ip_src = local_addr.in,
208 .ip_dst = host->endpoint.in.sin_addr,
209 };
210 dest_ep.in.sin_addr = host->endpoint.in.sin_addr;
211 udp = &packet.ipv4.udp;
212 len = sizeof(packet.ipv4);
213 } else {
214 packet.ipv6.ip = (struct ip6_hdr){
215 .ip6_flow = htonl(6 << 28),
216 .ip6_hops = 128,
217 .ip6_nxt = IPPROTO_UDP,
218 .ip6_src = local_addr.in6,
219 .ip6_dst = host->endpoint.in6.sin6_addr,
220 };
221 dest_ep.in6.sin6_addr = host->endpoint.in6.sin6_addr;
222 udp = &packet.ipv6.udp;
223 len = sizeof(packet.ipv6);
224 }
225
226 udp->uh_sport = htons(net->net_config.local_host->peer.port);
227 udp->uh_dport = host->endpoint.in6.sin6_port;
228
229 if (__pex_msg_send(-1, &dest_ep, &packet, len) < 0)
230 D_NET(net, "pex_msg_send_raw failed: %s", strerror(errno));
231 }
232
233
234 static void
235 network_pex_host_send_port_notify(struct network *net, struct network_pex_host *host)
236 {
237 struct pex_endpoint_port_notify *data;
238
239 if (!net->stun.port_ext)
240 return;
241
242 pex_msg_init_ext(net, PEX_MSG_ENDPOINT_PORT_NOTIFY, true);
243
244 data = pex_msg_append(sizeof(*data));
245 data->port = htons(net->stun.port_ext);
246
247 __pex_msg_send(-1, &host->endpoint, NULL, 0);
248 }
249
250 static void
251 network_pex_host_request_update(struct network *net, struct network_pex_host *host)
252 {
253 char addrstr[INET6_ADDRSTRLEN];
254 uint64_t version = 0;
255
256 host->last_ping = unet_gettime();
257
258 if (net->net_data_len)
259 version = net->net_data_version;
260
261 D("request network data from host %s",
262 inet_ntop(host->endpoint.sa.sa_family,
263 (host->endpoint.sa.sa_family == AF_INET6 ?
264 (const void *)&host->endpoint.in6.sin6_addr :
265 (const void *)&host->endpoint.in.sin_addr),
266 addrstr, sizeof(addrstr)));
267
268 if (!pex_msg_update_request_init(net->config.pubkey, net->config.key,
269 net->config.auth_key, &host->endpoint,
270 version, true))
271 return;
272
273 __pex_msg_send(-1, &host->endpoint, NULL, 0);
274
275 if (!net->net_config.local_host)
276 return;
277
278 network_pex_host_send_port_notify(net, host);
279 network_pex_host_send_endpoint_notify(net, host);
280 }
281
282 static void
283 network_pex_free_host(struct network *net, struct network_pex_host *host)
284 {
285 struct network_pex *pex = &net->pex;
286
287 pex->num_hosts--;
288 list_del(&host->list);
289 free(host);
290 }
291
292 static void
293 network_pex_request_update_cb(struct uloop_timeout *t)
294 {
295 struct network *net = container_of(t, struct network, pex.request_update_timer);
296 struct network_pex *pex = &net->pex;
297 struct network_pex_host *host, *tmp;
298 uint64_t now = unet_gettime();
299
300 uloop_timeout_set(t, 500);
301
302 if (list_empty(&pex->hosts))
303 return;
304
305 list_for_each_entry_safe(host, tmp, &pex->hosts, list) {
306 if (host->timeout && host->timeout < now) {
307 network_pex_free_host(net, host);
308 continue;
309 }
310
311 if (host->last_ping + 10 >= now)
312 continue;
313
314 list_move_tail(&host->list, &pex->hosts);
315 network_pex_host_request_update(net, host);
316 }
317 }
318
319 void network_pex_init(struct network *net)
320 {
321 struct network_pex *pex = &net->pex;
322
323 memset(pex, 0, sizeof(*pex));
324 pex->fd.fd = -1;
325 INIT_LIST_HEAD(&pex->hosts);
326 pex->request_update_timer.cb = network_pex_request_update_cb;
327 }
328
329 static void
330 network_pex_query_hosts(struct network *net)
331 {
332 struct network_host *host;
333 uint64_t now;
334 int rv = rand();
335 int hosts = 0;
336 int i;
337
338 pex_msg_init(net, PEX_MSG_QUERY);
339
340 avl_for_each_element(&net->hosts, host, node) {
341 struct network_peer *peer = &host->peer;
342 void *id;
343
344 if ((net->stun.port_ext && host == net->net_config.local_host) ||
345 peer->state.connected || peer->endpoint)
346 continue;
347
348 id = pex_msg_append(PEX_ID_LEN);
349 if (!id)
350 break;
351
352 memcpy(id, peer->key, PEX_ID_LEN);
353 hosts++;
354 }
355
356 if (!hosts)
357 return;
358
359 now = unet_gettime();
360 rv %= net->hosts.count;
361 for (i = 0; i < 2; i++) {
362 avl_for_each_element(&net->hosts, host, node) {
363 struct network_peer *peer = &host->peer;
364
365 if (rv > 0) {
366 rv--;
367 continue;
368 }
369
370 if (host == net->net_config.local_host)
371 continue;
372
373 if (!peer->state.connected ||
374 peer->state.last_query_sent + 15 >= now)
375 continue;
376
377 D_PEER(net, peer, "send query for %d hosts", hosts);
378 pex_msg_send(net, peer);
379 peer->state.last_query_sent = now;
380 return;
381 }
382 }
383
384 }
385
386 static void
387 network_pex_send_ping(struct network *net, struct network_peer *peer)
388 {
389 if (peer->state.pinged || !peer->state.endpoint.sa.sa_family)
390 return;
391
392 pex_msg_init(net, PEX_MSG_PING);
393 pex_msg_send(net, peer);
394 peer->state.pinged = true;
395 }
396
397 static void
398 network_pex_send_update_request(struct network *net, struct network_peer *peer,
399 struct sockaddr_in6 *addr)
400 {
401 union network_endpoint ep = {};
402 uint64_t version = 0;
403
404 if (addr)
405 memcpy(&ep.in6, addr, sizeof(ep.in6));
406 else
407 pex_get_peer_addr(&ep.in6, net, peer);
408
409 if (net->net_data_len)
410 version = net->net_data_version;
411
412 if (!pex_msg_update_request_init(net->config.pubkey, net->config.key,
413 net->config.auth_key, &ep,
414 version, !!addr))
415 return;
416
417 pex_msg_send_ext(net, peer, addr);
418 }
419
420 void network_pex_event(struct network *net, struct network_peer *peer,
421 enum pex_event ev)
422 {
423 if (!network_pex_active(&net->pex))
424 return;
425
426 switch (ev) {
427 case PEX_EV_HANDSHAKE:
428 peer->state.last_query_sent = 0;
429 pex_send_hello(net, peer);
430 if (net->config.type == NETWORK_TYPE_DYNAMIC)
431 network_pex_send_update_request(net, peer, NULL);
432 break;
433 case PEX_EV_ENDPOINT_CHANGE:
434 network_pex_handle_endpoint_change(net, peer);
435 break;
436 case PEX_EV_QUERY:
437 network_pex_query_hosts(net);
438 break;
439 case PEX_EV_PING:
440 network_pex_send_ping(net, peer);
441 break;
442 }
443 }
444
445 static void
446 network_pex_recv_hello(struct network *net, struct network_peer *peer,
447 const struct pex_hello *data, size_t len)
448 {
449 char addrstr[INET6_ADDRSTRLEN];
450 uint16_t flags;
451 int af;
452
453 if (len < sizeof(*data))
454 return;
455
456 if (peer->state.has_local_ep_addr &&
457 !memcmp(&peer->state.local_ep_addr, data->local_addr, sizeof(data->local_addr)))
458 return;
459
460 flags = ntohs(data->flags);
461 af = (flags & PEER_EP_F_IPV6) ? AF_INET6 : AF_INET;
462 D_PEER(net, peer, "set local endpoint address to %s",
463 inet_ntop(af, data->local_addr, addrstr, sizeof(addrstr)));
464 peer->state.has_local_ep_addr = true;
465 memcpy(&peer->state.local_ep_addr, data->local_addr, sizeof(data->local_addr));
466 }
467
468 static void
469 network_pex_recv_peers(struct network *net, struct network_peer *peer,
470 const struct pex_peer_endpoint *data, size_t len)
471 {
472 struct network_peer *local = &net->net_config.local_host->peer;
473 struct network_peer *cur;
474
475 for (; len >= sizeof(*data); len -= sizeof(*data), data++) {
476 union network_endpoint *ep;
477 uint16_t flags;
478 void *addr;
479 int len;
480
481 if (!memcmp(data->peer_id, &local->key, PEX_ID_LEN)) {
482 network_stun_update_port(net, false, ntohs(data->port));
483 continue;
484 }
485
486 cur = pex_msg_peer(net, data->peer_id);
487 if (!cur || cur == peer)
488 continue;
489
490 D_PEER(net, peer, "received peer address for %s",
491 network_peer_name(cur));
492 flags = ntohs(data->flags);
493 ep = &cur->state.next_endpoint[ENDPOINT_TYPE_PEX];
494 ep->sa.sa_family = (flags & PEER_EP_F_IPV6) ? AF_INET6 : AF_INET;
495 addr = network_endpoint_addr(ep, &len);
496 memcpy(addr, data->addr, len);
497 ep->in.sin_port = data->port;
498 }
499 }
500
501 static void
502 network_pex_recv_query(struct network *net, struct network_peer *peer,
503 const uint8_t *data, size_t len)
504 {
505 struct network_peer *cur;
506 int resp = 0;
507
508 pex_msg_init(net, PEX_MSG_NOTIFY_PEERS);
509 for (; len >= 8; data += 8, len -= 8) {
510 cur = pex_msg_peer(net, data);
511 if (!cur || !cur->state.connected)
512 continue;
513
514 if (!pex_msg_add_peer_endpoint(net, cur, peer))
515 resp++;
516 }
517
518 if (!resp)
519 return;
520
521 D_PEER(net, peer, "send query response with %d hosts", resp);
522 pex_msg_send(net, peer);
523 }
524
525 static void
526 network_pex_recv_ping(struct network *net, struct network_peer *peer)
527 {
528 time_t now = time(NULL);
529
530 if (peer->state.last_request == now)
531 return;
532
533 peer->state.last_request = now;
534 pex_msg_init(net, PEX_MSG_PONG);
535 pex_msg_send(net, peer);
536 }
537
538 static void
539 network_pex_recv_update_request(struct network *net, struct network_peer *peer,
540 const uint8_t *data, size_t len,
541 struct sockaddr_in6 *addr)
542 {
543 struct pex_update_request *req = (struct pex_update_request *)data;
544 struct pex_endpoint_port_notify *port_data;
545 struct pex_msg_update_send_ctx ctx = {};
546 uint64_t req_version = be64_to_cpu(req->cur_version);
547 int *query_count;
548 bool done = false;
549
550 if (len < sizeof(struct pex_update_request))
551 return;
552
553 if (net->config.type != NETWORK_TYPE_DYNAMIC)
554 return;
555
556 if (peer)
557 query_count = &peer->state.num_net_queries;
558 else
559 query_count = &net->num_net_queries;
560
561 if (++*query_count > 10)
562 return;
563
564 D("receive update request, local version=%"PRIu64", remote version=%"PRIu64, net->net_data_version, req_version);
565
566 if (req_version >= net->net_data_version) {
567 struct pex_update_response_no_data *res;
568
569 pex_msg_init_ext(net, PEX_MSG_UPDATE_RESPONSE_NO_DATA, !!addr);
570 res = pex_msg_append(sizeof(*res));
571 res->req_id = req->req_id;
572 res->cur_version = cpu_to_be64(net->net_data_version);
573 pex_msg_send_ext(net, peer, addr);
574 }
575
576 if (req_version > net->net_data_version)
577 network_pex_send_update_request(net, peer, addr);
578
579 if (!peer || !net->net_data_len)
580 return;
581
582 if (req_version >= net->net_data_version)
583 goto out;
584
585 pex_msg_update_response_init(&ctx, net->config.pubkey, net->config.auth_key,
586 peer->key, !!addr, (void *)data,
587 net->net_data, net->net_data_len);
588 while (!done) {
589 pex_msg_send_ext(net, peer, addr);
590 done = !pex_msg_update_response_continue(&ctx);
591 }
592
593 out:
594 if (peer->state.connected || !net->net_config.local_host)
595 return;
596
597 pex_msg_init_ext(net, PEX_MSG_ENDPOINT_PORT_NOTIFY, !!addr);
598
599 port_data = pex_msg_append(sizeof(*port_data));
600 if (net->stun.port_ext)
601 port_data->port = htons(net->stun.port_ext);
602 else
603 port_data->port = htons(net->net_config.local_host->peer.port);
604
605 pex_msg_send_ext(net, peer, addr);
606 }
607
608 static void
609 network_pex_recv_update_response(struct network *net, const uint8_t *data, size_t len,
610 struct sockaddr_in6 *addr, enum pex_opcode op)
611 {
612 struct network_peer *peer;
613 void *net_data;
614 int net_data_len = 0;
615 uint64_t version = 0;
616 bool no_prev_data = !net->net_data_len;
617
618 if (net->config.type != NETWORK_TYPE_DYNAMIC)
619 return;
620
621 net_data = pex_msg_update_response_recv(data, len, op, &net_data_len, &version);
622 if (!net_data)
623 return;
624
625 if (version <= net->net_data_version) {
626 free(net_data);
627 return;
628 }
629
630 D_NET(net, "received updated network data, len=%d", net_data_len);
631 free(net->net_data);
632
633 net->net_data = net_data;
634 net->net_data_len = net_data_len;
635 net->net_data_version = version;
636 if (network_save_dynamic(net) < 0)
637 return;
638
639 uloop_timeout_set(&net->reload_timer, no_prev_data ? 1 : UNETD_DATA_UPDATE_DELAY);
640 vlist_for_each_element(&net->peers, peer, node) {
641 if (!peer->state.connected || !peer->pex_port)
642 continue;
643 network_pex_send_update_request(net, peer, NULL);
644 }
645 }
646
647 static void
648 network_pex_recv(struct network *net, struct network_peer *peer, struct pex_hdr *hdr)
649 {
650 const void *data = hdr + 1;
651
652 if (hdr->version != 0)
653 return;
654
655 D_PEER(net, peer, "PEX rx op=%d", hdr->opcode);
656 switch (hdr->opcode) {
657 case PEX_MSG_HELLO:
658 network_pex_recv_hello(net, peer, data, hdr->len);
659 break;
660 case PEX_MSG_NOTIFY_PEERS:
661 network_pex_recv_peers(net, peer, data, hdr->len);
662 break;
663 case PEX_MSG_QUERY:
664 network_pex_recv_query(net, peer, data, hdr->len);
665 break;
666 case PEX_MSG_PING:
667 network_pex_recv_ping(net, peer);
668 break;
669 case PEX_MSG_PONG:
670 break;
671 case PEX_MSG_UPDATE_REQUEST:
672 network_pex_recv_update_request(net, peer, data, hdr->len,
673 NULL);
674 break;
675 case PEX_MSG_UPDATE_RESPONSE:
676 case PEX_MSG_UPDATE_RESPONSE_DATA:
677 case PEX_MSG_UPDATE_RESPONSE_NO_DATA:
678 network_pex_recv_update_response(net, data, hdr->len,
679 NULL, hdr->opcode);
680 break;
681 case PEX_MSG_ENDPOINT_NOTIFY:
682 break;
683 }
684 }
685
686 static void
687 network_pex_fd_cb(struct uloop_fd *fd, unsigned int events)
688 {
689 struct network *net = container_of(fd, struct network, pex.fd);
690 struct network_peer *local = &net->net_config.local_host->peer;
691 struct network_peer *peer;
692 struct sockaddr_in6 sin6;
693 static char buf[PEX_BUF_SIZE];
694 struct pex_hdr *hdr = (struct pex_hdr *)buf;
695 ssize_t len;
696
697 while (1) {
698 socklen_t slen = sizeof(sin6);
699
700 len = recvfrom(fd->fd, buf, sizeof(buf), 0, (struct sockaddr *)&sin6, &slen);
701 if (len < 0) {
702 if (errno == EINTR)
703 continue;
704
705 if (errno == EAGAIN)
706 break;
707
708 D_NET(net, "recvfrom failed: %s", strerror(errno));
709 network_pex_close(net);
710 return;
711 }
712
713 if (!len)
714 continue;
715
716 hdr = pex_rx_accept(buf, len, false);
717 if (!hdr)
718 continue;
719
720 peer = pex_msg_peer(net, hdr->id);
721 if (!peer)
722 continue;
723
724 if (memcmp(&sin6.sin6_addr, &peer->local_addr.in6, sizeof(sin6.sin6_addr)) != 0)
725 continue;
726
727 if (peer == local)
728 continue;
729
730 network_pex_recv(net, peer, hdr);
731 }
732 }
733
734 void network_pex_create_host(struct network *net, union network_endpoint *ep,
735 unsigned int timeout)
736 {
737 struct network_pex *pex = &net->pex;
738 struct network_pex_host *host;
739 uint64_t now = unet_gettime();
740 bool new_host = false;
741
742 list_for_each_entry(host, &pex->hosts, list) {
743 if (memcmp(&host->endpoint, ep, sizeof(host->endpoint)) != 0)
744 continue;
745
746 if (host->last_ping + 10 < now) {
747 list_move_tail(&host->list, &pex->hosts);
748 network_pex_host_request_update(net, host);
749 }
750 goto out;
751 }
752
753 host = calloc(1, sizeof(*host));
754 new_host = true;
755 memcpy(&host->endpoint, ep, sizeof(host->endpoint));
756 list_add_tail(&host->list, &pex->hosts);
757 pex->num_hosts++;
758
759 out:
760 if (timeout && (new_host || host->timeout))
761 host->timeout = timeout + unet_gettime();
762 }
763
764 static void
765 network_pex_open_auth_connect(struct network *net)
766 {
767 struct network_pex *pex = &net->pex;
768 struct network_peer *peer;
769 struct blob_attr *cur;
770 int rem;
771
772 if (net->config.type != NETWORK_TYPE_DYNAMIC)
773 return;
774
775 uloop_timeout_set(&pex->request_update_timer, 5000);
776
777 vlist_for_each_element(&net->peers, peer, node) {
778 union network_endpoint ep = {};
779
780 if (!peer->endpoint || peer->dynamic)
781 continue;
782
783 if (network_get_endpoint(&ep, AF_UNSPEC, peer->endpoint,
784 UNETD_GLOBAL_PEX_PORT, 0) < 0)
785 continue;
786
787 ep.in.sin_port = htons(UNETD_GLOBAL_PEX_PORT);
788 network_pex_create_host(net, &ep, 0);
789 }
790
791 if (!net->config.auth_connect)
792 return;
793
794 blobmsg_for_each_attr(cur, net->config.auth_connect, rem) {
795 union network_endpoint ep = {};
796
797 if (network_get_endpoint(&ep, AF_UNSPEC, blobmsg_get_string(cur),
798 UNETD_GLOBAL_PEX_PORT, 0) < 0)
799 continue;
800
801 network_pex_create_host(net, &ep, 0);
802 }
803 }
804
805
806 int network_pex_open(struct network *net)
807 {
808 struct network_host *local_host = net->net_config.local_host;
809 struct network_peer *local;
810 struct network_pex *pex = &net->pex;
811 struct sockaddr_in6 sin6 = {};
812 int yes = 1;
813 int fd;
814
815 network_pex_open_auth_connect(net);
816
817 if (!local_host || !local_host->peer.pex_port)
818 return 0;
819
820 local = &local_host->peer;
821 fd = socket(PF_INET6, SOCK_DGRAM, IPPROTO_UDP);
822 if (fd < 0)
823 return -1;
824
825 fcntl(fd, F_SETFL, fcntl(fd, F_GETFL) | O_NONBLOCK);
826 fcntl(fd, F_SETFD, fcntl(fd, F_GETFD) | FD_CLOEXEC);
827
828 sin6.sin6_family = AF_INET6;
829 memcpy(&sin6.sin6_addr, &local->local_addr.in6,
830 sizeof(local->local_addr.in6));
831 sin6.sin6_port = htons(local_host->peer.pex_port);
832
833 if (bind(fd, (struct sockaddr *)&sin6, sizeof(sin6)) < 0) {
834 perror("bind");
835 goto close;
836 }
837
838 setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes));
839 setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &yes, sizeof(yes));
840 #ifdef linux
841 setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE,
842 network_name(net), strlen(network_name(net)));
843 #endif
844
845 pex->fd.fd = fd;
846 pex->fd.cb = network_pex_fd_cb;
847 uloop_fd_add(&pex->fd, ULOOP_READ);
848
849 return 0;
850
851 close:
852 close(fd);
853 return -1;
854 }
855
856 void network_pex_close(struct network *net)
857 {
858 struct network_pex *pex = &net->pex;
859 struct network_pex_host *host, *tmp;
860 uint64_t now = unet_gettime();
861
862 uloop_timeout_cancel(&pex->request_update_timer);
863 list_for_each_entry_safe(host, tmp, &pex->hosts, list) {
864 if (host->timeout)
865 continue;
866
867 if (host->last_active + UNETD_PEX_HOST_ACITVE_TIMEOUT >= now)
868 continue;
869
870 network_pex_free_host(net, host);
871 }
872
873 if (pex->fd.fd < 0)
874 return;
875
876 uloop_fd_delete(&pex->fd);
877 close(pex->fd.fd);
878 network_pex_init(net);
879 }
880
881 void network_pex_free(struct network *net)
882 {
883 struct network_pex *pex = &net->pex;
884 struct network_pex_host *host, *tmp;
885
886 list_for_each_entry_safe(host, tmp, &pex->hosts, list)
887 network_pex_free_host(net, host);
888 }
889
890 static struct network *
891 global_pex_find_network(const uint8_t *id)
892 {
893 struct network *net;
894
895 avl_for_each_element(&networks, net, node) {
896 if (!memcmp(id, net->config.auth_key, PEX_ID_LEN))
897 return net;
898 }
899
900 return NULL;
901 }
902
903 static void
904 global_pex_set_active(struct network *net, struct sockaddr_in6 *addr)
905 {
906 struct network_pex *pex = &net->pex;
907 struct network_pex_host *host;
908
909 list_for_each_entry(host, &pex->hosts, list) {
910 if (memcmp(&host->endpoint.in6, addr, sizeof(*addr)) != 0)
911 continue;
912
913 host->last_active = unet_gettime();
914 }
915 }
916
917 static void
918 global_pex_recv(void *msg, size_t msg_len, struct sockaddr_in6 *addr)
919 {
920 struct pex_hdr *hdr;
921 struct pex_ext_hdr *ehdr;
922 struct network_peer *peer;
923 struct network *net;
924 char buf[INET6_ADDRSTRLEN];
925 void *data;
926 int addr_len;
927 int ep_idx = ENDPOINT_TYPE_ENDPOINT_NOTIFY;
928
929 if (stun_msg_is_valid(msg, msg_len)) {
930 avl_for_each_element(&networks, net, node)
931 network_stun_rx_packet(net, msg, msg_len);
932 }
933
934 hdr = pex_rx_accept(msg, msg_len, true);
935 if (!hdr)
936 return;
937
938 ehdr = (void *)(hdr + 1);
939 data = (void *)(ehdr + 1);
940
941 if (hdr->version != 0)
942 return;
943
944 net = global_pex_find_network(ehdr->auth_id);
945 if (!net || net->config.type != NETWORK_TYPE_DYNAMIC)
946 return;
947
948 *(uint64_t *)hdr->id ^= pex_network_hash(net->config.auth_key, ehdr->nonce);
949
950 global_pex_set_active(net, addr);
951
952 D("PEX global rx op=%d", hdr->opcode);
953 switch (hdr->opcode) {
954 case PEX_MSG_HELLO:
955 case PEX_MSG_NOTIFY_PEERS:
956 case PEX_MSG_QUERY:
957 case PEX_MSG_PING:
958 case PEX_MSG_PONG:
959 break;
960 case PEX_MSG_UPDATE_REQUEST:
961 peer = pex_msg_peer(net, hdr->id);
962 network_pex_recv_update_request(net, peer, data, hdr->len,
963 addr);
964 break;
965 case PEX_MSG_UPDATE_RESPONSE:
966 case PEX_MSG_UPDATE_RESPONSE_DATA:
967 case PEX_MSG_UPDATE_RESPONSE_NO_DATA:
968 network_pex_recv_update_response(net, data, hdr->len, addr, hdr->opcode);
969 break;
970 case PEX_MSG_ENDPOINT_PORT_NOTIFY:
971 if (hdr->len < sizeof(struct pex_endpoint_port_notify))
972 break;
973
974 ep_idx = ENDPOINT_TYPE_ENDPOINT_PORT_NOTIFY;
975 fallthrough;
976 case PEX_MSG_ENDPOINT_NOTIFY:
977 peer = pex_msg_peer(net, hdr->id);
978 if (!peer)
979 break;
980
981 D_PEER(net, peer, "receive endpoint notification from %s",
982 inet_ntop(addr->sin6_family, network_endpoint_addr((void *)addr, &addr_len),
983 buf, sizeof(buf)));
984
985 memcpy(&peer->state.next_endpoint[ep_idx], addr, sizeof(*addr));
986 if (hdr->opcode == PEX_MSG_ENDPOINT_PORT_NOTIFY) {
987 struct pex_endpoint_port_notify *port = data;
988 union network_endpoint host_ep = {
989 .in6 = *addr
990 };
991
992 peer->state.next_endpoint[ep_idx].in.sin_port = port->port;
993 if (net->pex.num_hosts < NETWORK_PEX_HOSTS_LIMIT)
994 network_pex_create_host(net, &host_ep, 120);
995 }
996 break;
997 }
998 }
999
1000 static void
1001 pex_recv_control(struct pex_msg_local_control *msg, int len)
1002 {
1003 struct network *net;
1004
1005 if (msg->msg_type != 0)
1006 return;
1007
1008 net = global_pex_find_network(msg->auth_id);
1009 if (!net)
1010 return;
1011
1012 if (!msg->timeout)
1013 msg->timeout = 60;
1014 network_pex_create_host(net, &msg->ep, msg->timeout);
1015 }
1016
1017 int global_pex_open(const char *unix_path)
1018 {
1019 struct sockaddr_in6 sin6 = {};
1020 int ret;
1021
1022 sin6.sin6_family = AF_INET6;
1023 sin6.sin6_port = htons(global_pex_port);
1024
1025 ret = pex_open(&sin6, sizeof(sin6), global_pex_recv, true);
1026
1027 if (unix_path)
1028 pex_unix_open(unix_path, pex_recv_control);
1029
1030 return ret;
1031 }