
High Performance TCP Proxy Server - ArashPartow
http://www.partow.net/programming/tcpproxy/idx.html
======
huhtenberg
Very nice, but this is more of a demo code for boost::asio than something that
is production-worthy.

For example, it doesn't relay FINs between connections, doesn't disable Nagle
algorithm on the upstream socket, doesn't wait for pending writes to complete
before tearing down the connection, doesn't handle congestion at all
(potentially leading to unbound memory use), etc.

~~~
pacmanfan
Could you point to an open source TCP proxy that you'd consider production
worthy with an approachable code base?

~~~
user5994461
HAProxy is the gold standard.

nginx and apache only do HTTP(S). Don't support TCP.

~~~
jorams
> nginx and apache only do HTTP(S). Don't support TCP.

That's not entirely accurate. For nginx, for example, there's the
ngx_stream_core_module[1]. It's not particularly well-documented though, so I
don't know much about it.

[1]:
[https://nginx.org/en/docs/stream/ngx_stream_core_module.html](https://nginx.org/en/docs/stream/ngx_stream_core_module.html)

~~~
user5994461
It's totally experimental. It's only been made a few months ago. It's not even
compiled into the official distribution, you gotta compile nginx yourself with
special flags.

For the sake of god, please don't have your entire site run on experimental
software like that. ^^

------
adontz
Why not just?

Linux: iptables -t nat -A PREROUTING -p tcp -s 192.168.20.200/0 -d
192.168.0.100/0 --dport 8080 -j REDIRECT --to-ports 20000

Windows: netsh interface portproxy add v4tov4 listenaddress=192.168.20.200
listenport=8080 connectaddress=192.168.0.100 connectport=20000 protocol=tcp

~~~
user5994461

        -s 192.168.20.200/0 -d 192.168.0.100/0
    

That sounds wrong.

You probably meant /24 or /32\. Or you meant to not write anything to not
filter it at all.

~~~
adontz
Yeah, sorry for that, was copy-pasting too quickly :-)

------
userbinator
As someone who has also written a TCP proxy (along with _many_ others...),
after thoroughly reading the page I'm still unsure of how exactly this is
"high performance". It is also curious that, despite the fact that it uses a
separate library for networking, the source is already quite a bit longer than
some other proxies which don't. I found the explanation overly complex.

Around half the code in this implementation could probably be removed by the
realisation that, after a connection is established, both ends are completely
symmetric: all it needs to do is try to read from A and write to B, then try
to read from B and write to A. If A closes, close B. If B closes, close A.

~~~
zzzcpan
> If A closes, close B. If B closes, close A.

It's shutdown() writes on EOFs, not close, with refcounting to also do close()
when EOFs were detected on both directions (I also have written a TCP proxy).
But yeah, TCP proxies are trivial, would be more interesting to see something
like a tunneling proxy that sends data over multiple connections to maximize
performance.

~~~
tlarkworthy
Hey, I am looking for a way of packing multiple TCP streams over a single TCP
connection to a backend server. I can unpack them in application logic if
necessary. Do you know what that is called? Kinda like SCTP

~~~
tyingq
The quick and dirty approach would be an ssh tunnel or vpn. There's also GRE
tunnels which would be faster, but not encrypted. Any of these would work
without having to change the application.

Probably, though, it's best to start with why you would want to do that. You
could be, for example, trying to solve something where a pub/sub model would
work better. Or just two separate apps, on different ports. What's driving the
idea of multiplexing?

~~~
tlarkworthy
Oh that's interesting, can we speak via email:- tom dot larkworthy at Google's
popular email provider?

------
matthewaveryusa
As a sidenote if you don't have a requirement to compile with C++03 I would
recommend using the standalone asio library free from boost[1]. The only
things you need to modify are the includes and namespaces.

[1] [http://think-async.com/Asio/Download](http://think-
async.com/Asio/Download)

~~~
inetknght
Why would you recommend the upstream Asio library instead of the one in Boost?

~~~
matthewaveryusa
Because it has zero dependencies -- There's no reason to pull in
boost::shared_ptr when you can use std::shared_ptr

------
larvaetron
A similar application that I'm fond of is Pen, which also does simple load
balancing and has udp support:

[http://siag.nu/pen/](http://siag.nu/pen/)

------
mdekkers
Ironically, the site appears down (I am redirected to google)

~~~
petethepig
I thought it was some kind of a joke. I guess you could say that google.com is
a high performance tcp proxy server.

------
throwaway2016a
How does this compare to using HAProxy in TCP mode?

~~~
matthewaveryusa
HAProxy is 90k loc while this is 300 loc so they really are different beasts.
I would say HAPRoxy is a great general purpose proxy that has most of the
features you want while this proxy server is a MVP proxy you can grow off of
if you want to do something that HAProxy can't provide.

~~~
shouldbworking
Netty is a more mature foundation for this sort of thing and likely much
faster

~~~
matthewaveryusa
Again, this is a really cool 300 loc snippet. No need to pull in the jvm if
you're going to do something simple.

As for performance, a reproducible benchmark is the minimum requirement to
even start the conversation.

~~~
eropple
And yet by "pulling in the JVM" (which is a rounding error in 2017), it's
remarkably easy to generate a proxy that actually works as people expect a TCP
proxy to work. This doesn't even so much as wait for connections to drain
before terminating. This "300-line snippet" (which is reliant on Asio, which
is _not_ 300 lines by any stretch) is, as near as I can tell, not viable in
real-world conditions and the spirited defenses of it that put it as
competitive with real-world, battle-tested solutions are profoundly weird.

(Similarly, because I don't really care about JVM versus not, HAProxy--which
I'd probably use for something like this because I have better things to do
with my programming time--is 90Kloc because it _has stuff to do and does it
right_. Simple is only better if simple can actually get the job done.)

------
signa11
are there benchmarks also available ? may you please share them for objective
comparison with other implementations. thank you!

------
brudgers
If it meets the guidelines, this might make a good 'Show HN'. Show HN
guidelines:
[https://news.ycombinator.com/showhn.html](https://news.ycombinator.com/showhn.html)

~~~
shouldbworking
I felt kinda bad tearing it apart and only did so because it wasn't posted as
a ShowHN.

It's cool to show people an example of networking using Boost but the article
and post have no mention of this being alpha quality software.

~~~
brudgers
Maybe the author was proud of shipping.

