#21560 closed defect (fixed)
NAT Network + LWIP: UDP proxy expires too early
Reported by: | fth0 | Owned by: | |
---|---|---|---|
Component: | network/NAT | Version: | VirtualBox-7.0.6 |
Keywords: | NAT Network, LWIP UDP proxy | Cc: | |
Guest type: | all | Host type: | all |
Description
TL;DR:
When using the NAT Network networking mode, the LWIP UDP proxy expires after being idle for 18 to 21 seconds, which is sometimes less than the intended 20 seconds. There's probably a simple bugfix by changing a comparison operator.
Detailed explanation:
src/VBox/Devices/Network/lwip-new/src/include/lwip/udp.h: /** * Time in seconds a proxy udp pcb is kept alive without outgoing * traffic. * * E.g. RFC 3948 (read "VPN") uses default NAT keepalive of 20 * seconds. */ #define UDP_PROXY_EXPIRATION 20 /* seconds */ #define UDP_PROXY_TMR_INTERVAL 3000 /* milliseconds */
The comment explains the intention to keep the UDP proxy alive for 20 seconds, and a 3 seconds timer is used to implement that, so far, so good.
src/VBox/Devices/Network/lwip-new/src/core/udp.c void udp_proxy_input(struct pbuf *p, struct netif *inp) { [...] pcb->proxy_cnt = 0; /* (1) */ [...] } void udp_proxy_tmr(void) { [...] const int limit = ((UDP_PROXY_EXPIRATION /* sec */ * 1000 /* msec/sec */ + UDP_PROXY_TMR_INTERVAL /* msec */ - 1) / UDP_PROXY_TMR_INTERVAL /* msec */); /* (2) */ [...] pprev = &udp_proxy_pcbs; pcb = udp_proxy_pcbs; while (pcb != NULL) { struct udp_pcb *xpcb; if (++pcb->proxy_cnt < limit) { /* (3) */ pprev = &pcb->next; pcb = pcb->next; continue; } [...] (*xpcb->recv.ip4)(xpcb->recv_arg, xpcb, NULL, /* signals expiration timeout */ ipX_2_ip(&xpcb->remote_ip), xpcb->remote_port); } [...] }
(1) Each UDP proxy has a counter which is reset to 0 after each sent packet.
(2) In the timer handling function, the limit variable is calculated to 7 timer intervals (7 * 3 = 21 >= 20). But since the timer is global for all UDP proxies and packets, it was (usually) already running when the last packet was sent. In consequence, the effective idle time of a UDP proxy is (usually) less than the counted timer intervals and a UDP proxy gets expired after being idle for between 18 and 21 seconds, which obviously breaks the goal of the 20-seconds NAT keep alive packets of RFC 3948.
(3) IMHO an easy fix would be to change the comparison with the limit variable from "<" to "<=", leading effectively to idle times of at least 7 full timer intervals (21 to 24 seconds) being allowed.
Change History (4)
comment:1 by , 20 months ago
comment:2 by , 19 months ago
Thank you for detailed explanation. I've applied your suggested fix, it will be included into the next maintenance release.
comment:3 by , 17 months ago
Resolution: | → fixed |
---|---|
Status: | new → closed |
Hello,
We just released VirtualBox 7.0.10. This issue should be fixed in this release. Culd you please give it a try? Packages are available on our downloads page.
comment:4 by , 16 months ago
I discovered the bug while investigating another user's issue in the VirtualBox forum. Since the bug fix was done exactly as proposed by me and since I don't have a test setup, I'll assess the bug fix as correct without testing it.
For the possible implications of this bug (e.g. breaking IPsec VPN connections at seemingly random times), see NAT Network Creates Spurious Translation for IPSEC VPN.