From 9b29b55e16b07a7b2dd39e6f3c0fd619b60fb7e0 Mon Sep 17 00:00:00 2001 From: Vivian Thiebaut Date: Tue, 17 Jan 2023 12:42:40 -0500 Subject: [PATCH 1/2] Stop setting SO_REUSEADDR option when creating socket to listen to port on forwarding scenarios --- channels.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/channels.c b/channels.c index 6b7d259a443..dd7338184a2 100644 --- a/channels.c +++ b/channels.c @@ -3683,8 +3683,18 @@ channel_setup_fwd_listener_tcpip(struct ssh *ssh, int type, strerror(errno)); continue; } - +#ifndef WINDOWS + /* + Setting the SO_REUSEADDR flag on a socket behaves differently on Windows than on *NIX OS. + On *NIX OS, the flag is used for handling specific edge cases and allows the tag to be reused + while busy only during TIME_WAIT state in the short period after termination. + On Windows, the option allows a socket to forcibly bind to a port in use by another socket in any + state. + This was allowing more than one socket to be created in the same port on Windows, which is + unnexpected behavior. + */ set_reuseaddr(sock); +#endif if (ai->ai_family == AF_INET6) sock_set_v6only(sock); From dcf8b97104bb0de020bba2e75e57ec760833884a Mon Sep 17 00:00:00 2001 From: Vivian Thiebaut Date: Mon, 23 Jan 2023 12:10:24 -0500 Subject: [PATCH 2/2] remove set_reuseaddr call on listen_on_addrs --- channels.c | 2 +- sshd.c | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/channels.c b/channels.c index dd7338184a2..e4c9c9f2edf 100644 --- a/channels.c +++ b/channels.c @@ -3686,7 +3686,7 @@ channel_setup_fwd_listener_tcpip(struct ssh *ssh, int type, #ifndef WINDOWS /* Setting the SO_REUSEADDR flag on a socket behaves differently on Windows than on *NIX OS. - On *NIX OS, the flag is used for handling specific edge cases and allows the tag to be reused + On *NIX OS, the flag is used for handling specific edge cases and allows the port to be reused while busy only during TIME_WAIT state in the short period after termination. On Windows, the option allows a socket to forcibly bind to a port in use by another socket in any state. diff --git a/sshd.c b/sshd.c index c209a9c241a..0df7e8a69cb 100644 --- a/sshd.c +++ b/sshd.c @@ -1472,7 +1472,9 @@ listen_on_addrs(struct listenaddr *la) continue; } /* Socket options */ +#ifndef WINDOWS set_reuseaddr(listen_sock); +#endif if (la->rdomain != NULL && set_rdomain(listen_sock, la->rdomain) == -1) { close(listen_sock);