From d32831d7e8549227176655da494f32aa6b77ac15 Mon Sep 17 00:00:00 2001 From: Howaner Date: Sat, 7 Feb 2015 11:03:38 +0100 Subject: Set reuse flag to sockets Should fix #1726 --- src/OSSupport/ServerHandleImpl.cpp | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) (limited to 'src/OSSupport/ServerHandleImpl.cpp') diff --git a/src/OSSupport/ServerHandleImpl.cpp b/src/OSSupport/ServerHandleImpl.cpp index 5fc5662e1..a3a08e84f 100644 --- a/src/OSSupport/ServerHandleImpl.cpp +++ b/src/OSSupport/ServerHandleImpl.cpp @@ -125,6 +125,17 @@ bool cServerHandleImpl::Listen(UInt16 a_Port) bool NeedsTwoSockets = false; int err; evutil_socket_t MainSock = socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP); + + // Set reuse flag + { + #if defined(_WIN32) || defined(ANDROID_NDK) + char yes = 1; + #else + int yes = 1; + #endif + setsockopt(MainSock, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)); + } + if (!IsValidSocket(MainSock)) { // Failed to create IPv6 socket, create an IPv4 one instead: @@ -193,6 +204,7 @@ bool cServerHandleImpl::Listen(UInt16 a_Port) } m_ConnListener = evconnlistener_new(cNetworkSingleton::Get().GetEventBase(), Callback, this, LEV_OPT_CLOSE_ON_FREE | LEV_OPT_REUSEABLE, 0, MainSock); m_IsListening = true; + if (!NeedsTwoSockets) { return true; @@ -201,6 +213,17 @@ bool cServerHandleImpl::Listen(UInt16 a_Port) // If a secondary socket is required (WinXP dual-stack), create it here: LOGD("Creating a second socket for IPv4"); evutil_socket_t SecondSock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + + // Set reuse flag + { + #if defined(_WIN32) || defined(ANDROID_NDK) + char yes = 1; + #else + int yes = 1; + #endif + setsockopt(SecondSock, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)); + } + if (!IsValidSocket(SecondSock)) { err = EVUTIL_SOCKET_ERROR(); @@ -233,7 +256,7 @@ bool cServerHandleImpl::Listen(UInt16 a_Port) if (listen(SecondSock, 0) != 0) { err = EVUTIL_SOCKET_ERROR(); - LOGD("Cannot listen on on secondary socket on port %d: %d (%s)", a_Port, err, evutil_socket_error_to_string(err)); + LOGD("Cannot listen on secondary socket on port %d: %d (%s)", a_Port, err, evutil_socket_error_to_string(err)); evutil_closesocket(SecondSock); return true; // Report as success, the primary socket is working } -- cgit v1.2.3 From be528a9f527e631181b590346d77eaaf64c914cd Mon Sep 17 00:00:00 2001 From: Howaner Date: Sat, 7 Feb 2015 18:39:24 +0100 Subject: Use evutil_make_listen_socket_reuseable --- src/OSSupport/ServerHandleImpl.cpp | 22 ++++++---------------- 1 file changed, 6 insertions(+), 16 deletions(-) (limited to 'src/OSSupport/ServerHandleImpl.cpp') diff --git a/src/OSSupport/ServerHandleImpl.cpp b/src/OSSupport/ServerHandleImpl.cpp index a3a08e84f..6f4343b1f 100644 --- a/src/OSSupport/ServerHandleImpl.cpp +++ b/src/OSSupport/ServerHandleImpl.cpp @@ -127,14 +127,9 @@ bool cServerHandleImpl::Listen(UInt16 a_Port) evutil_socket_t MainSock = socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP); // Set reuse flag - { - #if defined(_WIN32) || defined(ANDROID_NDK) - char yes = 1; - #else - int yes = 1; - #endif - setsockopt(MainSock, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)); - } + #if !defined(_WIN32) + evutil_make_listen_socket_reuseable(MainSock); + #endif if (!IsValidSocket(MainSock)) { @@ -215,14 +210,9 @@ bool cServerHandleImpl::Listen(UInt16 a_Port) evutil_socket_t SecondSock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); // Set reuse flag - { - #if defined(_WIN32) || defined(ANDROID_NDK) - char yes = 1; - #else - int yes = 1; - #endif - setsockopt(SecondSock, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)); - } + #if !defined(_WIN32) + evutil_make_listen_socket_reuseable(SecondSock); + #endif if (!IsValidSocket(SecondSock)) { -- cgit v1.2.3 From 81d7329ad31657e9e587dd7231be503ae1b157a9 Mon Sep 17 00:00:00 2001 From: Mattes D Date: Sun, 8 Feb 2015 14:41:24 +0100 Subject: ServerHandle: Fixed socket reuse. Fixes CID 104670, CID 104670 and CID 103724. --- src/OSSupport/ServerHandleImpl.cpp | 40 ++++++++++++++++++++++++++++---------- 1 file changed, 30 insertions(+), 10 deletions(-) (limited to 'src/OSSupport/ServerHandleImpl.cpp') diff --git a/src/OSSupport/ServerHandleImpl.cpp b/src/OSSupport/ServerHandleImpl.cpp index 6f4343b1f..72092df10 100644 --- a/src/OSSupport/ServerHandleImpl.cpp +++ b/src/OSSupport/ServerHandleImpl.cpp @@ -126,11 +126,6 @@ bool cServerHandleImpl::Listen(UInt16 a_Port) int err; evutil_socket_t MainSock = socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP); - // Set reuse flag - #if !defined(_WIN32) - evutil_make_listen_socket_reuseable(MainSock); - #endif - if (!IsValidSocket(MainSock)) { // Failed to create IPv6 socket, create an IPv4 one instead: @@ -144,6 +139,16 @@ bool cServerHandleImpl::Listen(UInt16 a_Port) return false; } + // Allow the port to be reused right after the socket closes: + if (evutil_make_listen_socket_reuseable(MainSock) != 0) + { + m_ErrorCode = EVUTIL_SOCKET_ERROR(); + Printf(m_ErrorMsg, "Port %d cannot be made reusable: %d (%s). Restarting the server might not work.", + a_Port, m_ErrorCode, evutil_socket_error_to_string(m_ErrorCode) + ); + LOG("%s", m_ErrorMsg.c_str()); + } + // Bind to all interfaces: sockaddr_in name; memset(&name, 0, sizeof(name)); @@ -170,6 +175,16 @@ bool cServerHandleImpl::Listen(UInt16 a_Port) setsockopt(MainSock, IPPROTO_IPV6, IPV6_V6ONLY, reinterpret_cast(&Zero), sizeof(Zero)); #endif + // Allow the port to be reused right after the socket closes: + if (evutil_make_listen_socket_reuseable(MainSock) != 0) + { + m_ErrorCode = EVUTIL_SOCKET_ERROR(); + Printf(m_ErrorMsg, "Port %d cannot be made reusable: %d (%s). Restarting the server might not work.", + a_Port, m_ErrorCode, evutil_socket_error_to_string(m_ErrorCode) + ); + LOG("%s", m_ErrorMsg.c_str()); + } + // Bind to all interfaces: sockaddr_in6 name; memset(&name, 0, sizeof(name)); @@ -209,11 +224,6 @@ bool cServerHandleImpl::Listen(UInt16 a_Port) LOGD("Creating a second socket for IPv4"); evutil_socket_t SecondSock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); - // Set reuse flag - #if !defined(_WIN32) - evutil_make_listen_socket_reuseable(SecondSock); - #endif - if (!IsValidSocket(SecondSock)) { err = EVUTIL_SOCKET_ERROR(); @@ -221,6 +231,16 @@ bool cServerHandleImpl::Listen(UInt16 a_Port) return true; // Report as success, the primary socket is working } + // Allow the port to be reused right after the socket closes: + if (evutil_make_listen_socket_reuseable(MainSock) != 0) + { + m_ErrorCode = EVUTIL_SOCKET_ERROR(); + Printf(m_ErrorMsg, "Port %d cannot be made reusable (second socket): %d (%s). Restarting the server might not work.", + a_Port, m_ErrorCode, evutil_socket_error_to_string(m_ErrorCode) + ); + LOG("%s", m_ErrorMsg.c_str()); + } + // Make the secondary socket nonblocking: if (evutil_make_socket_nonblocking(SecondSock) != 0) { -- cgit v1.2.3 From 612637ab2e3c6e63124053cce770bf406d06c742 Mon Sep 17 00:00:00 2001 From: Mattes D Date: Wed, 18 Feb 2015 09:34:33 +0100 Subject: Network: Fixed two-socket servers. --- src/OSSupport/ServerHandleImpl.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/OSSupport/ServerHandleImpl.cpp') diff --git a/src/OSSupport/ServerHandleImpl.cpp b/src/OSSupport/ServerHandleImpl.cpp index 72092df10..44ace448b 100644 --- a/src/OSSupport/ServerHandleImpl.cpp +++ b/src/OSSupport/ServerHandleImpl.cpp @@ -232,7 +232,7 @@ bool cServerHandleImpl::Listen(UInt16 a_Port) } // Allow the port to be reused right after the socket closes: - if (evutil_make_listen_socket_reuseable(MainSock) != 0) + if (evutil_make_listen_socket_reuseable(SecondSock) != 0) { m_ErrorCode = EVUTIL_SOCKET_ERROR(); Printf(m_ErrorMsg, "Port %d cannot be made reusable (second socket): %d (%s). Restarting the server might not work.", -- cgit v1.2.3