1

I need to create a virtual IP network over TCP connection. The hosting system is Linux, with the TUN/TAP kernel driver, it's quite easy to receive & re-inject IP packets of the virtual network.

The difficult part is to transmit the received IP packets to another host. For some non-technical reasons, I can only transmit the packets over TCP protocol but not UDP. Transmit IP packets over UDP is easy, but with TCP it becomes tricky, here's the reason:

UDP protocol doesn't support retransmission/reordering, just like IP. So, if one UDP packet is sent for every received virtual IP packet, the kernel TCP/IP protocol stack would still see virtual IP packet loss/duplication/reordering(those are required for TCP/IP to work well, if those "features" are missing, the TCP connection speed on the virtual network would suffer). If IP packets are transmitted over TCP all required "features" will be missing, unless they are simulated some how.

It seems I have to fake some kind of packet duplication/loss/reordering on TCP connection, or patch the kernel TCP/IP protocol stack. Both options aren't easy.

Is there any other simpler solution to my problem ? or did I just go into a completely wrong direction ? I'm all ears.

==== UPDATE ====

I'm thinking about using raw IP socket (which could get rid of all the TCP retransmission/reordering stuff on the physical network easily while still using TCP packets) to transmit the received virtual network IP packets. But on the receiving host, how can I only receive the packets I'm interested in and return all other IP packets to the kernel TCP/IP stack ?

user416983
  • 974
  • 3
  • 18
  • 28
  • I assume you have a good reason to hand roll VPN code from scratch? – Joe Jan 08 '15 at 09:43
  • The TCP VPN will simply be considered a reliable network which may lead to a bit more retransmissions on the tunnelled connections in the case the underlying network experiences congestion (in addition to the overhead of tunelling TCP connections inside a TCP connection). Tunnelled TCP connectiosn will still work, albeit not optimally in many cases. There's not really anything you can do about that besides not using TCP for the tunneling , and imo you are overthinking it. – nos Jan 08 '15 at 09:59
  • @Joe Yup, I tested almost every VPN I know, none of them meets my need. The VPN is mainly used to bypass firewall, and security isn't my consideration, so hand roll one from scratch isn't that bad. – user416983 Jan 08 '15 at 12:41
  • @nos I did some test, the network latency is unstable if implemented on TCP. On a 80ms latency physical network, I sometimes got like 1s latency virtual network if the underlying network is busy. When implemented on UDP it's like 100ms latency plus some packet loss. The TCP based implementation feels much worse than the UDP based one (think about browsing the Internet with 2s DNS lookup, 3s TCP handshake). Virtual network congestion control doesn't work at all if the VPN is implemented on TCP. – user416983 Jan 08 '15 at 12:56

1 Answers1

6

First of all, you do not want to make a VPN over TCP because you would end up with tcp-over-tcp eventually. The main issue is that the timers of your inner TCP and outer TCP might differ significantly which negatively impacts your TCP session reliability. You can find a bit longer explanation here.

UDP protocol doesn't support retransmission/reordering, just like IP. So, if one UDP packet is sent for every received virtual IP packet, the kernel TCP/IP protocol stack would still see virtual IP packet loss/duplication/reordering(those are required for TCP/IP to work well, if those "features" are missing, the TCP connection speed on the virtual network would suffer). If IP packets are transmitted over TCP all required "features" will be missing, unless they are simulated some how.

This does not make sense, if your outer layer uses TCP as a transport mechanism, nothing stops your inner layer to still use the full ip/tcp stack, including those features. They can conflict badly like I said, but it's not that this functionality disappears or breaks completely.

It seems like you actually want to use TCP just to have the headers and ignore the actual protocol, this would indeed avoid the issues with tcp over tcp. However, once again this is a very bad idea. Flow processing for firewalls, NAT, DPI, tcp boosters, becomes more and more common, if you fake TCP packets you might up stressing those boxes, possibly detoriating your own connection once again.

So you should ask yourself why you can't use UDP, and if no alternative protocol (header) is okay, like GRE or L2TP.

KillianDS
  • 16,936
  • 4
  • 61
  • 70
  • You are right, I don't need full blown TCP, just the headers, in fact TLS (not DTLS) headers are also needed, so TCP is my only option. You got my point: it's not easy to fake those TCP packets, since NAT/firewall/router will analyze the TCP header fields. – user416983 Jan 15 '15 at 06:33
  • @user416983 if you want to use TLS I don't think you have a choice aside from using the full TCP stack. TLS relies on a reliable transport protocol as far as I know. SCTP might also be an option but that is often not supported by NAT. – KillianDS Jan 16 '15 at 08:05