From 433fb1a95d7a96a033d7454e198d274e92108865 Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Mon, 25 May 2015 20:03:51 +0200 Subject: [RPC] extend setban to allow subnets --- src/netbase.cpp | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'src/netbase.cpp') diff --git a/src/netbase.cpp b/src/netbase.cpp index e3cb4e706..b7c77fda6 100644 --- a/src/netbase.cpp +++ b/src/netbase.cpp @@ -1330,6 +1330,11 @@ bool operator!=(const CSubNet& a, const CSubNet& b) return !(a==b); } +bool operator<(const CSubNet& a, const CSubNet& b) +{ + return (a.network < b.network || (a.network == b.network && memcmp(a.netmask, b.netmask, 16))); +} + #ifdef WIN32 std::string NetworkErrorString(int err) { -- cgit v1.2.3 From d624167387a658c9b2c25ad13492262ccd2592bf Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Fri, 12 Jun 2015 19:51:50 +0200 Subject: fix CSubNet comparison operator --- src/netbase.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/netbase.cpp') diff --git a/src/netbase.cpp b/src/netbase.cpp index b7c77fda6..adac5c2d0 100644 --- a/src/netbase.cpp +++ b/src/netbase.cpp @@ -1332,7 +1332,7 @@ bool operator!=(const CSubNet& a, const CSubNet& b) bool operator<(const CSubNet& a, const CSubNet& b) { - return (a.network < b.network || (a.network == b.network && memcmp(a.netmask, b.netmask, 16))); + return (a.network < b.network || (a.network == b.network && memcmp(a.netmask, b.netmask, 16) < 0)); } #ifdef WIN32 -- cgit v1.2.3 From 177a0e491449b9accfa0cf17c138147539071358 Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Mon, 29 Jun 2015 20:37:22 +0200 Subject: Adding CSubNet constructor over a single CNetAddr --- src/netbase.cpp | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'src/netbase.cpp') diff --git a/src/netbase.cpp b/src/netbase.cpp index adac5c2d0..c9fc7d67f 100644 --- a/src/netbase.cpp +++ b/src/netbase.cpp @@ -1291,6 +1291,13 @@ CSubNet::CSubNet(const std::string &strSubnet, bool fAllowLookup) network.ip[x] &= netmask[x]; } +CSubNet::CSubNet(const CNetAddr &addr): + valid(addr.IsValid()) +{ + memset(netmask, 255, sizeof(netmask)); + network = addr; +} + bool CSubNet::Match(const CNetAddr &addr) const { if (!valid || !addr.IsValid()) -- cgit v1.2.3 From d422f9b1fdb42a51aadaa1bbc157542dca2feb17 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Thu, 9 Jul 2015 18:23:27 -0400 Subject: Test whether created sockets are select()able --- src/netbase.cpp | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/netbase.cpp') diff --git a/src/netbase.cpp b/src/netbase.cpp index c9fc7d67f..b7e2e5791 100644 --- a/src/netbase.cpp +++ b/src/netbase.cpp @@ -266,6 +266,9 @@ bool static InterruptibleRecv(char* data, size_t len, int timeout, SOCKET& hSock } else { // Other error or blocking int nErr = WSAGetLastError(); if (nErr == WSAEINPROGRESS || nErr == WSAEWOULDBLOCK || nErr == WSAEINVAL) { + if (!IsSelectableSocket(hSocket)) { + return false; + } struct timeval tval = MillisToTimeval(std::min(endTime - curTime, maxWait)); fd_set fdset; FD_ZERO(&fdset); -- cgit v1.2.3 From 9f68ed6b6d1a9c6436ce37913666165f2b180ee3 Mon Sep 17 00:00:00 2001 From: Veres Lajos Date: Sun, 9 Aug 2015 00:17:27 +0100 Subject: typofixes (found by misspell_fixer) --- src/netbase.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/netbase.cpp') diff --git a/src/netbase.cpp b/src/netbase.cpp index b7e2e5791..dec00e1ee 100644 --- a/src/netbase.cpp +++ b/src/netbase.cpp @@ -349,7 +349,7 @@ static bool Socks5(const std::string& strDest, int port, const ProxyCredentials } if (pchRetA[0] != 0x01 || pchRetA[1] != 0x00) { CloseSocket(hSocket); - return error("Proxy authentication unsuccesful"); + return error("Proxy authentication unsuccessful"); } } else if (pchRet1[1] == 0x00) { // Perform no authentication -- cgit v1.2.3 From bba3db1a40c2125c23a657e5f2d89e334037f792 Mon Sep 17 00:00:00 2001 From: Alex Morcos Date: Fri, 14 Aug 2015 14:23:37 -0500 Subject: Fix masking of irrelevant bits in address groups. --- src/netbase.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/netbase.cpp') diff --git a/src/netbase.cpp b/src/netbase.cpp index b7e2e5791..259e5c14a 100644 --- a/src/netbase.cpp +++ b/src/netbase.cpp @@ -983,7 +983,7 @@ std::vector CNetAddr::GetGroup() const nBits -= 8; } if (nBits > 0) - vchRet.push_back(GetByte(15 - nStartByte) | ((1 << nBits) - 1)); + vchRet.push_back(GetByte(15 - nStartByte) | ((1 << (8 - nBits)) - 1)); return vchRet; } -- cgit v1.2.3 From 607809f037950f114f64f1ee09c1486a3c66638b Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Tue, 23 Jun 2015 17:20:00 +0200 Subject: net: use CIDR notation in CSubNet::ToString() --- src/netbase.cpp | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) (limited to 'src/netbase.cpp') diff --git a/src/netbase.cpp b/src/netbase.cpp index 7a87d125c..4163b1808 100644 --- a/src/netbase.cpp +++ b/src/netbase.cpp @@ -1314,15 +1314,17 @@ bool CSubNet::Match(const CNetAddr &addr) const std::string CSubNet::ToString() const { std::string strNetmask; - if (network.IsIPv4()) - strNetmask = strprintf("%u.%u.%u.%u", netmask[12], netmask[13], netmask[14], netmask[15]); - else - strNetmask = strprintf("%x:%x:%x:%x:%x:%x:%x:%x", - netmask[0] << 8 | netmask[1], netmask[2] << 8 | netmask[3], - netmask[4] << 8 | netmask[5], netmask[6] << 8 | netmask[7], - netmask[8] << 8 | netmask[9], netmask[10] << 8 | netmask[11], - netmask[12] << 8 | netmask[13], netmask[14] << 8 | netmask[15]); - return network.ToString() + "/" + strNetmask; + int cidr = 0; + for (int n = network.IsIPv4() ? 12 : 0 ; n < 16; ++n) + { + uint8_t netmaskpart = netmask[n]; + while (netmaskpart) + { + cidr += ( netmaskpart & 0x01 ); + netmaskpart >>= 1; + } + } + return network.ToString() + strprintf("/%u", cidr); } bool CSubNet::IsValid() const -- cgit v1.2.3 From e2b8028e4c60708a8d49b17d9d49dda10aaecc51 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Thu, 25 Jun 2015 10:47:34 +0200 Subject: net: Fix CIDR notation in ToString() Only use CIDR notation if the netmask can be represented as such. --- src/netbase.cpp | 58 +++++++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 48 insertions(+), 10 deletions(-) (limited to 'src/netbase.cpp') diff --git a/src/netbase.cpp b/src/netbase.cpp index 4163b1808..c3d56d918 100644 --- a/src/netbase.cpp +++ b/src/netbase.cpp @@ -1311,20 +1311,58 @@ bool CSubNet::Match(const CNetAddr &addr) const return true; } +static inline int NetmaskBits(uint8_t x) +{ + switch(x) { + case 0x00: return 0; break; + case 0x80: return 1; break; + case 0xc0: return 2; break; + case 0xe0: return 3; break; + case 0xf0: return 4; break; + case 0xf8: return 5; break; + case 0xfc: return 6; break; + case 0xfe: return 7; break; + case 0xff: return 8; break; + default: return -1; break; + } +} + std::string CSubNet::ToString() const { - std::string strNetmask; + /* Parse binary 1{n}0{N-n} to see if mask can be represented as /n */ int cidr = 0; - for (int n = network.IsIPv4() ? 12 : 0 ; n < 16; ++n) - { - uint8_t netmaskpart = netmask[n]; - while (netmaskpart) - { - cidr += ( netmaskpart & 0x01 ); - netmaskpart >>= 1; - } + bool valid_cidr = true; + int n = network.IsIPv4() ? 12 : 0; + for (; n < 16 && netmask[n] == 0xff; ++n) + cidr += 8; + if (n < 16) { + int bits = NetmaskBits(netmask[n]); + if (bits < 0) + valid_cidr = false; + else + cidr += bits; + ++n; } - return network.ToString() + strprintf("/%u", cidr); + for (; n < 16 && valid_cidr; ++n) + if (netmask[n] != 0x00) + valid_cidr = false; + + /* Format output */ + std::string strNetmask; + if (valid_cidr) { + strNetmask = strprintf("%u", cidr); + } else { + if (network.IsIPv4()) + strNetmask = strprintf("%u.%u.%u.%u", netmask[12], netmask[13], netmask[14], netmask[15]); + else + strNetmask = strprintf("%x:%x:%x:%x:%x:%x:%x:%x", + netmask[0] << 8 | netmask[1], netmask[2] << 8 | netmask[3], + netmask[4] << 8 | netmask[5], netmask[6] << 8 | netmask[7], + netmask[8] << 8 | netmask[9], netmask[10] << 8 | netmask[11], + netmask[12] << 8 | netmask[13], netmask[14] << 8 | netmask[15]); + } + + return network.ToString() + "/" + strNetmask; } bool CSubNet::IsValid() const -- cgit v1.2.3 From a4e28b3d1e5c95eb0c87f144851cd65048c3e0bc Mon Sep 17 00:00:00 2001 From: Gregory Maxwell Date: Wed, 21 Oct 2015 23:52:29 +0000 Subject: Set TCP_NODELAY on P2P sockets. Nagle appears to be a significant contributor to latency now that the static sleeps are gone. Most of our messages are relatively large compared to IP + TCP so I do not expect this to create enormous overhead. This may also reduce traffic burstyness somewhat. --- src/netbase.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'src/netbase.cpp') diff --git a/src/netbase.cpp b/src/netbase.cpp index c3d56d918..f5316965c 100644 --- a/src/netbase.cpp +++ b/src/netbase.cpp @@ -444,12 +444,19 @@ bool static ConnectSocketDirectly(const CService &addrConnect, SOCKET& hSocketRe if (hSocket == INVALID_SOCKET) return false; -#ifdef SO_NOSIGPIPE int set = 1; +#ifdef SO_NOSIGPIPE // Different way of disabling SIGPIPE on BSD setsockopt(hSocket, SOL_SOCKET, SO_NOSIGPIPE, (void*)&set, sizeof(int)); #endif + //Disable Nagle's algorithm +#ifdef WIN32 + setsockopt(hSocket, IPPROTO_TCP, TCP_NODELAY, (const char*)&set, sizeof(int)); +#else + setsockopt(hSocket, IPPROTO_TCP, TCP_NODELAY, (void*)&set, sizeof(int)); +#endif + // Set to non-blocking if (!SetSocketNonBlocking(hSocket, true)) return error("ConnectSocketDirectly: Setting socket to non-blocking failed, error %s\n", NetworkErrorString(WSAGetLastError())); -- cgit v1.2.3 From 8f4e67f152a9625a1c66c20de00679286b2c187c Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Tue, 25 Aug 2015 20:12:08 +0200 Subject: net: Automatically create hidden service, listen on Tor Starting with Tor version 0.2.7.1 it is possible, through Tor's control socket API, to create and destroy 'ephemeral' hidden services programmatically. https://stem.torproject.org/api/control.html#stem.control.Controller.create_ephemeral_hidden_service This means that if Tor is running (and proper authorization is available), bitcoin automatically creates a hidden service to listen on, without user manual configuration. This will positively affect the number of available .onion nodes. - When the node is started, connect to Tor through control socket - Send `ADD_ONION` command - First time: - Make it create a hidden service key - Save the key in the data directory for later usage - Make it redirect port 8333 to the local port 8333 (or whatever port we're listening on). - Keep control socket connection open for as long node is running. The hidden service will (by default) automatically go away when the connection is closed. --- src/netbase.cpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'src/netbase.cpp') diff --git a/src/netbase.cpp b/src/netbase.cpp index f5316965c..83cedfb62 100644 --- a/src/netbase.cpp +++ b/src/netbase.cpp @@ -227,10 +227,7 @@ bool LookupNumeric(const char *pszName, CService& addr, int portDefault) return Lookup(pszName, addr, portDefault, false); } -/** - * Convert milliseconds to a struct timeval for select. - */ -struct timeval static MillisToTimeval(int64_t nTimeout) +struct timeval MillisToTimeval(int64_t nTimeout) { struct timeval timeout; timeout.tv_sec = nTimeout / 1000; -- cgit v1.2.3 From b966aa836a3bc5bfa1314248258308f0026d41bb Mon Sep 17 00:00:00 2001 From: Luke Dashjr Date: Sat, 27 Jun 2015 19:21:41 +0000 Subject: Constrain constant values to a single location in code --- src/netbase.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/netbase.cpp') diff --git a/src/netbase.cpp b/src/netbase.cpp index 83cedfb62..fa6598c1e 100644 --- a/src/netbase.cpp +++ b/src/netbase.cpp @@ -40,7 +40,7 @@ static proxyType proxyInfo[NET_MAX]; static proxyType nameProxy; static CCriticalSection cs_proxyInfos; int nConnectTimeout = DEFAULT_CONNECT_TIMEOUT; -bool fNameLookup = false; +bool fNameLookup = true; static const unsigned char pchIPv4[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff }; -- cgit v1.2.3 From faf93f37fe47fe326fcc4955302a66f24eb13b65 Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Mon, 9 Nov 2015 19:16:38 +0100 Subject: [trivial] Reuse translation and cleanup DEFAULT_* values * DEFAULT_DISABLE_SAFEMODE = false * Use DEFAULT_* constants for extern bools --- src/netbase.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/netbase.cpp') diff --git a/src/netbase.cpp b/src/netbase.cpp index fa6598c1e..05214cb02 100644 --- a/src/netbase.cpp +++ b/src/netbase.cpp @@ -40,7 +40,7 @@ static proxyType proxyInfo[NET_MAX]; static proxyType nameProxy; static CCriticalSection cs_proxyInfos; int nConnectTimeout = DEFAULT_CONNECT_TIMEOUT; -bool fNameLookup = true; +bool fNameLookup = DEFAULT_NAME_LOOKUP; static const unsigned char pchIPv4[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff }; -- cgit v1.2.3 From fa24439ff3d8ab5b9efaf66ef4dae6713b88cb35 Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Sun, 13 Dec 2015 17:58:29 +0100 Subject: Bump copyright headers to 2015 --- src/netbase.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/netbase.cpp') diff --git a/src/netbase.cpp b/src/netbase.cpp index 05214cb02..4e1f26760 100644 --- a/src/netbase.cpp +++ b/src/netbase.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. -- cgit v1.2.3 From 9d263bd17c2bdd5ba9e31bd5fb110c332eb80691 Mon Sep 17 00:00:00 2001 From: Chris Wheeler Date: Sun, 17 Jan 2016 11:03:56 +0000 Subject: Typo fixes in comments --- src/netbase.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/netbase.cpp') diff --git a/src/netbase.cpp b/src/netbase.cpp index 4e1f26760..7f79dd02c 100644 --- a/src/netbase.cpp +++ b/src/netbase.cpp @@ -140,7 +140,7 @@ bool static LookupIntern(const char *pszName, std::vector& vIP, unsign return false; do { - // Should set the timeout limit to a resonable value to avoid + // Should set the timeout limit to a reasonable value to avoid // generating unnecessary checking call during the polling loop, // while it can still response to stop request quick enough. // 2 seconds looks fine in our situation. -- cgit v1.2.3 From eda3d9248971a1c3df6e6c4b23ba89be30508b51 Mon Sep 17 00:00:00 2001 From: mruddy Date: Tue, 5 Apr 2016 22:26:38 +0000 Subject: Net: Add IPv6 Link-Local Address Support --- src/netbase.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'src/netbase.cpp') diff --git a/src/netbase.cpp b/src/netbase.cpp index 7f79dd02c..281c6bcb7 100644 --- a/src/netbase.cpp +++ b/src/netbase.cpp @@ -170,7 +170,8 @@ bool static LookupIntern(const char *pszName, std::vector& vIP, unsign if (aiTrav->ai_family == AF_INET6) { assert(aiTrav->ai_addrlen >= sizeof(sockaddr_in6)); - vIP.push_back(CNetAddr(((struct sockaddr_in6*)(aiTrav->ai_addr))->sin6_addr)); + struct sockaddr_in6* s6 = (struct sockaddr_in6*) aiTrav->ai_addr; + vIP.push_back(CNetAddr(s6->sin6_addr, s6->sin6_scope_id)); } aiTrav = aiTrav->ai_next; @@ -629,6 +630,7 @@ bool ConnectSocketByName(CService &addr, SOCKET& hSocketRet, const char *pszDest void CNetAddr::Init() { memset(ip, 0, sizeof(ip)); + scopeId = 0; } void CNetAddr::SetIP(const CNetAddr& ipIn) @@ -678,9 +680,10 @@ CNetAddr::CNetAddr(const struct in_addr& ipv4Addr) SetRaw(NET_IPV4, (const uint8_t*)&ipv4Addr); } -CNetAddr::CNetAddr(const struct in6_addr& ipv6Addr) +CNetAddr::CNetAddr(const struct in6_addr& ipv6Addr, const uint32_t scope) { SetRaw(NET_IPV6, (const uint8_t*)&ipv6Addr); + scopeId = scope; } CNetAddr::CNetAddr(const char *pszIp, bool fAllowLookup) @@ -1099,7 +1102,7 @@ CService::CService(const struct sockaddr_in& addr) : CNetAddr(addr.sin_addr), po assert(addr.sin_family == AF_INET); } -CService::CService(const struct sockaddr_in6 &addr) : CNetAddr(addr.sin6_addr), port(ntohs(addr.sin6_port)) +CService::CService(const struct sockaddr_in6 &addr) : CNetAddr(addr.sin6_addr, addr.sin6_scope_id), port(ntohs(addr.sin6_port)) { assert(addr.sin6_family == AF_INET6); } @@ -1192,6 +1195,7 @@ bool CService::GetSockAddr(struct sockaddr* paddr, socklen_t *addrlen) const memset(paddrin6, 0, *addrlen); if (!GetIn6Addr(&paddrin6->sin6_addr)) return false; + paddrin6->sin6_scope_id = scopeId; paddrin6->sin6_family = AF_INET6; paddrin6->sin6_port = htons(port); return true; -- cgit v1.2.3 From 367569926a9b15c05ba8d56c554880b8f5614f71 Mon Sep 17 00:00:00 2001 From: Cory Fields Date: Tue, 12 Apr 2016 20:41:39 -0400 Subject: net: resolve outside of storage structures Rather than allowing CNetAddr/CService/CSubNet to launch DNS queries, require that addresses are already resolved. This greatly simplifies async resolve logic, and makes it harder to accidentally leak DNS queries. --- src/netbase.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'src/netbase.cpp') diff --git a/src/netbase.cpp b/src/netbase.cpp index 281c6bcb7..1855d0a2e 100644 --- a/src/netbase.cpp +++ b/src/netbase.cpp @@ -614,10 +614,12 @@ bool ConnectSocketByName(CService &addr, SOCKET& hSocketRet, const char *pszDest proxyType nameProxy; GetNameProxy(nameProxy); - CService addrResolved(CNetAddr(strDest, fNameLookup && !HaveNameProxy()), port); - if (addrResolved.IsValid()) { - addr = addrResolved; - return ConnectSocket(addr, hSocketRet, nTimeout); + CService addrResolved; + if (Lookup(strDest.c_str(), addrResolved, port, fNameLookup && !HaveNameProxy())) { + if (addrResolved.IsValid()) { + addr = addrResolved; + return ConnectSocket(addr, hSocketRet, nTimeout); + } } addr = CService("0.0.0.0:0"); -- cgit v1.2.3 From d39f5b425d8fc1bf3b7f33d35625ffd8d7a3cd77 Mon Sep 17 00:00:00 2001 From: Cory Fields Date: Tue, 12 Apr 2016 20:48:29 -0400 Subject: net: disable resolving from storage structures CNetAddr/CService/CSubnet can no longer resolve DNS. --- src/netbase.cpp | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) (limited to 'src/netbase.cpp') diff --git a/src/netbase.cpp b/src/netbase.cpp index 1855d0a2e..b44a8b16e 100644 --- a/src/netbase.cpp +++ b/src/netbase.cpp @@ -688,19 +688,19 @@ CNetAddr::CNetAddr(const struct in6_addr& ipv6Addr, const uint32_t scope) scopeId = scope; } -CNetAddr::CNetAddr(const char *pszIp, bool fAllowLookup) +CNetAddr::CNetAddr(const char *pszIp) { Init(); std::vector vIP; - if (LookupHost(pszIp, vIP, 1, fAllowLookup)) + if (LookupHost(pszIp, vIP, 1, false)) *this = vIP[0]; } -CNetAddr::CNetAddr(const std::string &strIp, bool fAllowLookup) +CNetAddr::CNetAddr(const std::string &strIp) { Init(); std::vector vIP; - if (LookupHost(strIp.c_str(), vIP, 1, fAllowLookup)) + if (LookupHost(strIp.c_str(), vIP, 1, false)) *this = vIP[0]; } @@ -1123,35 +1123,35 @@ bool CService::SetSockAddr(const struct sockaddr *paddr) } } -CService::CService(const char *pszIpPort, bool fAllowLookup) +CService::CService(const char *pszIpPort) { Init(); CService ip; - if (Lookup(pszIpPort, ip, 0, fAllowLookup)) + if (Lookup(pszIpPort, ip, 0, false)) *this = ip; } -CService::CService(const char *pszIpPort, int portDefault, bool fAllowLookup) +CService::CService(const char *pszIpPort, int portDefault) { Init(); CService ip; - if (Lookup(pszIpPort, ip, portDefault, fAllowLookup)) + if (Lookup(pszIpPort, ip, portDefault, false)) *this = ip; } -CService::CService(const std::string &strIpPort, bool fAllowLookup) +CService::CService(const std::string &strIpPort) { Init(); CService ip; - if (Lookup(strIpPort.c_str(), ip, 0, fAllowLookup)) + if (Lookup(strIpPort.c_str(), ip, 0, false)) *this = ip; } -CService::CService(const std::string &strIpPort, int portDefault, bool fAllowLookup) +CService::CService(const std::string &strIpPort, int portDefault) { Init(); CService ip; - if (Lookup(strIpPort.c_str(), ip, portDefault, fAllowLookup)) + if (Lookup(strIpPort.c_str(), ip, portDefault, false)) *this = ip; } @@ -1245,7 +1245,7 @@ CSubNet::CSubNet(): memset(netmask, 0, sizeof(netmask)); } -CSubNet::CSubNet(const std::string &strSubnet, bool fAllowLookup) +CSubNet::CSubNet(const std::string &strSubnet) { size_t slash = strSubnet.find_last_of('/'); std::vector vIP; @@ -1255,7 +1255,7 @@ CSubNet::CSubNet(const std::string &strSubnet, bool fAllowLookup) memset(netmask, 255, sizeof(netmask)); std::string strAddress = strSubnet.substr(0, slash); - if (LookupHost(strAddress.c_str(), vIP, 1, fAllowLookup)) + if (LookupHost(strAddress.c_str(), vIP, 1, false)) { network = vIP[0]; if (slash != strSubnet.npos) -- cgit v1.2.3 From 00678bdb0aeb296456501f818faaa012a75ce18e Mon Sep 17 00:00:00 2001 From: Warren Togami Date: Mon, 9 May 2016 17:01:33 -0700 Subject: Make failures to connect via Socks5() more informative and less unnecessarily scary. * The "ERROR" was printed far too often during normal operation for what was not an error. * Makes the Socks5() connect failure similar to the IP connect failure in debug.log. Before: `2016-05-09 00:15:00 ERROR: Proxy error: host unreachable` After: `2016-05-09 00:15:00 Socks5() connect to t6xj6wilh4ytvcs7.onion:18333 failed: host unreachable"` --- src/netbase.cpp | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) (limited to 'src/netbase.cpp') diff --git a/src/netbase.cpp b/src/netbase.cpp index b44a8b16e..6e81fdcac 100644 --- a/src/netbase.cpp +++ b/src/netbase.cpp @@ -379,19 +379,21 @@ static bool Socks5(const std::string& strDest, int port, const ProxyCredentials return error("Proxy failed to accept request"); } if (pchRet2[1] != 0x00) { + // Failures to connect to a peer that are not proxy errors CloseSocket(hSocket); switch (pchRet2[1]) { - case 0x01: return error("Proxy error: general failure"); - case 0x02: return error("Proxy error: connection not allowed"); - case 0x03: return error("Proxy error: network unreachable"); - case 0x04: return error("Proxy error: host unreachable"); - case 0x05: return error("Proxy error: connection refused"); - case 0x06: return error("Proxy error: TTL expired"); - case 0x07: return error("Proxy error: protocol error"); - case 0x08: return error("Proxy error: address type not supported"); - default: return error("Proxy error: unknown"); + case 0x01: LogPrintf("Socks5() connect to %s:%d failed: general failure\n", strDest, port); break; + case 0x02: LogPrintf("Socks5() connect to %s:%d failed: connection not allowed\n", strDest, port); break; + case 0x03: LogPrintf("Socks5() connect to %s:%d failed: network unreachable\n", strDest, port); break; + case 0x04: LogPrintf("Socks5() connect to %s:%d failed: host unreachable\n", strDest, port); break; + case 0x05: LogPrintf("Socks5() connect to %s:%d failed: connection refused\n", strDest, port); break; + case 0x06: LogPrintf("Socks5() connect to %s:%d failed: TTL expired\n", strDest, port); break; + case 0x07: LogPrintf("Socks5() connect to %s:%d failed: protocol error\n", strDest, port); break; + case 0x08: LogPrintf("Socks5() connect to %s:%d failed: address type not supported\n", strDest, port); break; + default: LogPrintf("Socks5() connect to %s:%d failed: unknown\n", strDest, port); } + return false; } if (pchRet2[2] != 0x00) { CloseSocket(hSocket); -- cgit v1.2.3 From 0d9af79e5084dc2fb6a73abd9dd113dda4e993b4 Mon Sep 17 00:00:00 2001 From: Warren Togami Date: Mon, 9 May 2016 17:35:14 -0700 Subject: SOCKS5 connecting and connected messages with -debug=net. They were too noisy and not necessary for normal operation. --- src/netbase.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/netbase.cpp') diff --git a/src/netbase.cpp b/src/netbase.cpp index 6e81fdcac..5ab12c9a7 100644 --- a/src/netbase.cpp +++ b/src/netbase.cpp @@ -294,7 +294,7 @@ struct ProxyCredentials /** Connect using SOCKS5 (as described in RFC1928) */ static bool Socks5(const std::string& strDest, int port, const ProxyCredentials *auth, SOCKET& hSocket) { - LogPrintf("SOCKS5 connecting %s\n", strDest); + LogPrint("net", "SOCKS5 connecting %s\n", strDest); if (strDest.size() > 255) { CloseSocket(hSocket); return error("Hostname too long"); @@ -425,7 +425,7 @@ static bool Socks5(const std::string& strDest, int port, const ProxyCredentials CloseSocket(hSocket); return error("Error reading from proxy"); } - LogPrintf("SOCKS5 connected %s\n", strDest); + LogPrint("net", "SOCKS5 connected %s\n", strDest); return true; } -- cgit v1.2.3 From 94fd1d8d53adceb80e5a41cc6438c7704aeac0f7 Mon Sep 17 00:00:00 2001 From: Warren Togami Date: Tue, 17 May 2016 16:43:23 +0900 Subject: Make Socks5() InterruptibleRecv() timeout/failures informative. Before: 2016-05-16 06:10:45 ERROR: Error reading proxy response After: 2016-05-16 06:10:45 Socks5() connect to k7s5d6jqig4ej4v4.onion:18333 failed: InterruptibleRecv() timeout or other failure --- src/netbase.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/netbase.cpp') diff --git a/src/netbase.cpp b/src/netbase.cpp index 5ab12c9a7..d2a4188ff 100644 --- a/src/netbase.cpp +++ b/src/netbase.cpp @@ -318,7 +318,8 @@ static bool Socks5(const std::string& strDest, int port, const ProxyCredentials char pchRet1[2]; if (!InterruptibleRecv(pchRet1, 2, SOCKS5_RECV_TIMEOUT, hSocket)) { CloseSocket(hSocket); - return error("Error reading proxy response"); + LogPrintf("Socks5() connect to %s:%d failed: InterruptibleRecv() timeout or other failure\n", strDest, port); + return false; } if (pchRet1[0] != 0x05) { CloseSocket(hSocket); -- cgit v1.2.3 From bf9266e017b286c36e08fd09b91d9e39f14b2cf3 Mon Sep 17 00:00:00 2001 From: Warren Togami Date: Thu, 19 May 2016 14:19:08 +0900 Subject: Use Socks5ErrorString() to decode error responses from socks proxy. --- src/netbase.cpp | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) (limited to 'src/netbase.cpp') diff --git a/src/netbase.cpp b/src/netbase.cpp index d2a4188ff..572ae7087 100644 --- a/src/netbase.cpp +++ b/src/netbase.cpp @@ -291,6 +291,21 @@ struct ProxyCredentials std::string password; }; +std::string Socks5ErrorString(int err) +{ + switch(err) { + case 0x01: return "general failure"; + case 0x02: return "connection not allowed"; + case 0x03: return "network unreachable"; + case 0x04: return "host unreachable"; + case 0x05: return "connection refused"; + case 0x06: return "TTL expired"; + case 0x07: return "protocol error"; + case 0x08: return "address type not supported"; + default: return "unknown"; + } +} + /** Connect using SOCKS5 (as described in RFC1928) */ static bool Socks5(const std::string& strDest, int port, const ProxyCredentials *auth, SOCKET& hSocket) { @@ -382,18 +397,7 @@ static bool Socks5(const std::string& strDest, int port, const ProxyCredentials if (pchRet2[1] != 0x00) { // Failures to connect to a peer that are not proxy errors CloseSocket(hSocket); - switch (pchRet2[1]) - { - case 0x01: LogPrintf("Socks5() connect to %s:%d failed: general failure\n", strDest, port); break; - case 0x02: LogPrintf("Socks5() connect to %s:%d failed: connection not allowed\n", strDest, port); break; - case 0x03: LogPrintf("Socks5() connect to %s:%d failed: network unreachable\n", strDest, port); break; - case 0x04: LogPrintf("Socks5() connect to %s:%d failed: host unreachable\n", strDest, port); break; - case 0x05: LogPrintf("Socks5() connect to %s:%d failed: connection refused\n", strDest, port); break; - case 0x06: LogPrintf("Socks5() connect to %s:%d failed: TTL expired\n", strDest, port); break; - case 0x07: LogPrintf("Socks5() connect to %s:%d failed: protocol error\n", strDest, port); break; - case 0x08: LogPrintf("Socks5() connect to %s:%d failed: address type not supported\n", strDest, port); break; - default: LogPrintf("Socks5() connect to %s:%d failed: unknown\n", strDest, port); - } + LogPrintf("Socks5() connect to %s:%d failed: %s\n", strDest, port, Socks5ErrorString(pchRet2[1])); return false; } if (pchRet2[2] != 0x00) { -- cgit v1.2.3 From 1a5a4e648873c4cd88b936648ebf2858393e5510 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Sat, 28 May 2016 16:44:08 +0200 Subject: Randomize name lookup result in ConnectSocketByName --- src/netbase.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src/netbase.cpp') diff --git a/src/netbase.cpp b/src/netbase.cpp index 572ae7087..e2a516986 100644 --- a/src/netbase.cpp +++ b/src/netbase.cpp @@ -621,10 +621,10 @@ bool ConnectSocketByName(CService &addr, SOCKET& hSocketRet, const char *pszDest proxyType nameProxy; GetNameProxy(nameProxy); - CService addrResolved; - if (Lookup(strDest.c_str(), addrResolved, port, fNameLookup && !HaveNameProxy())) { - if (addrResolved.IsValid()) { - addr = addrResolved; + std::vector addrResolved; + if (Lookup(strDest.c_str(), addrResolved, port, fNameLookup && !HaveNameProxy(), 256)) { + if (addrResolved.size() > 0) { + addr = addrResolved[GetRand(addrResolved.size())]; return ConnectSocket(addr, hSocketRet, nTimeout); } } -- cgit v1.2.3 From 31d6b1d5f0414d8b356d8cb9c99961d8a04d6c0a Mon Sep 17 00:00:00 2001 From: Cory Fields Date: Tue, 31 May 2016 13:05:52 -0400 Subject: net: Split resolving out of CNetAddr --- src/netbase.cpp | 26 ++++++++++---------------- 1 file changed, 10 insertions(+), 16 deletions(-) (limited to 'src/netbase.cpp') diff --git a/src/netbase.cpp b/src/netbase.cpp index e2a516986..bb16dd043 100644 --- a/src/netbase.cpp +++ b/src/netbase.cpp @@ -195,6 +195,16 @@ bool LookupHost(const char *pszName, std::vector& vIP, unsigned int nM return LookupIntern(strHost.c_str(), vIP, nMaxSolutions, fAllowLookup); } +bool LookupHost(const char *pszName, CNetAddr& addr, bool fAllowLookup) +{ + std::vector vIP; + LookupHost(pszName, vIP, 1, fAllowLookup); + if(vIP.empty()) + return false; + addr = vIP.front(); + return true; +} + bool Lookup(const char *pszName, std::vector& vAddr, int portDefault, bool fAllowLookup, unsigned int nMaxSolutions) { if (pszName[0] == 0) @@ -695,22 +705,6 @@ CNetAddr::CNetAddr(const struct in6_addr& ipv6Addr, const uint32_t scope) scopeId = scope; } -CNetAddr::CNetAddr(const char *pszIp) -{ - Init(); - std::vector vIP; - if (LookupHost(pszIp, vIP, 1, false)) - *this = vIP[0]; -} - -CNetAddr::CNetAddr(const std::string &strIp) -{ - Init(); - std::vector vIP; - if (LookupHost(strIp.c_str(), vIP, 1, false)) - *this = vIP[0]; -} - unsigned int CNetAddr::GetByte(int n) const { return ip[15-n]; -- cgit v1.2.3 From f96c7c4d91f3c09d26658bc9c15aa561689fa2d4 Mon Sep 17 00:00:00 2001 From: Cory Fields Date: Tue, 31 May 2016 13:51:11 -0400 Subject: net: Split resolving out of CService --- src/netbase.cpp | 34 +--------------------------------- 1 file changed, 1 insertion(+), 33 deletions(-) (limited to 'src/netbase.cpp') diff --git a/src/netbase.cpp b/src/netbase.cpp index bb16dd043..2e7a4f758 100644 --- a/src/netbase.cpp +++ b/src/netbase.cpp @@ -639,7 +639,7 @@ bool ConnectSocketByName(CService &addr, SOCKET& hSocketRet, const char *pszDest } } - addr = CService("0.0.0.0:0"); + addr = CService(); if (!HaveNameProxy()) return false; @@ -1124,38 +1124,6 @@ bool CService::SetSockAddr(const struct sockaddr *paddr) } } -CService::CService(const char *pszIpPort) -{ - Init(); - CService ip; - if (Lookup(pszIpPort, ip, 0, false)) - *this = ip; -} - -CService::CService(const char *pszIpPort, int portDefault) -{ - Init(); - CService ip; - if (Lookup(pszIpPort, ip, portDefault, false)) - *this = ip; -} - -CService::CService(const std::string &strIpPort) -{ - Init(); - CService ip; - if (Lookup(strIpPort.c_str(), ip, 0, false)) - *this = ip; -} - -CService::CService(const std::string &strIpPort, int portDefault) -{ - Init(); - CService ip; - if (Lookup(strIpPort.c_str(), ip, portDefault, false)) - *this = ip; -} - unsigned short CService::GetPort() const { return port; -- cgit v1.2.3 From b6c3ff3daed432e71d1c5bfe2357c4bb9fdc862a Mon Sep 17 00:00:00 2001 From: Cory Fields Date: Tue, 31 May 2016 15:50:24 -0400 Subject: net: Split resolving out of CSubNet --- src/netbase.cpp | 94 +++++++++++++++++++++++++++++++++++---------------------- 1 file changed, 58 insertions(+), 36 deletions(-) (limited to 'src/netbase.cpp') diff --git a/src/netbase.cpp b/src/netbase.cpp index 2e7a4f758..52badcd98 100644 --- a/src/netbase.cpp +++ b/src/netbase.cpp @@ -1214,63 +1214,85 @@ CSubNet::CSubNet(): memset(netmask, 0, sizeof(netmask)); } -CSubNet::CSubNet(const std::string &strSubnet) +CSubNet::CSubNet(const CNetAddr &addr, int32_t mask) { - size_t slash = strSubnet.find_last_of('/'); - std::vector vIP; + valid = true; + network = addr; + // Default to /32 (IPv4) or /128 (IPv6), i.e. match single address + memset(netmask, 255, sizeof(netmask)); + // IPv4 addresses start at offset 12, and first 12 bytes must match, so just offset n + const int astartofs = network.IsIPv4() ? 12 : 0; + + int32_t n = mask; + if(n >= 0 && n <= (128 - astartofs*8)) // Only valid if in range of bits of address + { + n += astartofs*8; + // Clear bits [n..127] + for (; n < 128; ++n) + netmask[n>>3] &= ~(1<<(7-(n&7))); + } else + valid = false; + + // Normalize network according to netmask + for(int x=0; x<16; ++x) + network.ip[x] &= netmask[x]; +} + +CSubNet::CSubNet(const CNetAddr &addr, const CNetAddr &mask) +{ valid = true; + network = addr; // Default to /32 (IPv4) or /128 (IPv6), i.e. match single address memset(netmask, 255, sizeof(netmask)); + // IPv4 addresses start at offset 12, and first 12 bytes must match, so just offset n + const int astartofs = network.IsIPv4() ? 12 : 0; + + for(int x=astartofs; x<16; ++x) + netmask[x] = mask.ip[x]; + + // Normalize network according to netmask + for(int x=0; x<16; ++x) + network.ip[x] &= netmask[x]; +} + + +bool LookupSubNet(const char* pszName, CSubNet& ret) +{ + std::string strSubnet(pszName); + size_t slash = strSubnet.find_last_of('/'); + std::vector vIP; + std::string strAddress = strSubnet.substr(0, slash); if (LookupHost(strAddress.c_str(), vIP, 1, false)) { - network = vIP[0]; + CNetAddr network = vIP[0]; if (slash != strSubnet.npos) { std::string strNetmask = strSubnet.substr(slash + 1); int32_t n; // IPv4 addresses start at offset 12, and first 12 bytes must match, so just offset n - const int astartofs = network.IsIPv4() ? 12 : 0; - if (ParseInt32(strNetmask, &n)) // If valid number, assume /24 symtex - { - if(n >= 0 && n <= (128 - astartofs*8)) // Only valid if in range of bits of address - { - n += astartofs*8; - // Clear bits [n..127] - for (; n < 128; ++n) - netmask[n>>3] &= ~(1<<(7-(n&7))); - } - else - { - valid = false; - } + if (ParseInt32(strNetmask, &n)) { // If valid number, assume /24 syntax + ret = CSubNet(network, n); + return ret.IsValid(); } else // If not a valid number, try full netmask syntax { - if (LookupHost(strNetmask.c_str(), vIP, 1, false)) // Never allow lookup for netmask - { - // Copy only the *last* four bytes in case of IPv4, the rest of the mask should stay 1's as - // we don't want pchIPv4 to be part of the mask. - for(int x=astartofs; x<16; ++x) - netmask[x] = vIP[0].ip[x]; - } - else - { - valid = false; + // Never allow lookup for netmask + if (LookupHost(strNetmask.c_str(), vIP, 1, false)) { + ret = CSubNet(network, vIP[0]); + return ret.IsValid(); } } } + else + { + ret = CSubNet(network); + return ret.IsValid(); + } } - else - { - valid = false; - } - - // Normalize network according to netmask - for(int x=0; x<16; ++x) - network.ip[x] &= netmask[x]; + return false; } CSubNet::CSubNet(const CNetAddr &addr): -- cgit v1.2.3 From 21e5b96ff417f304e624052f629e2b030984180f Mon Sep 17 00:00:00 2001 From: Cory Fields Date: Tue, 31 May 2016 17:25:03 -0400 Subject: net: move CNetAddr/CService/CSubNet out of netbase --- src/netbase.cpp | 705 -------------------------------------------------------- 1 file changed, 705 deletions(-) (limited to 'src/netbase.cpp') diff --git a/src/netbase.cpp b/src/netbase.cpp index 52badcd98..c2294a078 100644 --- a/src/netbase.cpp +++ b/src/netbase.cpp @@ -42,8 +42,6 @@ static CCriticalSection cs_proxyInfos; int nConnectTimeout = DEFAULT_CONNECT_TIMEOUT; bool fNameLookup = DEFAULT_NAME_LOOKUP; -static const unsigned char pchIPv4[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff }; - // Need ample time for negotiation for very slow proxies such as Tor (milliseconds) static const int SOCKS5_RECV_TIMEOUT = 20 * 1000; @@ -646,618 +644,6 @@ bool ConnectSocketByName(CService &addr, SOCKET& hSocketRet, const char *pszDest return ConnectThroughProxy(nameProxy, strDest, port, hSocketRet, nTimeout, outProxyConnectionFailed); } -void CNetAddr::Init() -{ - memset(ip, 0, sizeof(ip)); - scopeId = 0; -} - -void CNetAddr::SetIP(const CNetAddr& ipIn) -{ - memcpy(ip, ipIn.ip, sizeof(ip)); -} - -void CNetAddr::SetRaw(Network network, const uint8_t *ip_in) -{ - switch(network) - { - case NET_IPV4: - memcpy(ip, pchIPv4, 12); - memcpy(ip+12, ip_in, 4); - break; - case NET_IPV6: - memcpy(ip, ip_in, 16); - break; - default: - assert(!"invalid network"); - } -} - -static const unsigned char pchOnionCat[] = {0xFD,0x87,0xD8,0x7E,0xEB,0x43}; - -bool CNetAddr::SetSpecial(const std::string &strName) -{ - if (strName.size()>6 && strName.substr(strName.size() - 6, 6) == ".onion") { - std::vector vchAddr = DecodeBase32(strName.substr(0, strName.size() - 6).c_str()); - if (vchAddr.size() != 16-sizeof(pchOnionCat)) - return false; - memcpy(ip, pchOnionCat, sizeof(pchOnionCat)); - for (unsigned int i=0; i<16-sizeof(pchOnionCat); i++) - ip[i + sizeof(pchOnionCat)] = vchAddr[i]; - return true; - } - return false; -} - -CNetAddr::CNetAddr() -{ - Init(); -} - -CNetAddr::CNetAddr(const struct in_addr& ipv4Addr) -{ - SetRaw(NET_IPV4, (const uint8_t*)&ipv4Addr); -} - -CNetAddr::CNetAddr(const struct in6_addr& ipv6Addr, const uint32_t scope) -{ - SetRaw(NET_IPV6, (const uint8_t*)&ipv6Addr); - scopeId = scope; -} - -unsigned int CNetAddr::GetByte(int n) const -{ - return ip[15-n]; -} - -bool CNetAddr::IsIPv4() const -{ - return (memcmp(ip, pchIPv4, sizeof(pchIPv4)) == 0); -} - -bool CNetAddr::IsIPv6() const -{ - return (!IsIPv4() && !IsTor()); -} - -bool CNetAddr::IsRFC1918() const -{ - return IsIPv4() && ( - GetByte(3) == 10 || - (GetByte(3) == 192 && GetByte(2) == 168) || - (GetByte(3) == 172 && (GetByte(2) >= 16 && GetByte(2) <= 31))); -} - -bool CNetAddr::IsRFC2544() const -{ - return IsIPv4() && GetByte(3) == 198 && (GetByte(2) == 18 || GetByte(2) == 19); -} - -bool CNetAddr::IsRFC3927() const -{ - return IsIPv4() && (GetByte(3) == 169 && GetByte(2) == 254); -} - -bool CNetAddr::IsRFC6598() const -{ - return IsIPv4() && GetByte(3) == 100 && GetByte(2) >= 64 && GetByte(2) <= 127; -} - -bool CNetAddr::IsRFC5737() const -{ - return IsIPv4() && ((GetByte(3) == 192 && GetByte(2) == 0 && GetByte(1) == 2) || - (GetByte(3) == 198 && GetByte(2) == 51 && GetByte(1) == 100) || - (GetByte(3) == 203 && GetByte(2) == 0 && GetByte(1) == 113)); -} - -bool CNetAddr::IsRFC3849() const -{ - return GetByte(15) == 0x20 && GetByte(14) == 0x01 && GetByte(13) == 0x0D && GetByte(12) == 0xB8; -} - -bool CNetAddr::IsRFC3964() const -{ - return (GetByte(15) == 0x20 && GetByte(14) == 0x02); -} - -bool CNetAddr::IsRFC6052() const -{ - static const unsigned char pchRFC6052[] = {0,0x64,0xFF,0x9B,0,0,0,0,0,0,0,0}; - return (memcmp(ip, pchRFC6052, sizeof(pchRFC6052)) == 0); -} - -bool CNetAddr::IsRFC4380() const -{ - return (GetByte(15) == 0x20 && GetByte(14) == 0x01 && GetByte(13) == 0 && GetByte(12) == 0); -} - -bool CNetAddr::IsRFC4862() const -{ - static const unsigned char pchRFC4862[] = {0xFE,0x80,0,0,0,0,0,0}; - return (memcmp(ip, pchRFC4862, sizeof(pchRFC4862)) == 0); -} - -bool CNetAddr::IsRFC4193() const -{ - return ((GetByte(15) & 0xFE) == 0xFC); -} - -bool CNetAddr::IsRFC6145() const -{ - static const unsigned char pchRFC6145[] = {0,0,0,0,0,0,0,0,0xFF,0xFF,0,0}; - return (memcmp(ip, pchRFC6145, sizeof(pchRFC6145)) == 0); -} - -bool CNetAddr::IsRFC4843() const -{ - return (GetByte(15) == 0x20 && GetByte(14) == 0x01 && GetByte(13) == 0x00 && (GetByte(12) & 0xF0) == 0x10); -} - -bool CNetAddr::IsTor() const -{ - return (memcmp(ip, pchOnionCat, sizeof(pchOnionCat)) == 0); -} - -bool CNetAddr::IsLocal() const -{ - // IPv4 loopback - if (IsIPv4() && (GetByte(3) == 127 || GetByte(3) == 0)) - return true; - - // IPv6 loopback (::1/128) - static const unsigned char pchLocal[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1}; - if (memcmp(ip, pchLocal, 16) == 0) - return true; - - return false; -} - -bool CNetAddr::IsMulticast() const -{ - return (IsIPv4() && (GetByte(3) & 0xF0) == 0xE0) - || (GetByte(15) == 0xFF); -} - -bool CNetAddr::IsValid() const -{ - // Cleanup 3-byte shifted addresses caused by garbage in size field - // of addr messages from versions before 0.2.9 checksum. - // Two consecutive addr messages look like this: - // header20 vectorlen3 addr26 addr26 addr26 header20 vectorlen3 addr26 addr26 addr26... - // so if the first length field is garbled, it reads the second batch - // of addr misaligned by 3 bytes. - if (memcmp(ip, pchIPv4+3, sizeof(pchIPv4)-3) == 0) - return false; - - // unspecified IPv6 address (::/128) - unsigned char ipNone[16] = {}; - if (memcmp(ip, ipNone, 16) == 0) - return false; - - // documentation IPv6 address - if (IsRFC3849()) - return false; - - if (IsIPv4()) - { - // INADDR_NONE - uint32_t ipNone = INADDR_NONE; - if (memcmp(ip+12, &ipNone, 4) == 0) - return false; - - // 0 - ipNone = 0; - if (memcmp(ip+12, &ipNone, 4) == 0) - return false; - } - - return true; -} - -bool CNetAddr::IsRoutable() const -{ - return IsValid() && !(IsRFC1918() || IsRFC2544() || IsRFC3927() || IsRFC4862() || IsRFC6598() || IsRFC5737() || (IsRFC4193() && !IsTor()) || IsRFC4843() || IsLocal()); -} - -enum Network CNetAddr::GetNetwork() const -{ - if (!IsRoutable()) - return NET_UNROUTABLE; - - if (IsIPv4()) - return NET_IPV4; - - if (IsTor()) - return NET_TOR; - - return NET_IPV6; -} - -std::string CNetAddr::ToStringIP() const -{ - if (IsTor()) - return EncodeBase32(&ip[6], 10) + ".onion"; - CService serv(*this, 0); - struct sockaddr_storage sockaddr; - socklen_t socklen = sizeof(sockaddr); - if (serv.GetSockAddr((struct sockaddr*)&sockaddr, &socklen)) { - char name[1025] = ""; - if (!getnameinfo((const struct sockaddr*)&sockaddr, socklen, name, sizeof(name), NULL, 0, NI_NUMERICHOST)) - return std::string(name); - } - if (IsIPv4()) - return strprintf("%u.%u.%u.%u", GetByte(3), GetByte(2), GetByte(1), GetByte(0)); - else - return strprintf("%x:%x:%x:%x:%x:%x:%x:%x", - GetByte(15) << 8 | GetByte(14), GetByte(13) << 8 | GetByte(12), - GetByte(11) << 8 | GetByte(10), GetByte(9) << 8 | GetByte(8), - GetByte(7) << 8 | GetByte(6), GetByte(5) << 8 | GetByte(4), - GetByte(3) << 8 | GetByte(2), GetByte(1) << 8 | GetByte(0)); -} - -std::string CNetAddr::ToString() const -{ - return ToStringIP(); -} - -bool operator==(const CNetAddr& a, const CNetAddr& b) -{ - return (memcmp(a.ip, b.ip, 16) == 0); -} - -bool operator!=(const CNetAddr& a, const CNetAddr& b) -{ - return (memcmp(a.ip, b.ip, 16) != 0); -} - -bool operator<(const CNetAddr& a, const CNetAddr& b) -{ - return (memcmp(a.ip, b.ip, 16) < 0); -} - -bool CNetAddr::GetInAddr(struct in_addr* pipv4Addr) const -{ - if (!IsIPv4()) - return false; - memcpy(pipv4Addr, ip+12, 4); - return true; -} - -bool CNetAddr::GetIn6Addr(struct in6_addr* pipv6Addr) const -{ - memcpy(pipv6Addr, ip, 16); - return true; -} - -// get canonical identifier of an address' group -// no two connections will be attempted to addresses with the same group -std::vector CNetAddr::GetGroup() const -{ - std::vector vchRet; - int nClass = NET_IPV6; - int nStartByte = 0; - int nBits = 16; - - // all local addresses belong to the same group - if (IsLocal()) - { - nClass = 255; - nBits = 0; - } - - // all unroutable addresses belong to the same group - if (!IsRoutable()) - { - nClass = NET_UNROUTABLE; - nBits = 0; - } - // for IPv4 addresses, '1' + the 16 higher-order bits of the IP - // includes mapped IPv4, SIIT translated IPv4, and the well-known prefix - else if (IsIPv4() || IsRFC6145() || IsRFC6052()) - { - nClass = NET_IPV4; - nStartByte = 12; - } - // for 6to4 tunnelled addresses, use the encapsulated IPv4 address - else if (IsRFC3964()) - { - nClass = NET_IPV4; - nStartByte = 2; - } - // for Teredo-tunnelled IPv6 addresses, use the encapsulated IPv4 address - else if (IsRFC4380()) - { - vchRet.push_back(NET_IPV4); - vchRet.push_back(GetByte(3) ^ 0xFF); - vchRet.push_back(GetByte(2) ^ 0xFF); - return vchRet; - } - else if (IsTor()) - { - nClass = NET_TOR; - nStartByte = 6; - nBits = 4; - } - // for he.net, use /36 groups - else if (GetByte(15) == 0x20 && GetByte(14) == 0x01 && GetByte(13) == 0x04 && GetByte(12) == 0x70) - nBits = 36; - // for the rest of the IPv6 network, use /32 groups - else - nBits = 32; - - vchRet.push_back(nClass); - while (nBits >= 8) - { - vchRet.push_back(GetByte(15 - nStartByte)); - nStartByte++; - nBits -= 8; - } - if (nBits > 0) - vchRet.push_back(GetByte(15 - nStartByte) | ((1 << (8 - nBits)) - 1)); - - return vchRet; -} - -uint64_t CNetAddr::GetHash() const -{ - uint256 hash = Hash(&ip[0], &ip[16]); - uint64_t nRet; - memcpy(&nRet, &hash, sizeof(nRet)); - return nRet; -} - -// private extensions to enum Network, only returned by GetExtNetwork, -// and only used in GetReachabilityFrom -static const int NET_UNKNOWN = NET_MAX + 0; -static const int NET_TEREDO = NET_MAX + 1; -int static GetExtNetwork(const CNetAddr *addr) -{ - if (addr == NULL) - return NET_UNKNOWN; - if (addr->IsRFC4380()) - return NET_TEREDO; - return addr->GetNetwork(); -} - -/** Calculates a metric for how reachable (*this) is from a given partner */ -int CNetAddr::GetReachabilityFrom(const CNetAddr *paddrPartner) const -{ - enum Reachability { - REACH_UNREACHABLE, - REACH_DEFAULT, - REACH_TEREDO, - REACH_IPV6_WEAK, - REACH_IPV4, - REACH_IPV6_STRONG, - REACH_PRIVATE - }; - - if (!IsRoutable()) - return REACH_UNREACHABLE; - - int ourNet = GetExtNetwork(this); - int theirNet = GetExtNetwork(paddrPartner); - bool fTunnel = IsRFC3964() || IsRFC6052() || IsRFC6145(); - - switch(theirNet) { - case NET_IPV4: - switch(ourNet) { - default: return REACH_DEFAULT; - case NET_IPV4: return REACH_IPV4; - } - case NET_IPV6: - switch(ourNet) { - default: return REACH_DEFAULT; - case NET_TEREDO: return REACH_TEREDO; - case NET_IPV4: return REACH_IPV4; - case NET_IPV6: return fTunnel ? REACH_IPV6_WEAK : REACH_IPV6_STRONG; // only prefer giving our IPv6 address if it's not tunnelled - } - case NET_TOR: - switch(ourNet) { - default: return REACH_DEFAULT; - case NET_IPV4: return REACH_IPV4; // Tor users can connect to IPv4 as well - case NET_TOR: return REACH_PRIVATE; - } - case NET_TEREDO: - switch(ourNet) { - default: return REACH_DEFAULT; - case NET_TEREDO: return REACH_TEREDO; - case NET_IPV6: return REACH_IPV6_WEAK; - case NET_IPV4: return REACH_IPV4; - } - case NET_UNKNOWN: - case NET_UNROUTABLE: - default: - switch(ourNet) { - default: return REACH_DEFAULT; - case NET_TEREDO: return REACH_TEREDO; - case NET_IPV6: return REACH_IPV6_WEAK; - case NET_IPV4: return REACH_IPV4; - case NET_TOR: return REACH_PRIVATE; // either from Tor, or don't care about our address - } - } -} - -void CService::Init() -{ - port = 0; -} - -CService::CService() -{ - Init(); -} - -CService::CService(const CNetAddr& cip, unsigned short portIn) : CNetAddr(cip), port(portIn) -{ -} - -CService::CService(const struct in_addr& ipv4Addr, unsigned short portIn) : CNetAddr(ipv4Addr), port(portIn) -{ -} - -CService::CService(const struct in6_addr& ipv6Addr, unsigned short portIn) : CNetAddr(ipv6Addr), port(portIn) -{ -} - -CService::CService(const struct sockaddr_in& addr) : CNetAddr(addr.sin_addr), port(ntohs(addr.sin_port)) -{ - assert(addr.sin_family == AF_INET); -} - -CService::CService(const struct sockaddr_in6 &addr) : CNetAddr(addr.sin6_addr, addr.sin6_scope_id), port(ntohs(addr.sin6_port)) -{ - assert(addr.sin6_family == AF_INET6); -} - -bool CService::SetSockAddr(const struct sockaddr *paddr) -{ - switch (paddr->sa_family) { - case AF_INET: - *this = CService(*(const struct sockaddr_in*)paddr); - return true; - case AF_INET6: - *this = CService(*(const struct sockaddr_in6*)paddr); - return true; - default: - return false; - } -} - -unsigned short CService::GetPort() const -{ - return port; -} - -bool operator==(const CService& a, const CService& b) -{ - return (CNetAddr)a == (CNetAddr)b && a.port == b.port; -} - -bool operator!=(const CService& a, const CService& b) -{ - return (CNetAddr)a != (CNetAddr)b || a.port != b.port; -} - -bool operator<(const CService& a, const CService& b) -{ - return (CNetAddr)a < (CNetAddr)b || ((CNetAddr)a == (CNetAddr)b && a.port < b.port); -} - -bool CService::GetSockAddr(struct sockaddr* paddr, socklen_t *addrlen) const -{ - if (IsIPv4()) { - if (*addrlen < (socklen_t)sizeof(struct sockaddr_in)) - return false; - *addrlen = sizeof(struct sockaddr_in); - struct sockaddr_in *paddrin = (struct sockaddr_in*)paddr; - memset(paddrin, 0, *addrlen); - if (!GetInAddr(&paddrin->sin_addr)) - return false; - paddrin->sin_family = AF_INET; - paddrin->sin_port = htons(port); - return true; - } - if (IsIPv6()) { - if (*addrlen < (socklen_t)sizeof(struct sockaddr_in6)) - return false; - *addrlen = sizeof(struct sockaddr_in6); - struct sockaddr_in6 *paddrin6 = (struct sockaddr_in6*)paddr; - memset(paddrin6, 0, *addrlen); - if (!GetIn6Addr(&paddrin6->sin6_addr)) - return false; - paddrin6->sin6_scope_id = scopeId; - paddrin6->sin6_family = AF_INET6; - paddrin6->sin6_port = htons(port); - return true; - } - return false; -} - -std::vector CService::GetKey() const -{ - std::vector vKey; - vKey.resize(18); - memcpy(&vKey[0], ip, 16); - vKey[16] = port / 0x100; - vKey[17] = port & 0x0FF; - return vKey; -} - -std::string CService::ToStringPort() const -{ - return strprintf("%u", port); -} - -std::string CService::ToStringIPPort() const -{ - if (IsIPv4() || IsTor()) { - return ToStringIP() + ":" + ToStringPort(); - } else { - return "[" + ToStringIP() + "]:" + ToStringPort(); - } -} - -std::string CService::ToString() const -{ - return ToStringIPPort(); -} - -void CService::SetPort(unsigned short portIn) -{ - port = portIn; -} - -CSubNet::CSubNet(): - valid(false) -{ - memset(netmask, 0, sizeof(netmask)); -} - -CSubNet::CSubNet(const CNetAddr &addr, int32_t mask) -{ - valid = true; - network = addr; - // Default to /32 (IPv4) or /128 (IPv6), i.e. match single address - memset(netmask, 255, sizeof(netmask)); - - // IPv4 addresses start at offset 12, and first 12 bytes must match, so just offset n - const int astartofs = network.IsIPv4() ? 12 : 0; - - int32_t n = mask; - if(n >= 0 && n <= (128 - astartofs*8)) // Only valid if in range of bits of address - { - n += astartofs*8; - // Clear bits [n..127] - for (; n < 128; ++n) - netmask[n>>3] &= ~(1<<(7-(n&7))); - } else - valid = false; - - // Normalize network according to netmask - for(int x=0; x<16; ++x) - network.ip[x] &= netmask[x]; -} - -CSubNet::CSubNet(const CNetAddr &addr, const CNetAddr &mask) -{ - valid = true; - network = addr; - // Default to /32 (IPv4) or /128 (IPv6), i.e. match single address - memset(netmask, 255, sizeof(netmask)); - - // IPv4 addresses start at offset 12, and first 12 bytes must match, so just offset n - const int astartofs = network.IsIPv4() ? 12 : 0; - - for(int x=astartofs; x<16; ++x) - netmask[x] = mask.ip[x]; - - // Normalize network according to netmask - for(int x=0; x<16; ++x) - network.ip[x] &= netmask[x]; -} - - bool LookupSubNet(const char* pszName, CSubNet& ret) { std::string strSubnet(pszName); @@ -1295,97 +681,6 @@ bool LookupSubNet(const char* pszName, CSubNet& ret) return false; } -CSubNet::CSubNet(const CNetAddr &addr): - valid(addr.IsValid()) -{ - memset(netmask, 255, sizeof(netmask)); - network = addr; -} - -bool CSubNet::Match(const CNetAddr &addr) const -{ - if (!valid || !addr.IsValid()) - return false; - for(int x=0; x<16; ++x) - if ((addr.ip[x] & netmask[x]) != network.ip[x]) - return false; - return true; -} - -static inline int NetmaskBits(uint8_t x) -{ - switch(x) { - case 0x00: return 0; break; - case 0x80: return 1; break; - case 0xc0: return 2; break; - case 0xe0: return 3; break; - case 0xf0: return 4; break; - case 0xf8: return 5; break; - case 0xfc: return 6; break; - case 0xfe: return 7; break; - case 0xff: return 8; break; - default: return -1; break; - } -} - -std::string CSubNet::ToString() const -{ - /* Parse binary 1{n}0{N-n} to see if mask can be represented as /n */ - int cidr = 0; - bool valid_cidr = true; - int n = network.IsIPv4() ? 12 : 0; - for (; n < 16 && netmask[n] == 0xff; ++n) - cidr += 8; - if (n < 16) { - int bits = NetmaskBits(netmask[n]); - if (bits < 0) - valid_cidr = false; - else - cidr += bits; - ++n; - } - for (; n < 16 && valid_cidr; ++n) - if (netmask[n] != 0x00) - valid_cidr = false; - - /* Format output */ - std::string strNetmask; - if (valid_cidr) { - strNetmask = strprintf("%u", cidr); - } else { - if (network.IsIPv4()) - strNetmask = strprintf("%u.%u.%u.%u", netmask[12], netmask[13], netmask[14], netmask[15]); - else - strNetmask = strprintf("%x:%x:%x:%x:%x:%x:%x:%x", - netmask[0] << 8 | netmask[1], netmask[2] << 8 | netmask[3], - netmask[4] << 8 | netmask[5], netmask[6] << 8 | netmask[7], - netmask[8] << 8 | netmask[9], netmask[10] << 8 | netmask[11], - netmask[12] << 8 | netmask[13], netmask[14] << 8 | netmask[15]); - } - - return network.ToString() + "/" + strNetmask; -} - -bool CSubNet::IsValid() const -{ - return valid; -} - -bool operator==(const CSubNet& a, const CSubNet& b) -{ - return a.valid == b.valid && a.network == b.network && !memcmp(a.netmask, b.netmask, 16); -} - -bool operator!=(const CSubNet& a, const CSubNet& b) -{ - return !(a==b); -} - -bool operator<(const CSubNet& a, const CSubNet& b) -{ - return (a.network < b.network || (a.network == b.network && memcmp(a.netmask, b.netmask, 16) < 0)); -} - #ifdef WIN32 std::string NetworkErrorString(int err) { -- cgit v1.2.3 From 8945384bca00f74ba85c98a52925c254c49025a5 Mon Sep 17 00:00:00 2001 From: Cory Fields Date: Thu, 4 Aug 2016 16:37:49 -0400 Subject: net: Have LookupNumeric return a CService directly Also fix up a few small issues: - Lookup with "badip:port" now sets the port to 0 - Don't allow assert to have side-effects --- src/netbase.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'src/netbase.cpp') diff --git a/src/netbase.cpp b/src/netbase.cpp index c2294a078..4f243ec6f 100644 --- a/src/netbase.cpp +++ b/src/netbase.cpp @@ -231,9 +231,14 @@ bool Lookup(const char *pszName, CService& addr, int portDefault, bool fAllowLoo return true; } -bool LookupNumeric(const char *pszName, CService& addr, int portDefault) +CService LookupNumeric(const char *pszName, int portDefault) { - return Lookup(pszName, addr, portDefault, false); + CService addr; + // "1.2:345" will fail to resolve the ip, but will still set the port. + // If the ip fails to resolve, re-init the result. + if(!Lookup(pszName, addr, portDefault, false)) + addr = CService(); + return addr; } struct timeval MillisToTimeval(int64_t nTimeout) -- cgit v1.2.3 From b7c349d5e7c207bb7a2e7469c3e5522c9909c17f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pavel=20Jan=C3=ADk?= Date: Mon, 15 Aug 2016 14:10:07 +0200 Subject: Do not shadow variables in networking code --- src/netbase.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/netbase.cpp') diff --git a/src/netbase.cpp b/src/netbase.cpp index 4f243ec6f..7d7f1b678 100644 --- a/src/netbase.cpp +++ b/src/netbase.cpp @@ -631,8 +631,8 @@ bool ConnectSocketByName(CService &addr, SOCKET& hSocketRet, const char *pszDest SplitHostPort(std::string(pszDest), port, strDest); - proxyType nameProxy; - GetNameProxy(nameProxy); + proxyType proxy; + GetNameProxy(proxy); std::vector addrResolved; if (Lookup(strDest.c_str(), addrResolved, port, fNameLookup && !HaveNameProxy(), 256)) { @@ -646,7 +646,7 @@ bool ConnectSocketByName(CService &addr, SOCKET& hSocketRet, const char *pszDest if (!HaveNameProxy()) return false; - return ConnectThroughProxy(nameProxy, strDest, port, hSocketRet, nTimeout, outProxyConnectionFailed); + return ConnectThroughProxy(proxy, strDest, port, hSocketRet, nTimeout, outProxyConnectionFailed); } bool LookupSubNet(const char* pszName, CSubNet& ret) -- cgit v1.2.3 From 5eaaa83ac1f5eb525f93e2808fafd73f5ed97013 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Thu, 13 Oct 2016 16:19:20 +0200 Subject: Kill insecure_random and associated global state There are only a few uses of `insecure_random` outside the tests. This PR replaces uses of insecure_random (and its accompanying global state) in the core code with an FastRandomContext that is automatically seeded on creation. This is meant to be used for inner loops. The FastRandomContext can be in the outer scope, or the class itself, then rand32() is used inside the loop. Useful e.g. for pushing addresses in CNode or the fee rounding, or randomization for coin selection. As a context is created per purpose, thus it gets rid of cross-thread unprotected shared usage of a single set of globals, this should also get rid of the potential race conditions. - I'd say TxMempool::check is not called enough to warrant using a special fast random context, this is switched to GetRand() (open for discussion...) - The use of `insecure_rand` in ConnectThroughProxy has been replaced by an atomic integer counter. The only goal here is to have a different credentials pair for each connection to go on a different Tor circuit, it does not need to be random nor unpredictable. - To avoid having a FastRandomContext on every CNode, the context is passed into PushAddress as appropriate. There remains an insecure_random for test usage in `test_random.h`. --- src/netbase.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/netbase.cpp') diff --git a/src/netbase.cpp b/src/netbase.cpp index 7d7f1b678..9fe34108f 100644 --- a/src/netbase.cpp +++ b/src/netbase.cpp @@ -596,8 +596,8 @@ static bool ConnectThroughProxy(const proxyType &proxy, const std::string& strDe // do socks negotiation if (proxy.randomize_credentials) { ProxyCredentials random_auth; - random_auth.username = strprintf("%i", insecure_rand()); - random_auth.password = strprintf("%i", insecure_rand()); + static std::atomic_int counter; + random_auth.username = random_auth.password = strprintf("%i", counter++); if (!Socks5(strDest, (unsigned short)port, &random_auth, hSocket)) return false; } else { -- cgit v1.2.3 From 10ae7a7b2316f8052ec58ef237ce6dd987300900 Mon Sep 17 00:00:00 2001 From: Matt Corallo Date: Thu, 1 Dec 2016 14:31:38 -0800 Subject: Revert "Use async name resolving to improve net thread responsiveness" This reverts commit caf6150e9785da408f1e603ae70eae25b5202d98. getaddrinfo_a has a nasty tendency to segfault internally in its background thread, on every version of glibc I tested, especially under helgrind. See https://sourceware.org/bugzilla/show_bug.cgi?id=20874 --- src/netbase.cpp | 48 +----------------------------------------------- 1 file changed, 1 insertion(+), 47 deletions(-) (limited to 'src/netbase.cpp') diff --git a/src/netbase.cpp b/src/netbase.cpp index 9fe34108f..9118584b8 100644 --- a/src/netbase.cpp +++ b/src/netbase.cpp @@ -94,30 +94,9 @@ bool static LookupIntern(const char *pszName, std::vector& vIP, unsign } } -#ifdef HAVE_GETADDRINFO_A - struct in_addr ipv4_addr; -#ifdef HAVE_INET_PTON - if (inet_pton(AF_INET, pszName, &ipv4_addr) > 0) { - vIP.push_back(CNetAddr(ipv4_addr)); - return true; - } - - struct in6_addr ipv6_addr; - if (inet_pton(AF_INET6, pszName, &ipv6_addr) > 0) { - vIP.push_back(CNetAddr(ipv6_addr)); - return true; - } -#else - ipv4_addr.s_addr = inet_addr(pszName); - if (ipv4_addr.s_addr != INADDR_NONE) { - vIP.push_back(CNetAddr(ipv4_addr)); - return true; - } -#endif -#endif - struct addrinfo aiHint; memset(&aiHint, 0, sizeof(struct addrinfo)); + aiHint.ai_socktype = SOCK_STREAM; aiHint.ai_protocol = IPPROTO_TCP; aiHint.ai_family = AF_UNSPEC; @@ -126,33 +105,8 @@ bool static LookupIntern(const char *pszName, std::vector& vIP, unsign #else aiHint.ai_flags = fAllowLookup ? AI_ADDRCONFIG : AI_NUMERICHOST; #endif - struct addrinfo *aiRes = NULL; -#ifdef HAVE_GETADDRINFO_A - struct gaicb gcb, *query = &gcb; - memset(query, 0, sizeof(struct gaicb)); - gcb.ar_name = pszName; - gcb.ar_request = &aiHint; - int nErr = getaddrinfo_a(GAI_NOWAIT, &query, 1, NULL); - if (nErr) - return false; - - do { - // Should set the timeout limit to a reasonable value to avoid - // generating unnecessary checking call during the polling loop, - // while it can still response to stop request quick enough. - // 2 seconds looks fine in our situation. - struct timespec ts = { 2, 0 }; - gai_suspend(&query, 1, &ts); - boost::this_thread::interruption_point(); - - nErr = gai_error(query); - if (0 == nErr) - aiRes = query->ar_result; - } while (nErr == EAI_INPROGRESS); -#else int nErr = getaddrinfo(pszName, NULL, &aiHint, &aiRes); -#endif if (nErr) return false; -- cgit v1.2.3 From 8c1dbc5e9ddbafb77e60e8c4e6eb275a3a76ac12 Mon Sep 17 00:00:00 2001 From: Karl-Johan Alm Date: Fri, 9 Dec 2016 12:01:37 +0900 Subject: Refactor: Removed begin/end_ptr functions. --- src/netbase.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/netbase.cpp') diff --git a/src/netbase.cpp b/src/netbase.cpp index 9118584b8..da94fd4d1 100644 --- a/src/netbase.cpp +++ b/src/netbase.cpp @@ -292,7 +292,7 @@ static bool Socks5(const std::string& strDest, int port, const ProxyCredentials vSocks5Init.push_back(0x01); // # METHODS vSocks5Init.push_back(0x00); // X'00' NO AUTHENTICATION REQUIRED } - ssize_t ret = send(hSocket, (const char*)begin_ptr(vSocks5Init), vSocks5Init.size(), MSG_NOSIGNAL); + ssize_t ret = send(hSocket, (const char*)vSocks5Init.data(), vSocks5Init.size(), MSG_NOSIGNAL); if (ret != (ssize_t)vSocks5Init.size()) { CloseSocket(hSocket); return error("Error sending to proxy"); @@ -317,7 +317,7 @@ static bool Socks5(const std::string& strDest, int port, const ProxyCredentials vAuth.insert(vAuth.end(), auth->username.begin(), auth->username.end()); vAuth.push_back(auth->password.size()); vAuth.insert(vAuth.end(), auth->password.begin(), auth->password.end()); - ret = send(hSocket, (const char*)begin_ptr(vAuth), vAuth.size(), MSG_NOSIGNAL); + ret = send(hSocket, (const char*)vAuth.data(), vAuth.size(), MSG_NOSIGNAL); if (ret != (ssize_t)vAuth.size()) { CloseSocket(hSocket); return error("Error sending authentication to proxy"); @@ -347,7 +347,7 @@ static bool Socks5(const std::string& strDest, int port, const ProxyCredentials vSocks5.insert(vSocks5.end(), strDest.begin(), strDest.end()); vSocks5.push_back((port >> 8) & 0xFF); vSocks5.push_back((port >> 0) & 0xFF); - ret = send(hSocket, (const char*)begin_ptr(vSocks5), vSocks5.size(), MSG_NOSIGNAL); + ret = send(hSocket, (const char*)vSocks5.data(), vSocks5.size(), MSG_NOSIGNAL); if (ret != (ssize_t)vSocks5.size()) { CloseSocket(hSocket); return error("Error sending to proxy"); -- cgit v1.2.3 From 27765b6403cece54320374b37afb01a0cfe571c3 Mon Sep 17 00:00:00 2001 From: isle2983 Date: Sat, 31 Dec 2016 11:01:21 -0700 Subject: Increment MIT Licence copyright header year on files modified in 2016 Edited via: $ contrib/devtools/copyright_header.py update . --- src/netbase.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/netbase.cpp') diff --git a/src/netbase.cpp b/src/netbase.cpp index da94fd4d1..21aa645de 100644 --- a/src/netbase.cpp +++ b/src/netbase.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2015 The Bitcoin Core developers +// Copyright (c) 2009-2016 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. -- cgit v1.2.3 From 8b3159ef0a912da67c545a3d24f4558f8df866e4 Mon Sep 17 00:00:00 2001 From: Cory Fields Date: Tue, 27 Dec 2016 17:13:31 -0500 Subject: net: make proxy receives interruptible --- src/netbase.cpp | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) (limited to 'src/netbase.cpp') diff --git a/src/netbase.cpp b/src/netbase.cpp index da94fd4d1..87c7abd7c 100644 --- a/src/netbase.cpp +++ b/src/netbase.cpp @@ -19,6 +19,7 @@ #ifdef HAVE_GETADDRINFO_A #include #endif +#include #ifndef WIN32 #if HAVE_INET_PTON @@ -44,6 +45,7 @@ bool fNameLookup = DEFAULT_NAME_LOOKUP; // Need ample time for negotiation for very slow proxies such as Tor (milliseconds) static const int SOCKS5_RECV_TIMEOUT = 20 * 1000; +static std::atomic interruptSocks5Recv(false); enum Network ParseNetwork(std::string net) { boost::to_lower(net); @@ -206,7 +208,7 @@ struct timeval MillisToTimeval(int64_t nTimeout) /** * Read bytes from socket. This will either read the full number of bytes requested * or return False on error or timeout. - * This function can be interrupted by boost thread interrupt. + * This function can be interrupted by calling InterruptSocks5() * * @param data Buffer to receive into * @param len Length of data to receive @@ -246,7 +248,8 @@ bool static InterruptibleRecv(char* data, size_t len, int timeout, SOCKET& hSock return false; } } - boost::this_thread::interruption_point(); + if (interruptSocks5Recv) + return false; curTime = GetTimeMillis(); } return len == 0; @@ -715,3 +718,8 @@ bool SetSocketNonBlocking(SOCKET& hSocket, bool fNonBlocking) return true; } + +void InterruptSocks5(bool interrupt) +{ + interruptSocks5Recv = interrupt; +} -- cgit v1.2.3 From 67ee4ec9015592c8447955356adfcbb1bf473e32 Mon Sep 17 00:00:00 2001 From: Cory Fields Date: Tue, 27 Dec 2016 17:13:51 -0500 Subject: net: misc header cleanups --- src/netbase.cpp | 7 ------- 1 file changed, 7 deletions(-) (limited to 'src/netbase.cpp') diff --git a/src/netbase.cpp b/src/netbase.cpp index 87c7abd7c..afa3c3b13 100644 --- a/src/netbase.cpp +++ b/src/netbase.cpp @@ -16,21 +16,14 @@ #include "util.h" #include "utilstrencodings.h" -#ifdef HAVE_GETADDRINFO_A -#include -#endif #include #ifndef WIN32 -#if HAVE_INET_PTON -#include -#endif #include #endif #include // for to_lower() #include // for startswith() and endswith() -#include #if !defined(HAVE_MSG_NOSIGNAL) && !defined(MSG_NOSIGNAL) #define MSG_NOSIGNAL 0 -- cgit v1.2.3