Linux
socket

[Linux] note of SO_REUSEADDR & SO_REUSEPORT

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

04074715_KI9l.png

reuseport

http {
     server {          listen 80 reuseport;
          server_name  localhost;
          ...
     }
}

stream {
     server {          listen 12345 reuseport;
          ...
     }
}

04074715_Z1rt.png

ref.