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