top | item 22758639

Show HN: A UDP to TCP proxy server for sending HTTP requests with zero latency

146 points| timetoogo | 6 years ago |github.com

75 comments

order

cosmotic|6 years ago

This doesn't just magically remove the latency.

* I presume the case here is the proxy is close to the server so the handshake is faster and thus the single benefit of this setup, although that's not at all what's illustrated.

* The illustrations show the request taking longer with the proxy, although maybe the two diagrams aren't to scale

* The originating UDP packet could get lost and the client would never know

The author could improve the latency by prepping the TCP connection before the request comes in, giving a significant reduction in latency.

kstenerud|6 years ago

It's about SENDING requests with "zero latency", not about completing http operations with zero latency.

And yes, you get no confirmation, and no reply.

I must admit I'm hard pressed to come up with a use case for this. You could just as easily do a regular HTTP request on a separate thread and throw away the result to get "zero latency" fire-and-forget behavior.

jaimex2|6 years ago

Finding a use case for this would be tricky...

Quic already does this end to end.

The only use case I can think of might be gaming. If you had a HTTP/Websockets based game you wanted to cut latency down on you could have the FF proxy hosted near the game server.

umvi|6 years ago

> Finding a use case for this would be tricky...

I can tell you a real life use case that already exists because I built this exact thing already (though a closed-source version): satellite internet terminals.

With satellite internet, uplink (upload) is generally more complicated than downlink (download). This is because a terminal can just passively listen for packets intended for him, but with uplink you have to make sure you only transmit in your designated time slot.

Because uplink is more complicated than downlink, more often than not uplink will get in a degraded or broken state, while downlink is still operational.

Now say I get a call from a customer service rep saying a customer's terminal is stuck in a degraded state. How can I recover it? TCP (and therefore HTTP) is a no-go because it requires uplink to be fully functional. So I can't visit the terminal's embedded webserver or issue commands to the HTTP API.

However, using a udp to tcp proxy like this, I can issue commands to the terminal's HTTP API "blindly" which it will then execute to (hopefully) recover itself. This can also be done with other "one-way" protocols like SNMP.

vvanders|6 years ago

You can already do this with WebRTC, you just need and implementation that won't fall back to TCP if the UDP negotiation fails.

bweitzman|6 years ago

What would be the use case of this versus say making an HTTP request over TCP in a background thread?

aeyes|6 years ago

Well obviously you don't need to maintain a background thread and a connection so you would be able to send out much more data using the same resources by offloading the TCP workload to the proxy.

If the service you are sending data to is unavailable, you wouldn't get any backpressure from it.

Think of a monitoring or log system where you might want to send out millions of datapoints but you can afford to lose some, in return you don't have to worry about the system not being reachable.

leoedin|6 years ago

I wonder if the author wrote this with something in mind?

Fire and forget logging to HTTP endpoints would be pretty useful for IoT sensors. You'd have a lot less code and could potentially save significant power. You obviously lose the ability to guarantee data arrived, but that's probably not important for all sensor situations.

jeroenhd|5 years ago

For that stuff protocols such as CoAP might be more useful as it's a standard with pretty much the same benefits but less custom code.

It's even possible to translate CoAP directly into HTTP using a proxy such as Squid.

There's also MQTT, which was basically designed for IoT sensor reporting. This has even more supported libraries and has been around for ages.

The UDP proxy system has the benefit of not being able to fall victim to classic UDP amplification vulnerabilities (send a packet with a spoofed source and have the response bounce back), but it does allow an unsuspecting proxy server to turn into a HTTP-based DDoS. You can send a single packet towards a server and the server automatically does a full TCP handshake and payload delivery for you! That's a lot of extra traffic.

I'd stick with known protocols for IoT stuff instead of this. At least the risks have been analysed and firewalls can (should) be easily configurable to block outgoing DDoS attacks in the worst case. The same is not really true for this.

bullen|6 years ago

I'm going to sacrifice my karma for this: the solution is not to make TCP use UDP, but instead to allow TCP to behave like UDP by giving it the option to ignore out-of-order. All operatives have flawed implementaions of this, but we need it to be in the TCP RFC.

mbreese|6 years ago

Wouldn’t out of order TCP require whole new client libraries as well. All the TCP client code expects well ordered packets. So if you’re doing that, might as well go all the way to a new protocol. Which isn’t this then QUIC? I’m not familiar enough with either to know what the practical differences would be between QUIC and out of order TCP.

