On Sun, Aug 25, 2013 at 7:20 AM, Amos Jeffries <squid3@xxxxxxxxxxxxx> wrote: >> Before digging deeper into the TPROXY kernel code, I'd like to clarify >> one aspect of squid's behaviour. Do you pass a port number (anything > >> 0) in inaddr.ai_addr during the bind call? Sorry, I couldn't trace it >> myself, as I didn't do much C/C++ programming since early 90's :-) >> >> Is it Squid or the kernel who decides what port to be used? > > > We pass the destination port:IP to connect() and then try to bind() to the > client IP on port 0 for source. The kernel decides which port is available, > then we retrieve its decision with getsockname(). > Tranced down the kernel issue with exhausting ports to inet_csk_get_port() in net/ipv4/inet_connection_sock.c. Seems the issue is not TPROXY related, but kicks in always when a socket bind is requested to an IP (local or foreign, doesn't matter) without specifying a port number. In this scenario the broken logic of the kernel is to take the difference between max and min of /proc/sys/net/ipv4/ip_local_port_range and use it as a cap of the number of automatically assigned ports. The counter of assigned ports is global, not per IP, this is what creates the issue. The good news is there's simple way to avoid this behaviour from the application itself - just provide a port number during bind and it works flawlessly. Then you can bind ip_local_port_range.max - ip_local_port_range.min + 1 per IP without any issue. Is it possible to make Squid assigning a port by itself before calling bind? User's original port seems to be an easy option in TPROXY mode. Best, Niki