On Wed, 14 Mar 2018 11:58:46 -0700 Rio <m...@riobard.com> wrote:
> 
> While implementing a SOCKS proxy in Go, I ran into an issue which is better 
> explained in details by Evan Klitzke in this post 
> https://eklitzke.org/goroutines-nonblocking-io-and-memory-usage 
> 
> In my case, each proxied connection costs two goroutines and two buffers in 
> blocking read. For TCP connections the buffer size can be small (e.g. 2kb), 
> so the overhead per proxied TCP connection is 8kb (2 x 2kb goroutine stack 
> + 2 x 2kb read buffer). For UDP connections the buffer size must be large 
> enough to hold the largest packet due to the nature of packet-oriented 
> network, so the overhead per proxied UDP connection is 132kb (2 x 2kb 
> goroutine stack + 2 x 64kb read buffer for largest UDP packet). Handling 
> 10,000 UDP proxied connections requires at least 1.25GB memory, which is 
> unnecessary if there's a way to poll I/O readiness and use a shared read 
> buffer. 

You will need 10K*64KiB*2 = 1.22GiB kernel bufferspace at a
minimum in any case.  That is still one datagram's worth of
buffering per UDP socket so you can still lose some packets.
This is in addition to any user level buffering passd in to
recv() or read(). So you need at least 2.48GiB!

> I'm wondering if there's a better way other than calling 
> syscall.Epoll/Kqueue to create custom poller?

I did such a custom poller for a network proxy. It was a pain
to get right (I only did the Eww!poll version). In my case all
the traffic was via tcp. It has been a while now but IIRC my
reason was not to save memory but to gain flexibility over Go
runtime's networking. I don't remember the details now though.

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to