aboutsummaryrefslogtreecommitdiff
path: root/src/net.cpp
diff options
context:
space:
mode:
authorWladimir J. van der Laan <laanwj@gmail.com>2017-12-13 05:09:57 +0100
committerWladimir J. van der Laan <laanwj@gmail.com>2017-12-13 05:42:32 +0100
commitba2f19504c6b1302a93accbb50383f422c54df43 (patch)
tree4a373f3b1ade813c77d8cb67e63bc72870ea7cff /src/net.cpp
parentef8ba7d73a480197b756fab00126914e49de4e7b (diff)
parent3830b6e0659106458c941029f5b2e789e3cb38a3 (diff)
downloadbitcoin-ba2f19504c6b1302a93accbb50383f422c54df43.tar.xz
Merge #11363: net: Split socket create/connect
3830b6e net: use CreateSocket for binds (Cory Fields) df3bcf8 net: pass socket closing responsibility up to caller for outgoing connections (Cory Fields) 9e3b2f5 net: Move IsSelectableSocket check into socket creation (Cory Fields) 1729c29 net: split socket creation out of connection (Cory Fields) Pull request description: Requirement for #11227. We'll need to create sockets and perform the actual connect in separate steps, so break them up. #11227 adds an RAII wrapper around connection attempts, as a belt-and-suspenders in case a CloseSocket is missed. Tree-SHA512: de675bb718cc56d68893c303b8057ca062c7431eaa17ae7c4829caed119fa3f15b404d8f52aca22a6bca6e73a26fb79e898b335d090ab015bf6456cf417fc694
Diffstat (limited to 'src/net.cpp')
-rw-r--r--src/net.cpp70
1 files changed, 28 insertions, 42 deletions
diff --git a/src/net.cpp b/src/net.cpp
index c0f31e83dd..23bf640472 100644
--- a/src/net.cpp
+++ b/src/net.cpp
@@ -415,39 +415,48 @@ 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);
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()
@@ -2056,44 +2065,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()) {