eps|5 years ago

Given MTU fragmentation this is not a very bright idea.

It will basically require another framing protocol on top of TCP to make it even remotely usable.

huhtenberg|6 years ago

Good stuff. Could use some asserts and checks for NULL here and there, but overall it's a nicely organized C code (and with proper bracing and indentation style :)). Always a pleasure to read through something like this.

edoo|6 years ago

Actually it has the wrong indentation style. Should be tabs left spaces right. I run tab width of 3 in my editors. To each their own, if you use tabs left of course.

jkarneges|6 years ago

Neat! FF Proxy reminds me of one of my projects ( https://github.com/fanout/zurl ), but more extreme since the sender uses raw UDP. It seems like it would be great for remote use by lightweight senders. Maybe low power devices emitting stats?

P.S. good to see the comment, "TODO: filter out private IP ranges". I was going to suggest this but it seems you already know. :)

ElijahLynn|6 years ago

"Zero Latency"?

throw-away_42|6 years ago

Zero Latency*

* for sufficiently large values of zero

jandrese|6 years ago

Effectively zero latency from the data being written to the socket until it appears on the wire, by eliminating the latency of the TCP 3 way handshake.

They've basically discovered TCP Performance Enhancing Proxies, used for decades for space communications.

dspillett|6 years ago

Yes, but only for a specific set of circumstances (when you can live without reliable & timely delivery, and do not need any sort of response) and only from the PoV of the client.

The claim seems correct with those caveats, though is a bit "click baity" without them.

umvi|6 years ago

Well, from the perspective of the client, yes.

fourmyle|6 years ago

[deleted]

sneak|6 years ago

I am reminded of statsd. I like this, though, as it generalizes more. Cool hack!

I wonder if it would be worth making this embeddable into an existing web framework for Python or Go, so that the existing service could receive UDP requests. Then again, that's what 0RTT is for so it might be a little wheel-reinventy.

thecodrr|6 years ago

WOW. This is such a fascinating project. (near) zero latencies are relatively hard to achieve especially over network connections. Will definitely try this out once I get the time. Oh and thanks for the various pre-built client libraries, will definitely come in useful.

vvanders|6 years ago

Using the term "zero" is not the best choice. UDP packets have the same latency as TCP packets, you're just saving the handshake.

Games and VoIP still have latency, they're usually structured such the data loss and duplicate responses are normal and handled appropriately.

flyGuyOnTheSly|6 years ago

Is this only possible if the server you are communicating with is setup to work with ff-proxy in the first place, I imagine?

I can't just start using this and get no handshake confirmations from any website's rest api can I?

loeg|6 years ago

The server doesn't need anything special. You could indeed just start using this and fire-and-forget REST API requests.

czbond|6 years ago

This is very cool. I had to write something in the near realm a few year ago, and love your implementation.

nickphx|6 years ago

Impressive work, thanks for sharing.

fitzn|6 years ago

I read the README. It certainly makes some trade-offs! :) Sounds like it was a fun exercise.

stevemadere|5 years ago

This would be a great DOS attack tool!

zekrioca|6 years ago

The second figure could have shown the client receiving the HTTP response to its request. Also, isn't HTTP/3 (QUIC) already supporting something like this?

easytiger|6 years ago

> zero latency

> Docker

29athrowaway|6 years ago

UDP doesn't implement:

- Reliable delivery

- Ordering

- Congestion control

- Flow control

...and a large list of RFCs that I'll never ever read.

If you are delivering a document (like a webpage or an API response), or transferring files, you want these things.

If you are doing real-time stuff, like video, voice, real-time games... and you just need the most recent information, that's where UDP shines.

W4ldi|6 years ago

I think the author is aware of that. I think it's more an easy way to 'udp-fy' existing tcp services and only update the client to use udp

pankake|6 years ago

I dont know why more web servers are not using UDP by default and only go TCP when the client or content needs it. For example, sites like youtube - the videos must be streamed to us, why not the site itself? Only when I want the client to definitley know it sent data (a banking transaction, an amazon order) but for the vast majority of sites UDP bi-di should be fine.

Can you imagine the amount of bandwidth saved around the world in aggregate?

TCP should be restricted based on content classification.

rlpb|6 years ago

UDP does not have congestion or flow control.