SO_REUSEADDR
- SO_REUSEADDR set or not
- socketA has already been successfully bound to the address
- bind to the address given for socketB
- result of the bind operation for socketB
SO_REUSEADDR | socketA | socketB | result |
---|---|---|---|
ON/OFF | 192.168.0.1:21 | 192.168.0.1:21 | Error (EADDRINUSE) |
ON/OFF | 192.168.0.1:21 | 10.0.0.1:21 | OK |
ON/OFF | 10.0.0.1:21 | 192.168.0.1:21 | OK |
OFF | 0.0.0.0:21 | 192.168.0.1:21 | Error (EADDRINUSE) |
OFF | 192.168.0.1:21 | 0.0.0.0:21 | Error (EADDRINUSE) |
ON | 0.0.0.0:21 | 192.168.0.1:21 | OK |
ON | 192.168.0.1:21 | 0.0.0.0:21 | OK |
ON/OFF | 0.0.0.0:21 | 0.0.0.0:21 | Error (EADDRINUSE) |
set SO_REUSEADDR to be able to bind
socketA | socketB | |
---|---|---|
TIME_WAIT (after "half dead") | ON | |
multicast | ON | ON |
TIME_WAIT
- until all pending data has been successfully sent
- until a timeout is hit
socket is closed forcefully
SO_REUSEPORT
SO_REUSEPORT (since Linux 3.9)
Permits multiple AF_INET or AF_INET6 sockets to be bound to an
identical socket address. This option must be set on each
socket (including the first socket) prior to calling bind(2)
on the socket. To prevent port hijacking, all of the
processes binding to the same address must have the same
effective UID. This option can be employed with both TCP and
UDP sockets.
sample code
socket set SO_REUSEPORT option
Linux kernel 3.9 の新機能 SO_REUSEPORT を試してみる
def listener_work(num):
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, SO_REUSEPORT, 1) # set SO_REUSEPORT
s.bind(("", PORT))
...
NGINX
Scaling NGINX Web Server Performance Socket Sharding Using SO REUSEPORT
reuseport
http {
server { listen 80 reuseport;
server_name localhost;
...
}
}
stream {
server { listen 12345 reuseport;
...
}
}