Considere un proceso principal que completa un socket/bind/accept
y bifurcará a los niños con ese socket abierto para que se comuniquen, mientras el padre continúa aceptando conexiones. Luego, ese proceso principal se elimina.
Otro proceso ahora intenta vincularse a la misma dirección a la que estaba vinculado el proceso principal, en el mismo puerto, pero recibe un error EADDRINUSE.
Sin embargo, cuando completa este proceso con sshd
, parecesshd
escapaz de volver a vincularse al puerto que se cerró, mientras que durante la ventana de reinicio (donde el proceso principal sshd no se está ejecutando), un programa diferente (que se ejecuta como un usuario diferente) simplemente obtiene EADDRINUSE.
¿Cuál es la semántica detrás de esto? ¿Por qué se puede sshd
volver a vincular, pero el proceso de otro usuario no?
Además, puedo confirmar que la netstat -a | grep PORT
salida durante el tiempo en que solo se ejecuta el proceso secundario (cuando el otro proceso no puede bind
), la única conexión es la ESTABLISHED
única, ninguna en LISTEN
estado.
Respuesta1
Si bien no entiendo toda la semántica (estoy buscando en el lugar equivocado o falta la documentación), creo que durante un cierto período de tiempo después de cerrar una conexión (tal vez establecida por SO_LINGER
), ningún proceso puede Abra un nuevo enchufe con los mismos detalles a menos que se hayan SO_REUSEADDR
configurado.
Esto es para evitar que alguien se vuelva a conectar un segundo después de cerrar una conexión y que el proceso tenga que lidiar con paquetes que estaban destinados al proceso anterior, según tengo entendido.
man 7 socket
no documenta esto como parte de SO_REUSEADDR
lo que hizo que esta respuesta fuera difícil de entender.