mirror of
https://github.com/3proxy/3proxy.git
synced 2026-10-28 13:55:48 +08:00
Outgoing connections bound with IP_BIND_ADDRESS_NO_PORT
The socket of a connection to the destination is bound to the external address before connect(), with port 0 unless a range is given. bind() then takes an ephemeral port for the socket alone: not one in use towards another destination, nor one of a connection still closing in TIME_WAIT, which connect() would reuse. With many connections the range runs out and bind() fails, result 12, or searches long for a port: 7 ms a call was seen. The more connections are open at once, the sooner: with event loops, serving more of them at once, the client of every tenth connection or so of a saturated relay got its end at once. Where the system has IP_BIND_ADDRESS_NO_PORT (Linux 4.2), the port is left to connect() for a socket that is going to connect: chosen for the pair with the destination, together with IP_LOCAL_PORT_RANGE when a range is given. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
b56e5aff2b
commit
aaa36f1dd1
16
src/common.c
16
src/common.c
@ -780,6 +780,22 @@ int doconnect(struct clientparam * param){
|
||||
param->srv->so._setsockopt(param->sostate, param->remsock, SOL_SOCKET, SO_LINGER, (char *)&lg, sizeof(lg));
|
||||
#endif
|
||||
if(extbindtodevice(param, param->remsock)) return 12;
|
||||
#ifdef IP_BIND_ADDRESS_NO_PORT
|
||||
/* A port the kernel chooses is chosen by connect(), for the pair with
|
||||
the destination: one in use towards another destination, or closing
|
||||
from an earlier connection, does as well. bind() would take one of
|
||||
its own, and with many connections find none left, or search long
|
||||
for it. */
|
||||
if((param->operation >= 256 || (param->operation & CONNECT) || param->redirected)
|
||||
# ifdef WITH_UN
|
||||
&& *SAFAMILY(¶m->sinsl) != AF_UNIX
|
||||
# endif
|
||||
){
|
||||
int one = 1;
|
||||
|
||||
param->srv->so._setsockopt(param->sostate, param->remsock, IPPROTO_IP, IP_BIND_ADDRESS_NO_PORT, (char *)&one, sizeof(one));
|
||||
}
|
||||
#endif
|
||||
#ifdef WITH_UN
|
||||
if(*SAFAMILY(¶m->sinsl) != AF_UNIX)
|
||||
#endif
|
||||
|
||||
Loading…
Reference in New Issue
Block a user