dndx / phantun

Transforms UDP stream into (fake) TCP streams that can go through Layer 3 & Layer 4 (NAPT) firewalls/NATs.
Apache License 2.0
1.71k stars 138 forks source link

feat(fake-tcp) add TCP keep-alive support to client #93

Open andreadaoud opened 1 year ago

andreadaoud commented 1 year ago

This adds TCP KeepAlive support to client. Close #30, also related to #87. Three arguments are added: keepalive-time, keepalive-interval, keepalive-retries.

Let's say keepalive-time=300s, keepalive-interval=10s, keepalive-retries=3. This feature works like this: when the client detects that no TCP packet has arrived within 300 seconds, it will send a TCP Keep-alive packet to server. If server doesn't respond in time, the client will retry in 10 seconds. After 3 retries, the client will give up this connection. When server received the Keep-alive packet, it will immediately respond with an ACK.

Although the user application may already have its own keep-alive mechanism, they cannot detect broken connections. To actually distinguish broken "TCP" connection, it is still necessary to have keep-alive on fake-tcp layer. For example, if the NAT mapping table on the router is somehow reset, packets are no longer be able to go through. Without keep alive detection, the client will not mark the connection as expired because the UDP client keeps sending packets, so the UDP client may never be able to communicate. With keep alive detection, after the phantun client detected that the connection is not receiving data, it will actively send keep-alive packets. When maximum retries are reached without response, the client knows that the connection is broken, and it will remove the connection from its memory, so a new connection can be established. This feature will not add any extra overhead on active connections, because packets from the user application will prevent the keepalive-time timer from being triggered.

sakamoto-poteko commented 1 year ago

I'd love this feature. In a very common IPv6 setup, the LAN client probably gets its IP address by SLAAC from router's RA. Suppose the ISP delegates a new prefix to the router, the client would have a new IP but still keep the old (not-yet-expired-but-unusable-already) IP - while the phantun connection still last - which means conntrack isn't going to MASQUERADE to a new address.

Currently the workaround is to simply restart the phantun, but there should be a more elegant way.

andreadaoud commented 1 year ago

@sakamoto-poteko Could you please test if this works?

sakamoto-poteko commented 1 year ago

@sakamoto-poteko Could you please test if this works?

@andreadaoud I've been running with -k 10 with https://github.com/sakamoto-poteko/phantun/tree/andreadaoud-keepalive for a few days. So far so good.