pex: add support for figuring out the external data port via STUN servers
[project/unetd.git] / pex.h
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3 * Copyright (C) 2022 Felix Fietkau <nbd@nbd.name>
4 */
5 #ifndef __UNETD_PEX_H
6 #define __UNETD_PEX_H
7
8 #include <sys/socket.h>
9 #include <libubox/uloop.h>
10 #include "stun.h"
11
12 struct network;
13
14 struct network_pex_host {
15 struct list_head list;
16 uint64_t timeout;
17 uint64_t last_active;
18 union network_endpoint endpoint;
19 };
20
21 struct network_pex {
22 struct uloop_fd fd;
23 struct list_head hosts;
24 struct uloop_timeout request_update_timer;
25 };
26
27 enum network_stun_state {
28 STUN_STATE_IDLE,
29 STUN_STATE_PEX_QUERY_WAIT,
30 STUN_STATE_STUN_QUERY_SEND,
31 STUN_STATE_STUN_QUERY_WAIT,
32 };
33
34 struct network_stun_server {
35 struct list_head list;
36
37 struct avl_node pending_node;
38 struct stun_request req;
39
40 const char *host;
41 uint8_t seq;
42 bool req_auth_port;
43 bool pending;
44 };
45
46 struct network_stun {
47 struct list_head servers;
48 struct avl_tree pending;
49
50 struct uloop_timeout timer;
51
52 enum network_stun_state state;
53 bool wgport_disabled;
54
55 uint16_t auth_port_ext;
56 uint16_t port_local;
57 uint16_t port_ext;
58
59 int retry;
60
61 struct uloop_fd socket;
62 };
63
64 enum pex_event {
65 PEX_EV_HANDSHAKE,
66 PEX_EV_ENDPOINT_CHANGE,
67 PEX_EV_QUERY,
68 PEX_EV_PING,
69 };
70
71 void network_pex_init(struct network *net);
72 int network_pex_open(struct network *net);
73 void network_pex_close(struct network *net);
74 void network_pex_free(struct network *net);
75
76 void network_pex_event(struct network *net, struct network_peer *peer,
77 enum pex_event ev);
78 void network_pex_create_host(struct network *net, union network_endpoint *ep,
79 unsigned int timeout);
80
81 void network_stun_init(struct network *net);
82 void network_stun_free(struct network *net);
83 void network_stun_server_add(struct network *net, const char *host);
84 void network_stun_rx_packet(struct network *net, const void *data, size_t len);
85 void network_stun_update_port(struct network *net, bool auth, uint16_t val);
86 void network_stun_start(struct network *net);
87
88 static inline bool network_pex_active(struct network_pex *pex)
89 {
90 return pex->fd.fd >= 0;
91 }
92
93 int global_pex_open(const char *unix_path);
94
95 #endif