From 1729c29dedc64d900a1a1c686a56e16fa5417fa1 Mon Sep 17 00:00:00 2001 From: Cory Fields Date: Mon, 18 Sep 2017 18:45:51 -0400 Subject: net: split socket creation out of connection Also, check for the correct error during socket creation --- src/net.cpp | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) (limited to 'src/net.cpp') diff --git a/src/net.cpp b/src/net.cpp index 5eaeaab8f6..8f15842150 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -417,16 +417,30 @@ CNode* CConnman::ConnectNode(CAddress addrConnect, const char *pszDest, bool fCo if (addrConnect.IsValid()) { bool proxyConnectionFailed = false; - if (GetProxy(addrConnect.GetNetwork(), proxy)) + if (GetProxy(addrConnect.GetNetwork(), proxy)) { + hSocket = CreateSocket(proxy.proxy); + if (hSocket == INVALID_SOCKET) { + return nullptr; + } connected = ConnectThroughProxy(proxy, addrConnect.ToStringIP(), addrConnect.GetPort(), hSocket, nConnectTimeout, &proxyConnectionFailed); - else // no proxy needed (none set for target network) + } else { + // no proxy needed (none set for target network) + hSocket = CreateSocket(addrConnect); + if (hSocket == INVALID_SOCKET) { + return nullptr; + } connected = ConnectSocketDirectly(addrConnect, hSocket, nConnectTimeout); + } if (!proxyConnectionFailed) { // If a connection to the node was attempted, and failure (if any) is not caused by a problem connecting to // the proxy, mark this as an attempt. addrman.Attempt(addrConnect, fCountFailure); } } else if (pszDest && GetNameProxy(proxy)) { + hSocket = CreateSocket(proxy.proxy); + if (hSocket == INVALID_SOCKET) { + return nullptr; + } std::string host; int port = default_port; SplitHostPort(std::string(pszDest), port, host); -- cgit v1.2.3 From 9e3b2f576bb368a0857e808dcbd24b2dcb8bef2d Mon Sep 17 00:00:00 2001 From: Cory Fields Date: Mon, 2 Oct 2017 14:18:32 -0400 Subject: net: Move IsSelectableSocket check into socket creation We use select in ConnectSocketDirectly, so this check needs to happen before that. IsSelectableSocket will not be relevant after upcoming changes to remove select. --- src/net.cpp | 27 +++++++++++---------------- 1 file changed, 11 insertions(+), 16 deletions(-) (limited to 'src/net.cpp') diff --git a/src/net.cpp b/src/net.cpp index 8f15842150..07128a0349 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -446,24 +446,19 @@ CNode* CConnman::ConnectNode(CAddress addrConnect, const char *pszDest, bool fCo SplitHostPort(std::string(pszDest), port, host); connected = ConnectThroughProxy(proxy, host, port, hSocket, nConnectTimeout, nullptr); } - if (connected) { - if (!IsSelectableSocket(hSocket)) { - LogPrintf("Cannot create connection: non-selectable socket created (fd >= FD_SETSIZE ?)\n"); - CloseSocket(hSocket); - return nullptr; - } - - // Add node - NodeId id = GetNewNodeId(); - uint64_t nonce = GetDeterministicRandomizer(RANDOMIZER_ID_LOCALHOSTNONCE).Write(id).Finalize(); - CAddress addr_bind = GetBindAddress(hSocket); - CNode* pnode = new CNode(id, nLocalServices, GetBestHeight(), hSocket, addrConnect, CalculateKeyedNetGroup(addrConnect), nonce, addr_bind, pszDest ? pszDest : "", false); - pnode->AddRef(); - - return pnode; + if (!connected) { + CloseSocket(hSocket); + return nullptr; } - return nullptr; + // Add node + NodeId id = GetNewNodeId(); + uint64_t nonce = GetDeterministicRandomizer(RANDOMIZER_ID_LOCALHOSTNONCE).Write(id).Finalize(); + CAddress addr_bind = GetBindAddress(hSocket); + CNode* pnode = new CNode(id, nLocalServices, GetBestHeight(), hSocket, addrConnect, CalculateKeyedNetGroup(addrConnect), nonce, addr_bind, pszDest ? pszDest : "", false); + pnode->AddRef(); + + return pnode; } void CConnman::DumpBanlist() -- cgit v1.2.3 From 3830b6e0659106458c941029f5b2e789e3cb38a3 Mon Sep 17 00:00:00 2001 From: Cory Fields Date: Mon, 2 Oct 2017 16:31:37 -0400 Subject: net: use CreateSocket for binds --- src/net.cpp | 25 +------------------------ 1 file changed, 1 insertion(+), 24 deletions(-) (limited to 'src/net.cpp') diff --git a/src/net.cpp b/src/net.cpp index 07128a0349..8eb25a8c74 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -2078,44 +2078,21 @@ bool CConnman::BindListenPort(const CService &addrBind, std::string& strError, b return false; } - SOCKET hListenSocket = socket(((struct sockaddr*)&sockaddr)->sa_family, SOCK_STREAM, IPPROTO_TCP); + SOCKET hListenSocket = CreateSocket(addrBind); if (hListenSocket == INVALID_SOCKET) { strError = strprintf("Error: Couldn't open socket for incoming connections (socket returned error %s)", NetworkErrorString(WSAGetLastError())); LogPrintf("%s\n", strError); return false; } - if (!IsSelectableSocket(hListenSocket)) - { - strError = "Error: Couldn't create a listenable socket for incoming connections"; - LogPrintf("%s\n", strError); - return false; - } - - #ifndef WIN32 -#ifdef SO_NOSIGPIPE - // Different way of disabling SIGPIPE on BSD - setsockopt(hListenSocket, SOL_SOCKET, SO_NOSIGPIPE, (void*)&nOne, sizeof(int)); -#endif // Allow binding if the port is still in TIME_WAIT state after // the program was closed and restarted. setsockopt(hListenSocket, SOL_SOCKET, SO_REUSEADDR, (void*)&nOne, sizeof(int)); - // Disable Nagle's algorithm - setsockopt(hListenSocket, IPPROTO_TCP, TCP_NODELAY, (void*)&nOne, sizeof(int)); #else setsockopt(hListenSocket, SOL_SOCKET, SO_REUSEADDR, (const char*)&nOne, sizeof(int)); - setsockopt(hListenSocket, IPPROTO_TCP, TCP_NODELAY, (const char*)&nOne, sizeof(int)); #endif - // Set to non-blocking, incoming connections will also inherit this - if (!SetSocketNonBlocking(hListenSocket, true)) { - CloseSocket(hListenSocket); - strError = strprintf("BindListenPort: Setting listening socket to non-blocking failed, error %s\n", NetworkErrorString(WSAGetLastError())); - LogPrintf("%s\n", strError); - return false; - } - // some systems don't have IPV6_V6ONLY but are always v6only; others do have the option // and enable it by default or not. Try to enable it, if possible. if (addrBind.IsIPv6()) { -- cgit v1.2.3