Qual é a semântica de obter um EADDRINUSE quando nenhum soquete de escuta está vinculado, mas as conexões estão abertas

Qual é a semântica de obter um EADDRINUSE quando nenhum soquete de escuta está vinculado, mas as conexões estão abertas

Considere um processo pai que completa um socket/bind/accepte bifurcará os filhos com esse soquete aberto para eles se comunicarem, enquanto o pai continua aceitando conexões. Esse processo pai é então eliminado.

Outro processo agora tenta vincular-se ao mesmo endereço ao qual o processo pai estava vinculado, na mesma porta, mas recebe um erro EADDRINUSE.

No entanto, quando você conclui este processo com sshd, parecesshd écapaz de religar à porta que foi fechada, enquanto durante a janela de reinicialização (onde o processo pai sshd não está em execução), um programa diferente (executando como um usuário diferente) apenas obtém EADDRINUSE.

Qual é a semântica por trás disso? Por que pode ser sshdreligado, mas o processo de outro usuário não pode?

Além disso, posso confirmar que a netstat -a | grep PORTsaída durante o tempo em que apenas o processo filho está em execução (quando o outro processo não pode bind), a única conexão é ESTABLISHEDaquela, nenhuma no LISTENestado.

Responder1

Embora eu não entenda toda a semântica (ou estou procurando no lugar errado ou falta documentação), acredito que por um certo período de tempo após fechar uma conexão (talvez definida por SO_LINGER), nenhum processo pode abra um novo soquete com os mesmos detalhes, a menos que eles tenham sido SO_REUSEADDRconfigurados.

Isso evita que alguém se reconecte um segundo após o fechamento da conexão e o processo tenha que lidar com pacotes que foram destinados ao processo anterior, pelo que entendi.

man 7 socketnão documenta isso, o SO_REUSEADDRque tornou essa resposta difícil de descobrir.

informação relacionada