Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RFC: Fake TCP with UDP #2

Open
jbenet opened this issue May 18, 2014 · 15 comments
Open

RFC: Fake TCP with UDP #2

jbenet opened this issue May 18, 2014 · 15 comments

Comments

@jbenet
Copy link
Owner

jbenet commented May 18, 2014

In p2p systems, it's useful to use udp, as connection state and reliability can be done at a higher layer (i.e. {uTP,DCCP,SCTP}/UDP/IP). NAT Traversal sucks. Many aggressive NATs will block all UDP access. TURN sometimes fails. WebRTC has not gotten 100% connectivity.

As @feross pointed out, SSL/TCP is usually accepted. It would be pretty bad if NATs blanket-blocked HTTPS access. It is generally annoying to do p2p relaying on TCP, as TCP has all the session magic in its stack. It would be nicer to be able to use standard UDP (particularly when you have your own reliability / congestion control on top).

So, what if one does {uTP,DCCP,SCTP}/SSL/UTCP, Unreliable TCP. Use what -- to the NAT -- looks like legitimate TCP traffic, but is simply UDP. Will still have to keep track of seqnos (windowing) on a per-flow basis, as NATs/Firewalls may rewrite/drop a packet based on those.

 0                   1                   2                   3      
    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1  
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+      
   |          Source Port          |       Destination Port        |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                        Sequence Number                        |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                    Acknowledgment Number                      |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |  Data |           |U|A|P|R|S|F|                               |
   | Offset| Reserved  |R|C|S|S|Y|I|            Window             |
   |       |           |G|K|H|T|N|N|                               |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |           Checksum            |         Urgent Pointer        |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                    Options                    |    Padding    |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                             data                              |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

                            TCP Header Format 

Nothing else seems to matter. I think this would totally bypass most NATs.

@jbenet
Copy link
Owner Author

jbenet commented May 18, 2014

@feross
Copy link

feross commented May 18, 2014

This is clever and would probably work!

@jbenet
Copy link
Owner Author

jbenet commented May 18, 2014

@cleichner

@davidad
Copy link

davidad commented May 18, 2014

I think this is something that could only be determined experimentally. If it does work, the hardest part would be bypassing the OS TCP stack. This is, of course, possible—just annoying.

@jbenet
Copy link
Owner Author

jbenet commented May 18, 2014

@davidad yeah. raw ip in user land gets into permissions issues.

@msparks
Copy link

msparks commented May 19, 2014

Agree with @davidad.

Do you have numbers on the percentage of "aggressive NATs" in the wild? Are they increasing in number or decreasing? UTCP, as clever as it is, may just be yak shaving for the last few percent of connectivity.

@jbenet
Copy link
Owner Author

jbenet commented May 19, 2014

In https://www.usenix.org/conference/nsdi12/technical-sessions/presentation/raiciu talks about real life middlebox problems. (it's also a good talk :) )

If +hangout users get "cannot connect to this other user at all" even 0.1% of the time, it would be unacceptable. In the end, need to relay any pair of connections. Ensuring any two hosts are capable of establishing a stream is not yak shaving IMO, it's basic internet functionality.

@davidad
Copy link

davidad commented May 19, 2014

I think @msparks means that it's yak shaving vs. using regular TCP as a fallback, even if UTCP is "nicer". UTCP is still not guaranteed to work, so you'd probably need a regular-TCP fallback either way, and adding UTCP into the mix seems like a low payoff/complexity ratio.

@jbenet
Copy link
Owner Author

jbenet commented Apr 8, 2015

Oh Minion looks pretty good

@lepasserby
Copy link

This is absolutely awesome (especially if one uses TLS to obscure actual data being transmitted) however, wouldn't that require kernel modifications (and thus become rather problematic for platforms like android, where building/loading your own kernel modules is still a god-damn adventure) ?

And yes, reminiscent of Minion, as well as this https://www.usenix.org/conference/foci13/workshop-program/presentation/nowlan
Both minion and "uTCP" seem to require kernel modification tho :(

It would be extremely awesome if there was a way to make this work in a manner that
(1) is not distinguishable from a "healthy" HTTPS/TLS session on port 443 for a competent, hostile observer (think China's Great Firewal thingie)
(2) does not require kernel modification on user's side (thus allowing it to be useful for mobile platforms with limited/complicated kernel modification opportunities)
(3) supports bi-directional unordered delivery (because "server -> client" head-of-line blocking is a bad thing even when "client -> server" head-of-line blocking is not present)

P.S.:
Since we want complete indistinguishability from normal TCP, we should probably still ACK (otherwise a smart firewall will be able to tell something very fishy is going on) thus some retransmit overhead is unavoidable, but with out-of-order support being in place, that's probably not a terrible thing.

@tv42
Copy link

tv42 commented May 1, 2015

@lepasserby Kernel changes are for performance. Though injecting/receiving packets that look like TCP would require root privileges -> no unrooted Android etc. This is why piggybacking on UDP is so popular.

@lepasserby
Copy link

@tv42
Well, root is much less of an issue (absolute majority of android phones are rootable).
Writing (and loading) a kernel module for android would be a PITA (and given the unhealthy diversity of android phones, compatibility will be an issue)

How severe would be perfomance degradation that one can expect without kernel changes (ballpark estimate) ?

@lepasserby
Copy link

Hmmmm... just a thought - it seems to me that android does in fact allow raw IP sockets for root apps.
One could mayhaps establish raw IP connection and use it to transmit and recieve packets with headers that "look like" good TCP-TLS, but in fact are "FakeTCP-TLS/uTCP-TLS" ?

The server, most likely, will have a patched kernel to ensure "properly unordered" behavior.

The overhead, in terms of bandwidth wasted, would be [(retransmit overhead, since we have to follow retransmit behaviors even if we have unordered delivery) + (header-related overhead, since we have to feign TCP)]. Seems nice.

Would that work?

@wangyu-
Copy link

wangyu- commented Aug 9, 2017

i have a repo implemented the similiar idea,use raw socket to send udp packet with fake tcp/icmp headers ,its basically a tunnel which supports almost all udp programs.
https://github.com/wangyu-/udp2raw-tunnel

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants