2 #include <netinet/in.h>
3 #include <netinet/ip.h>
4 #include <netinet/udp.h>
8 #include <libubox/usock.h>
12 static inline int avl_stun_cmp(const void *k1
, const void *k2
, void *priv
)
14 return memcmp(k1
, k2
, 12);
17 static bool has_connected_peer(struct network
*net
, bool pex
)
19 struct network_peer
*peer
;
21 vlist_for_each_element(&net
->peers
, peer
, node
) {
22 if (pex
&& !peer
->pex_port
)
25 if (peer
->state
.connected
)
32 void network_stun_server_add(struct network
*net
, const char *host
)
34 struct network_stun
*stun
= &net
->stun
;
35 struct network_stun_server
*s
;
38 s
= calloc_a(sizeof(*s
), &name_buf
, strlen(host
) + 1);
39 s
->pending_node
.key
= s
->req
.transaction
;
40 s
->host
= strcpy(name_buf
, host
);
42 list_add_tail(&s
->list
, &stun
->servers
);
46 network_stun_close_socket(struct network
*net
)
48 struct network_host
*local
= net
->net_config
.local_host
;
49 struct network_stun
*stun
= &net
->stun
;
51 if (!stun
->wgport_disabled
)
54 D_NET(net
, "close STUN socket");
55 uloop_fd_delete(&stun
->socket
);
56 close(stun
->socket
.fd
);
57 wg_init_local(net
, &local
->peer
);
58 stun
->wgport_disabled
= false;
62 network_stun_socket_cb(struct uloop_fd
*fd
, unsigned int events
)
64 struct network_stun
*stun
= container_of(fd
, struct network_stun
, socket
);
65 struct network
*net
= container_of(stun
, struct network
, stun
);
70 len
= recv(fd
->fd
, buf
, sizeof(buf
), 0);
78 network_stun_close_socket(net
);
82 if (!stun_msg_is_valid(buf
, len
))
85 network_stun_rx_packet(net
, buf
, len
);
90 network_stun_open_socket(struct network
*net
)
92 struct network_host
*local
= net
->net_config
.local_host
;
93 struct network_stun
*stun
= &net
->stun
;
96 if (stun
->wgport_disabled
)
99 D_NET(net
, "open STUN socket");
100 wg_init_local(net
, NULL
);
102 fd
= usock(USOCK_SERVER
| USOCK_UDP
| USOCK_IPV4ONLY
| USOCK_NONBLOCK
,
103 NULL
, usock_port(stun
->port_local
));
105 wg_init_local(net
, &local
->peer
);
109 stun
->socket
.fd
= fd
;
110 uloop_fd_add(&stun
->socket
, ULOOP_READ
);
111 stun
->wgport_disabled
= true;
115 network_stun_query_next(struct network
*net
)
117 struct network_stun
*stun
= &net
->stun
;
118 struct network_stun_server
*s
;
119 char addrstr
[INET6_ADDRSTRLEN
];
120 union network_endpoint ep
;
121 uint16_t res_port
= 0;
126 s
= list_first_entry(&stun
->servers
, struct network_stun_server
, list
);
130 /* send next query */
131 if (network_get_endpoint(&ep
, AF_INET
, s
->host
, 0, s
->seq
++) < 0) {
132 D_NET(net
, "lookup failed for STUN host %s", s
->host
);
136 if (ep
.sa
.sa_family
!= AF_INET
|| !ep
.in
.sin_port
)
139 if (!stun
->wgport_disabled
&& stun
->auth_port_ext
)
140 res_port
= stun
->auth_port_ext
;
142 D_NET(net
, "Send STUN query to %s, res_port=%d, wg_disabled=%d",
143 inet_ntop(ep
.sa
.sa_family
, network_endpoint_addr(&ep
, NULL
),
144 addrstr
, sizeof(addrstr
)), res_port
, stun
->wgport_disabled
);
145 msg
= stun_msg_request_prepare(&s
->req
, &len
, res_port
);
150 s
->req_auth_port
= false;
151 if (stun
->wgport_disabled
) {
152 ret
= sendto(stun
->socket
.fd
, msg
, len
, 0, &ep
.sa
, sizeof(ep
.in
));
153 } else if (!stun
->auth_port_ext
) {
154 s
->req_auth_port
= true;
155 ret
= sendto(pex_socket(), msg
, len
, 0, &ep
.sa
, sizeof(ep
.in
));
161 union network_addr local_addr
= {};
163 network_get_local_addr(&local_addr
, &ep
);
164 packet_hdr
.ip
= (struct ip
){
169 .ip_src
= local_addr
.in
,
170 .ip_dst
= ep
.in
.sin_addr
,
172 packet_hdr
.udp
= (struct udphdr
){
173 .uh_sport
= htons(stun
->port_local
),
174 .uh_dport
= ep
.in
.sin_port
,
178 ret
= sendto_rawudp(pex_raw_socket(AF_INET
), &ep
,
179 &packet_hdr
, sizeof(packet_hdr
),
183 if (ret
< 0 && errno
== EINTR
)
187 avl_insert(&stun
->pending
, &s
->pending_node
);
190 if (!list_is_last(&s
->list
, &stun
->servers
))
191 list_move_tail(&s
->list
, &stun
->servers
);
197 network_stun_query_clear_pending(struct network
*net
)
199 struct network_stun
*stun
= &net
->stun
;
200 struct network_stun_server
*s
;
202 list_for_each_entry(s
, &stun
->servers
, list
) {
206 avl_delete(&stun
->pending
, &s
->pending_node
);
211 void network_stun_rx_packet(struct network
*net
, const void *data
, size_t len
)
213 struct network_stun
*stun
= &net
->stun
;
214 const struct stun_msg_hdr
*hdr
= data
;
215 struct network_stun_server
*s
;
217 s
= avl_find_element(&stun
->pending
, hdr
->transaction
, s
, pending_node
);
221 if (!stun_msg_request_complete(&s
->req
, data
, len
))
227 network_stun_update_port(net
, s
->req_auth_port
, s
->req
.port
);
228 if (s
->req_auth_port
)
229 stun
->state
= STUN_STATE_STUN_QUERY_SEND
;
231 stun
->state
= STUN_STATE_IDLE
;
233 network_stun_query_clear_pending(net
);
235 uloop_timeout_set(&stun
->timer
, 1);
239 network_stun_timer_cb(struct uloop_timeout
*t
)
241 struct network_stun
*stun
= container_of(t
, struct network_stun
, timer
);
242 struct network
*net
= container_of(stun
, struct network
, stun
);
243 unsigned int next
= 0;
246 switch (stun
->state
) {
247 case STUN_STATE_IDLE
:
248 network_stun_close_socket(net
);
249 next
= 15 * 60 * 1000;
250 stun
->state
= STUN_STATE_STUN_QUERY_SEND
;
251 D_NET(net
, "STUN idle");
253 case STUN_STATE_PEX_QUERY_WAIT
:
254 stun
->state
= STUN_STATE_STUN_QUERY_SEND
;
256 case STUN_STATE_STUN_QUERY_SEND
:
257 if (network_stun_query_next(net
)) {
262 stun
->state
= STUN_STATE_STUN_QUERY_WAIT
;
263 D_NET(net
, "wait for STUN server responses");
266 case STUN_STATE_STUN_QUERY_WAIT
:
267 D_NET(net
, "timeout waiting for STUN server responses, retry=%d", stun
->retry
);
268 network_stun_query_clear_pending(net
);
269 if (stun
->retry
> 0) {
271 stun
->state
= STUN_STATE_STUN_QUERY_SEND
;
275 if (!stun
->port_ext
&& !stun
->wgport_disabled
) {
276 network_stun_open_socket(net
);
277 stun
->state
= STUN_STATE_STUN_QUERY_SEND
;
280 stun
->state
= STUN_STATE_IDLE
;
286 uloop_timeout_set(t
, next
);
289 void network_stun_update_port(struct network
*net
, bool auth
, uint16_t val
)
291 struct network_stun
*stun
= &net
->stun
;
292 uint16_t *port
= auth
? &stun
->auth_port_ext
: &stun
->port_ext
;
294 D_NET(net
, "Update external %s port: %d", auth
? "auth" : "data", val
);
298 void network_stun_start(struct network
*net
)
300 struct network_host
*local
= net
->net_config
.local_host
;
301 struct network_stun
*stun
= &net
->stun
;
302 unsigned int next
= 1;
304 if (!local
|| list_empty(&stun
->servers
))
307 if (local
->peer
.port
!= stun
->port_local
) {
309 stun
->port_local
= local
->peer
.port
;
312 if (!stun
->port_ext
&& has_connected_peer(net
, true)) {
313 D_NET(net
, "wait for port information from PEX");
314 stun
->state
= STUN_STATE_PEX_QUERY_WAIT
;
317 if (!stun
->port_ext
&& !has_connected_peer(net
, false))
318 network_stun_open_socket(net
);
320 stun
->state
= STUN_STATE_STUN_QUERY_SEND
;
324 uloop_timeout_set(&stun
->timer
, next
);
327 void network_stun_init(struct network
*net
)
329 struct network_stun
*stun
= &net
->stun
;
331 stun
->socket
.cb
= network_stun_socket_cb
;
332 stun
->timer
.cb
= network_stun_timer_cb
;
333 INIT_LIST_HEAD(&stun
->servers
);
334 avl_init(&stun
->pending
, avl_stun_cmp
, true, NULL
);
337 void network_stun_free(struct network
*net
)
339 struct network_stun
*stun
= &net
->stun
;
340 struct network_stun_server
*s
, *tmp
;
342 uloop_timeout_cancel(&stun
->timer
);
343 network_stun_close_socket(net
);
345 avl_remove_all_elements(&stun
->pending
, s
, pending_node
, tmp
)
348 list_for_each_entry_safe(s
, tmp
, &stun
->servers
, list
) {