diff --git a/common/os_calls.c b/common/os_calls.c index ac12cff8..b85260b0 100644 --- a/common/os_calls.c +++ b/common/os_calls.c @@ -402,8 +402,6 @@ int g_tcp_socket(void) { int rv; - int option_value; - socklen_t option_len; #if defined(XRDP_ENABLE_IPV6) rv = (int)socket(AF_INET6, SOCK_STREAM, 0); @@ -431,7 +429,8 @@ g_tcp_socket(void) return -1; } #if defined(XRDP_ENABLE_IPV6) - option_len = sizeof(option_value); + int option_value; + socklen_t option_len = sizeof(option_value); if (getsockopt(rv, IPPROTO_IPV6, IPV6_V6ONLY, (char *)&option_value, &option_len) == 0) { @@ -451,22 +450,6 @@ g_tcp_socket(void) } } #endif - option_len = sizeof(option_value); - if (getsockopt(rv, SOL_SOCKET, SO_REUSEADDR, (char *)&option_value, - &option_len) == 0) - { - if (option_value == 0) - { - option_value = 1; - option_len = sizeof(option_value); - if (setsockopt(rv, SOL_SOCKET, SO_REUSEADDR, (char *)&option_value, - option_len) < 0) - { - LOG(LOG_LEVEL_ERROR, "g_tcp_socket: setsockopt() failed"); - } - } - } - return rv; } @@ -544,6 +527,23 @@ g_sck_get_recv_buffer_bytes(int sck, int *bytes) return 0; } +/*****************************************************************************/ +int +g_sck_set_reuseaddr(int sck) +{ + int rv; + int option_value = 1; + socklen_t option_len = sizeof(option_value); + + rv = setsockopt(sck, SOL_SOCKET, SO_REUSEADDR, + (char *) &option_value, option_len); + if (rv < 0) + { + LOG(LOG_LEVEL_ERROR, "g_sck_set_reuseaddr: %s", g_get_strerror()); + } + return rv; +} + /*****************************************************************************/ int g_sck_local_socket(void) @@ -4122,30 +4122,7 @@ g_tcp4_socket(void) #if defined(XRDP_ENABLE_IPV6ONLY) return -1; #else - int rv; - int option_value; - socklen_t option_len; - - rv = socket(AF_INET, SOCK_STREAM, 0); - if (rv < 0) - { - return -1; - } - option_len = sizeof(option_value); - if (getsockopt(rv, SOL_SOCKET, SO_REUSEADDR, - (char *) &option_value, &option_len) == 0) - { - if (option_value == 0) - { - option_value = 1; - option_len = sizeof(option_value); - if (setsockopt(rv, SOL_SOCKET, SO_REUSEADDR, - (char *) &option_value, option_len) < 0) - { - } - } - } - return rv; + return socket(AF_INET, SOCK_STREAM, 0); #endif } @@ -4208,20 +4185,6 @@ g_tcp6_socket(void) } } } - option_len = sizeof(option_value); - if (getsockopt(rv, SOL_SOCKET, SO_REUSEADDR, - (char *) &option_value, &option_len) == 0) - { - if (option_value == 0) - { - option_value = 1; - option_len = sizeof(option_value); - if (setsockopt(rv, SOL_SOCKET, SO_REUSEADDR, - (char *) &option_value, option_len) < 0) - { - } - } - } return rv; #else return -1; diff --git a/common/os_calls.h b/common/os_calls.h index 6b09e070..dadf466c 100644 --- a/common/os_calls.h +++ b/common/os_calls.h @@ -74,6 +74,14 @@ int g_sck_set_send_buffer_bytes(int sck, int bytes); int g_sck_get_send_buffer_bytes(int sck, int *bytes); int g_sck_set_recv_buffer_bytes(int sck, int bytes); int g_sck_get_recv_buffer_bytes(int sck, int *bytes); +/** + * Set SO_REUSEADDR for a socket + * + * Use before binding, if appropriate. + * @param sck Socket + * @return 0 for success + */ +int g_sck_set_reuseaddr(int sck); int g_sck_local_socket(void); int g_sck_local_socketpair(int sck[2]); int g_sck_vsock_socket(void); diff --git a/common/trans.c b/common/trans.c index e08ed81b..a97f87c4 100644 --- a/common/trans.c +++ b/common/trans.c @@ -892,6 +892,7 @@ trans_listen_address(struct trans *self, const char *port, const char *address) g_file_set_cloexec(self->sck, 1); g_tcp_set_non_blocking(self->sck); + g_sck_set_reuseaddr(self->sck); if (g_tcp_bind_address(self->sck, port, address) == 0) { @@ -961,6 +962,7 @@ trans_listen_address(struct trans *self, const char *port, const char *address) } g_file_set_cloexec(self->sck, 1); g_tcp_set_non_blocking(self->sck); + g_sck_set_reuseaddr(self->sck); if (g_tcp4_bind_address(self->sck, port, address) == 0) { if (g_tcp_listen(self->sck) == 0) @@ -980,6 +982,7 @@ trans_listen_address(struct trans *self, const char *port, const char *address) } g_file_set_cloexec(self->sck, 1); g_tcp_set_non_blocking(self->sck); + g_sck_set_reuseaddr(self->sck); if (g_tcp6_bind_address(self->sck, port, address) == 0) { if (g_tcp_listen(self->sck) == 0) diff --git a/tools/devel/tcp_proxy/main.c b/tools/devel/tcp_proxy/main.c index 85505ebd..9d1c7f38 100644 --- a/tools/devel/tcp_proxy/main.c +++ b/tools/devel/tcp_proxy/main.c @@ -149,6 +149,7 @@ main_loop(char *local_port, char *remote_ip, char *remote_port, int hexdump) else { g_tcp_set_non_blocking(lis_sck); + g_sck_set_reuseaddr(lis_sck); error = g_tcp_bind(lis_sck, local_port); }