aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWladimir J. van der Laan <laanwj@gmail.com>2016-08-15 13:33:46 +0200
committerWladimir J. van der Laan <laanwj@gmail.com>2016-08-15 13:35:27 +0200
commit1030fa718c59c29d3208af13e853457b7ac59d2e (patch)
treef2ba7f33f972be99ef8198e3e9676131b8f2dc8f
parentd727f77e390426e9e463336bda08d50c451c7086 (diff)
parent9e9d644f5178da8b5743ea3ddc3b779a2c8d1cd4 (diff)
downloadbitcoin-1030fa718c59c29d3208af13e853457b7ac59d2e.tar.xz
Merge #8128: Net: Turn net structures into dumb storage classes
9e9d644 net: fixup nits (Cory Fields) 8945384 net: Have LookupNumeric return a CService directly (Cory Fields) 21ba407 net: narrow include scope after moving to netaddress (Cory Fields) 21e5b96 net: move CNetAddr/CService/CSubNet out of netbase (Cory Fields) 1017b8a net: Add direct tests for new CSubNet constructors (Cory Fields) b6c3ff3 net: Split resolving out of CSubNet (Cory Fields) f96c7c4 net: Split resolving out of CService (Cory Fields) 31d6b1d net: Split resolving out of CNetAddr (Cory Fields)
-rw-r--r--src/Makefile.am2
-rw-r--r--src/addrman.h2
-rw-r--r--src/httpserver.cpp13
-rw-r--r--src/init.cpp10
-rw-r--r--src/net.cpp27
-rw-r--r--src/net.h2
-rw-r--r--src/netaddress.cpp716
-rw-r--r--src/netaddress.h171
-rw-r--r--src/netbase.cpp782
-rw-r--r--src/netbase.h167
-rw-r--r--src/protocol.h2
-rw-r--r--src/qt/optionsdialog.cpp3
-rw-r--r--src/qt/optionsmodel.cpp1
-rw-r--r--src/qt/rpcconsole.cpp9
-rw-r--r--src/rpc/net.cpp9
-rw-r--r--src/test/addrman_tests.cpp151
-rw-r--r--src/test/net_tests.cpp24
-rw-r--r--src/test/netbase_tests.cpp281
-rw-r--r--src/timedata.cpp2
-rw-r--r--src/torcontrol.cpp7
-rw-r--r--src/wallet/rpcwallet.cpp1
21 files changed, 1246 insertions, 1136 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index e3eaacdb4c..03fac5bf97 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -105,6 +105,7 @@ BITCOIN_CORE_H = \
merkleblock.h \
miner.h \
net.h \
+ netaddress.h \
netbase.h \
noui.h \
policy/fees.h \
@@ -289,6 +290,7 @@ libbitcoin_common_a_SOURCES = \
core_write.cpp \
key.cpp \
keystore.cpp \
+ netaddress.cpp \
netbase.cpp \
protocol.cpp \
scheduler.cpp \
diff --git a/src/addrman.h b/src/addrman.h
index 1caf540758..9bab39049d 100644
--- a/src/addrman.h
+++ b/src/addrman.h
@@ -6,7 +6,7 @@
#ifndef BITCOIN_ADDRMAN_H
#define BITCOIN_ADDRMAN_H
-#include "netbase.h"
+#include "netaddress.h"
#include "protocol.h"
#include "random.h"
#include "sync.h"
diff --git a/src/httpserver.cpp b/src/httpserver.cpp
index be7a6a1dde..f921305fcc 100644
--- a/src/httpserver.cpp
+++ b/src/httpserver.cpp
@@ -197,12 +197,17 @@ static bool ClientAllowed(const CNetAddr& netaddr)
static bool InitHTTPAllowList()
{
rpc_allow_subnets.clear();
- rpc_allow_subnets.push_back(CSubNet("127.0.0.0/8")); // always allow IPv4 local subnet
- rpc_allow_subnets.push_back(CSubNet("::1")); // always allow IPv6 localhost
+ CNetAddr localv4;
+ CNetAddr localv6;
+ LookupHost("127.0.0.1", localv4, false);
+ LookupHost("::1", localv6, false);
+ rpc_allow_subnets.push_back(CSubNet(localv4, 8)); // always allow IPv4 local subnet
+ rpc_allow_subnets.push_back(CSubNet(localv6)); // always allow IPv6 localhost
if (mapMultiArgs.count("-rpcallowip")) {
const std::vector<std::string>& vAllow = mapMultiArgs["-rpcallowip"];
for (std::string strAllow : vAllow) {
- CSubNet subnet(strAllow);
+ CSubNet subnet;
+ LookupSubNet(strAllow.c_str(), subnet);
if (!subnet.IsValid()) {
uiInterface.ThreadSafeMessageBox(
strprintf("Invalid -rpcallowip subnet specification: %s. Valid are a single IP (e.g. 1.2.3.4), a network/netmask (e.g. 1.2.3.4/255.255.255.0) or a network/CIDR (e.g. 1.2.3.4/24).", strAllow),
@@ -614,7 +619,7 @@ CService HTTPRequest::GetPeer()
const char* address = "";
uint16_t port = 0;
evhttp_connection_get_peer(con, (char**)&address, &port);
- peer = CService(address, port);
+ peer = LookupNumeric(address, port);
}
return peer;
}
diff --git a/src/init.cpp b/src/init.cpp
index 4d9de6cfc8..51784fe06b 100644
--- a/src/init.cpp
+++ b/src/init.cpp
@@ -21,6 +21,7 @@
#include "key.h"
#include "main.h"
#include "miner.h"
+#include "netbase.h"
#include "net.h"
#include "policy/policy.h"
#include "rpc/server.h"
@@ -1134,7 +1135,8 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
if (mapArgs.count("-whitelist")) {
BOOST_FOREACH(const std::string& net, mapMultiArgs["-whitelist"]) {
- CSubNet subnet(net);
+ CSubNet subnet;
+ LookupSubNet(net.c_str(), subnet);
if (!subnet.IsValid())
return InitError(strprintf(_("Invalid netmask specified in -whitelist: '%s'"), net));
CNode::AddWhitelistedRange(subnet);
@@ -1147,7 +1149,8 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
std::string proxyArg = GetArg("-proxy", "");
SetLimited(NET_TOR);
if (proxyArg != "" && proxyArg != "0") {
- proxyType addrProxy = proxyType(CService(proxyArg, 9050), proxyRandomize);
+ CService resolved(LookupNumeric(proxyArg.c_str(), 9050));
+ proxyType addrProxy = proxyType(resolved, proxyRandomize);
if (!addrProxy.IsValid())
return InitError(strprintf(_("Invalid -proxy address: '%s'"), proxyArg));
@@ -1166,7 +1169,8 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
if (onionArg == "0") { // Handle -noonion/-onion=0
SetLimited(NET_TOR); // set onions as unreachable
} else {
- proxyType addrOnion = proxyType(CService(onionArg, 9050), proxyRandomize);
+ CService resolved(LookupNumeric(onionArg.c_str(), 9050));
+ proxyType addrOnion = proxyType(resolved, proxyRandomize);
if (!addrOnion.IsValid())
return InitError(strprintf(_("Invalid -onion address: '%s'"), onionArg));
SetProxy(NET_TOR, addrOnion);
diff --git a/src/net.cpp b/src/net.cpp
index 4bbe5059df..a0773b2e07 100644
--- a/src/net.cpp
+++ b/src/net.cpp
@@ -17,6 +17,7 @@
#include "crypto/sha256.h"
#include "hash.h"
#include "primitives/transaction.h"
+#include "netbase.h"
#include "scheduler.h"
#include "ui_interface.h"
#include "utilstrencodings.h"
@@ -175,7 +176,7 @@ static std::vector<CAddress> convertSeed6(const std::vector<SeedSpec6> &vSeedsIn
// one by discovery.
CAddress GetLocalAddress(const CNetAddr *paddrPeer)
{
- CAddress ret(CService("0.0.0.0",GetListenPort()), NODE_NONE);
+ CAddress ret(CService(CNetAddr(),GetListenPort()), NODE_NONE);
CService addr;
if (GetLocal(addr, paddrPeer))
{
@@ -494,7 +495,7 @@ void CNode::PushVersion()
int nBestHeight = GetNodeSignals().GetHeight().get_value_or(0);
int64_t nTime = (fInbound ? GetAdjustedTime() : GetTime());
- CAddress addrYou = (addr.IsRoutable() && !IsProxy(addr) ? addr : CAddress(CService("0.0.0.0", 0), addr.nServices));
+ CAddress addrYou = (addr.IsRoutable() && !IsProxy(addr) ? addr : CAddress(CService(), addr.nServices));
CAddress addrMe = GetLocalAddress(&addr);
GetRandBytes((unsigned char*)&nLocalHostNonce, sizeof(nLocalHostNonce));
if (fLogIPs)
@@ -1396,8 +1397,11 @@ void ThreadMapPort()
{
if(externalIPAddress[0])
{
- LogPrintf("UPnP: ExternalIPAddress = %s\n", externalIPAddress);
- AddLocal(CNetAddr(externalIPAddress), LOCAL_UPNP);
+ CNetAddr resolved;
+ if(LookupHost(externalIPAddress, resolved, false)) {
+ LogPrintf("UPnP: ExternalIPAddress = %s\n", resolved.ToString().c_str());
+ AddLocal(resolved, LOCAL_UPNP);
+ }
}
else
LogPrintf("UPnP: GetExternalIPAddress failed.\n");
@@ -1623,7 +1627,9 @@ void ThreadOpenConnections()
static bool done = false;
if (!done) {
LogPrintf("Adding fixed seed nodes as DNS doesn't seem to be available.\n");
- addrman.Add(convertSeed6(Params().FixedSeeds()), CNetAddr("127.0.0.1"));
+ CNetAddr local;
+ LookupHost("127.0.0.1", local, false);
+ addrman.Add(convertSeed6(Params().FixedSeeds()), local);
done = true;
}
}
@@ -1722,7 +1728,7 @@ std::vector<AddedNodeInfo> GetAddedNodeInfo()
}
BOOST_FOREACH(const std::string& strAddNode, lAddresses) {
- CService service(strAddNode, Params().GetDefaultPort());
+ CService service(LookupNumeric(strAddNode.c_str(), Params().GetDefaultPort()));
if (service.IsValid()) {
// strAddNode is an IP:port
auto it = mapConnected.find(service);
@@ -1760,7 +1766,7 @@ void ThreadOpenAddedConnections()
CSemaphoreGrant grant(*semOutbound);
// If strAddedNode is an IP/port, decode it immediately, so
// OpenNetworkConnection can detect existing connections to that IP/port.
- CService service(info.strAddedNode, Params().GetDefaultPort());
+ CService service(LookupNumeric(info.strAddedNode.c_str(), Params().GetDefaultPort()));
OpenNetworkConnection(CAddress(service, NODE_NONE), false, &grant, info.strAddedNode.c_str(), false);
MilliSleep(500);
}
@@ -2060,8 +2066,11 @@ void StartNode(boost::thread_group& threadGroup, CScheduler& scheduler)
semOutbound = new CSemaphore(nMaxOutbound);
}
- if (pnodeLocalHost == NULL)
- pnodeLocalHost = new CNode(INVALID_SOCKET, CAddress(CService("127.0.0.1", 0), nLocalServices));
+ if (pnodeLocalHost == NULL) {
+ CNetAddr local;
+ LookupHost("127.0.0.1", local, false);
+ pnodeLocalHost = new CNode(INVALID_SOCKET, CAddress(CService(local, 0), nLocalServices));
+ }
Discover(threadGroup);
diff --git a/src/net.h b/src/net.h
index 41315fc9b9..ea03defc40 100644
--- a/src/net.h
+++ b/src/net.h
@@ -10,7 +10,7 @@
#include "bloom.h"
#include "compat.h"
#include "limitedmap.h"
-#include "netbase.h"
+#include "netaddress.h"
#include "protocol.h"
#include "random.h"
#include "streams.h"
diff --git a/src/netaddress.cpp b/src/netaddress.cpp
new file mode 100644
index 0000000000..7000ce3f0a
--- /dev/null
+++ b/src/netaddress.cpp
@@ -0,0 +1,716 @@
+// Copyright (c) 2009-2010 Satoshi Nakamoto
+// 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.
+
+#ifdef HAVE_CONFIG_H
+#include "config/bitcoin-config.h"
+#endif
+
+#include "netaddress.h"
+#include "hash.h"
+#include "utilstrencodings.h"
+#include "tinyformat.h"
+
+static const unsigned char pchIPv4[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff };
+static const unsigned char pchOnionCat[] = {0xFD,0x87,0xD8,0x7E,0xEB,0x43};
+
+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");
+ }
+}
+
+bool CNetAddr::SetSpecial(const std::string &strName)
+{
+ if (strName.size()>6 && strName.substr(strName.size() - 6, 6) == ".onion") {
+ std::vector<unsigned char> 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<unsigned char> CNetAddr::GetGroup() const
+{
+ std::vector<unsigned char> 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<unsigned char> CService::GetKey() const
+{
+ std::vector<unsigned char> 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];
+}
+
+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));
+}
diff --git a/src/netaddress.h b/src/netaddress.h
new file mode 100644
index 0000000000..9330fe3328
--- /dev/null
+++ b/src/netaddress.h
@@ -0,0 +1,171 @@
+// 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.
+
+#ifndef BITCOIN_NETADDRESS_H
+#define BITCOIN_NETADDRESS_H
+
+#if defined(HAVE_CONFIG_H)
+#include "config/bitcoin-config.h"
+#endif
+
+#include "compat.h"
+#include "serialize.h"
+
+#include <stdint.h>
+#include <string>
+#include <vector>
+
+enum Network
+{
+ NET_UNROUTABLE = 0,
+ NET_IPV4,
+ NET_IPV6,
+ NET_TOR,
+
+ NET_MAX,
+};
+
+/** IP address (IPv6, or IPv4 using mapped IPv6 range (::FFFF:0:0/96)) */
+class CNetAddr
+{
+ protected:
+ unsigned char ip[16]; // in network byte order
+ uint32_t scopeId; // for scoped/link-local ipv6 addresses
+
+ public:
+ CNetAddr();
+ CNetAddr(const struct in_addr& ipv4Addr);
+ void Init();
+ void SetIP(const CNetAddr& ip);
+
+ /**
+ * Set raw IPv4 or IPv6 address (in network byte order)
+ * @note Only NET_IPV4 and NET_IPV6 are allowed for network.
+ */
+ void SetRaw(Network network, const uint8_t *data);
+
+ bool SetSpecial(const std::string &strName); // for Tor addresses
+ bool IsIPv4() const; // IPv4 mapped address (::FFFF:0:0/96, 0.0.0.0/0)
+ bool IsIPv6() const; // IPv6 address (not mapped IPv4, not Tor)
+ bool IsRFC1918() const; // IPv4 private networks (10.0.0.0/8, 192.168.0.0/16, 172.16.0.0/12)
+ bool IsRFC2544() const; // IPv4 inter-network communcations (192.18.0.0/15)
+ bool IsRFC6598() const; // IPv4 ISP-level NAT (100.64.0.0/10)
+ bool IsRFC5737() const; // IPv4 documentation addresses (192.0.2.0/24, 198.51.100.0/24, 203.0.113.0/24)
+ bool IsRFC3849() const; // IPv6 documentation address (2001:0DB8::/32)
+ bool IsRFC3927() const; // IPv4 autoconfig (169.254.0.0/16)
+ bool IsRFC3964() const; // IPv6 6to4 tunnelling (2002::/16)
+ bool IsRFC4193() const; // IPv6 unique local (FC00::/7)
+ bool IsRFC4380() const; // IPv6 Teredo tunnelling (2001::/32)
+ bool IsRFC4843() const; // IPv6 ORCHID (2001:10::/28)
+ bool IsRFC4862() const; // IPv6 autoconfig (FE80::/64)
+ bool IsRFC6052() const; // IPv6 well-known prefix (64:FF9B::/96)
+ bool IsRFC6145() const; // IPv6 IPv4-translated address (::FFFF:0:0:0/96)
+ bool IsTor() const;
+ bool IsLocal() const;
+ bool IsRoutable() const;
+ bool IsValid() const;
+ bool IsMulticast() const;
+ enum Network GetNetwork() const;
+ std::string ToString() const;
+ std::string ToStringIP() const;
+ unsigned int GetByte(int n) const;
+ uint64_t GetHash() const;
+ bool GetInAddr(struct in_addr* pipv4Addr) const;
+ std::vector<unsigned char> GetGroup() const;
+ int GetReachabilityFrom(const CNetAddr *paddrPartner = NULL) const;
+
+ CNetAddr(const struct in6_addr& pipv6Addr, const uint32_t scope = 0);
+ bool GetIn6Addr(struct in6_addr* pipv6Addr) const;
+
+ friend bool operator==(const CNetAddr& a, const CNetAddr& b);
+ friend bool operator!=(const CNetAddr& a, const CNetAddr& b);
+ friend bool operator<(const CNetAddr& a, const CNetAddr& b);
+
+ ADD_SERIALIZE_METHODS;
+
+ template <typename Stream, typename Operation>
+ inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
+ READWRITE(FLATDATA(ip));
+ }
+
+ friend class CSubNet;
+};
+
+class CSubNet
+{
+ protected:
+ /// Network (base) address
+ CNetAddr network;
+ /// Netmask, in network byte order
+ uint8_t netmask[16];
+ /// Is this value valid? (only used to signal parse errors)
+ bool valid;
+
+ public:
+ CSubNet();
+ CSubNet(const CNetAddr &addr, int32_t mask);
+ CSubNet(const CNetAddr &addr, const CNetAddr &mask);
+
+ //constructor for single ip subnet (<ipv4>/32 or <ipv6>/128)
+ explicit CSubNet(const CNetAddr &addr);
+
+ bool Match(const CNetAddr &addr) const;
+
+ std::string ToString() const;
+ bool IsValid() const;
+
+ friend bool operator==(const CSubNet& a, const CSubNet& b);
+ friend bool operator!=(const CSubNet& a, const CSubNet& b);
+ friend bool operator<(const CSubNet& a, const CSubNet& b);
+
+ ADD_SERIALIZE_METHODS;
+
+ template <typename Stream, typename Operation>
+ inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
+ READWRITE(network);
+ READWRITE(FLATDATA(netmask));
+ READWRITE(FLATDATA(valid));
+ }
+};
+
+/** A combination of a network address (CNetAddr) and a (TCP) port */
+class CService : public CNetAddr
+{
+ protected:
+ unsigned short port; // host order
+
+ public:
+ CService();
+ CService(const CNetAddr& ip, unsigned short port);
+ CService(const struct in_addr& ipv4Addr, unsigned short port);
+ CService(const struct sockaddr_in& addr);
+ void Init();
+ void SetPort(unsigned short portIn);
+ unsigned short GetPort() const;
+ bool GetSockAddr(struct sockaddr* paddr, socklen_t *addrlen) const;
+ bool SetSockAddr(const struct sockaddr* paddr);
+ friend bool operator==(const CService& a, const CService& b);
+ friend bool operator!=(const CService& a, const CService& b);
+ friend bool operator<(const CService& a, const CService& b);
+ std::vector<unsigned char> GetKey() const;
+ std::string ToString() const;
+ std::string ToStringPort() const;
+ std::string ToStringIPPort() const;
+
+ CService(const struct in6_addr& ipv6Addr, unsigned short port);
+ CService(const struct sockaddr_in6& addr);
+
+ ADD_SERIALIZE_METHODS;
+
+ template <typename Stream, typename Operation>
+ inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
+ READWRITE(FLATDATA(ip));
+ unsigned short portN = htons(port);
+ READWRITE(FLATDATA(portN));
+ if (ser_action.ForRead())
+ port = ntohs(portN);
+ }
+};
+
+#endif // BITCOIN_NETADDRESS_H
diff --git a/src/netbase.cpp b/src/netbase.cpp
index e2a516986c..4f243ec6f5 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;
@@ -195,6 +193,16 @@ bool LookupHost(const char *pszName, std::vector<CNetAddr>& vIP, unsigned int nM
return LookupIntern(strHost.c_str(), vIP, nMaxSolutions, fAllowLookup);
}
+bool LookupHost(const char *pszName, CNetAddr& addr, bool fAllowLookup)
+{
+ std::vector<CNetAddr> vIP;
+ LookupHost(pszName, vIP, 1, fAllowLookup);
+ if(vIP.empty())
+ return false;
+ addr = vIP.front();
+ return true;
+}
+
bool Lookup(const char *pszName, std::vector<CService>& vAddr, int portDefault, bool fAllowLookup, unsigned int nMaxSolutions)
{
if (pszName[0] == 0)
@@ -223,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)
@@ -629,777 +642,48 @@ bool ConnectSocketByName(CService &addr, SOCKET& hSocketRet, const char *pszDest
}
}
- addr = CService("0.0.0.0:0");
+ addr = CService();
if (!HaveNameProxy())
return false;
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<unsigned char> 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;
-}
-
-CNetAddr::CNetAddr(const char *pszIp)
-{
- Init();
- std::vector<CNetAddr> vIP;
- if (LookupHost(pszIp, vIP, 1, false))
- *this = vIP[0];
-}
-
-CNetAddr::CNetAddr(const std::string &strIp)
-{
- Init();
- std::vector<CNetAddr> vIP;
- if (LookupHost(strIp.c_str(), vIP, 1, false))
- *this = vIP[0];
-}
-
-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<unsigned char> CNetAddr::GetGroup() const
-{
- std::vector<unsigned char> 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;
- }
-}
-
-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;
-}
-
-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<unsigned char> CService::GetKey() const
-{
- std::vector<unsigned char> 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 std::string &strSubnet)
+bool LookupSubNet(const char* pszName, CSubNet& ret)
{
+ std::string strSubnet(pszName);
size_t slash = strSubnet.find_last_of('/');
std::vector<CNetAddr> vIP;
- valid = true;
- // Default to /32 (IPv4) or /128 (IPv6), i.e. match single address
- memset(netmask, 255, sizeof(netmask));
-
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
- {
- valid = false;
- }
-
- // Normalize network according to netmask
- for(int x=0; x<16; ++x)
- 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())
- 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]);
+ {
+ ret = CSubNet(network);
+ return ret.IsValid();
+ }
}
-
- 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));
+ return false;
}
#ifdef WIN32
diff --git a/src/netbase.h b/src/netbase.h
index 65187a17cf..bb12019a82 100644
--- a/src/netbase.h
+++ b/src/netbase.h
@@ -10,6 +10,7 @@
#endif
#include "compat.h"
+#include "netaddress.h"
#include "serialize.h"
#include <stdint.h>
@@ -24,168 +25,6 @@ static const int DEFAULT_CONNECT_TIMEOUT = 5000;
//! -dns default
static const int DEFAULT_NAME_LOOKUP = true;
-#ifdef WIN32
-// In MSVC, this is defined as a macro, undefine it to prevent a compile and link error
-#undef SetPort
-#endif
-
-enum Network
-{
- NET_UNROUTABLE = 0,
- NET_IPV4,
- NET_IPV6,
- NET_TOR,
-
- NET_MAX,
-};
-
-/** IP address (IPv6, or IPv4 using mapped IPv6 range (::FFFF:0:0/96)) */
-class CNetAddr
-{
- protected:
- unsigned char ip[16]; // in network byte order
- uint32_t scopeId; // for scoped/link-local ipv6 addresses
-
- public:
- CNetAddr();
- CNetAddr(const struct in_addr& ipv4Addr);
- explicit CNetAddr(const char *pszIp);
- explicit CNetAddr(const std::string &strIp);
- void Init();
- void SetIP(const CNetAddr& ip);
-
- /**
- * Set raw IPv4 or IPv6 address (in network byte order)
- * @note Only NET_IPV4 and NET_IPV6 are allowed for network.
- */
- void SetRaw(Network network, const uint8_t *data);
-
- bool SetSpecial(const std::string &strName); // for Tor addresses
- bool IsIPv4() const; // IPv4 mapped address (::FFFF:0:0/96, 0.0.0.0/0)
- bool IsIPv6() const; // IPv6 address (not mapped IPv4, not Tor)
- bool IsRFC1918() const; // IPv4 private networks (10.0.0.0/8, 192.168.0.0/16, 172.16.0.0/12)
- bool IsRFC2544() const; // IPv4 inter-network communcations (192.18.0.0/15)
- bool IsRFC6598() const; // IPv4 ISP-level NAT (100.64.0.0/10)
- bool IsRFC5737() const; // IPv4 documentation addresses (192.0.2.0/24, 198.51.100.0/24, 203.0.113.0/24)
- bool IsRFC3849() const; // IPv6 documentation address (2001:0DB8::/32)
- bool IsRFC3927() const; // IPv4 autoconfig (169.254.0.0/16)
- bool IsRFC3964() const; // IPv6 6to4 tunnelling (2002::/16)
- bool IsRFC4193() const; // IPv6 unique local (FC00::/7)
- bool IsRFC4380() const; // IPv6 Teredo tunnelling (2001::/32)
- bool IsRFC4843() const; // IPv6 ORCHID (2001:10::/28)
- bool IsRFC4862() const; // IPv6 autoconfig (FE80::/64)
- bool IsRFC6052() const; // IPv6 well-known prefix (64:FF9B::/96)
- bool IsRFC6145() const; // IPv6 IPv4-translated address (::FFFF:0:0:0/96)
- bool IsTor() const;
- bool IsLocal() const;
- bool IsRoutable() const;
- bool IsValid() const;
- bool IsMulticast() const;
- enum Network GetNetwork() const;
- std::string ToString() const;
- std::string ToStringIP() const;
- unsigned int GetByte(int n) const;
- uint64_t GetHash() const;
- bool GetInAddr(struct in_addr* pipv4Addr) const;
- std::vector<unsigned char> GetGroup() const;
- int GetReachabilityFrom(const CNetAddr *paddrPartner = NULL) const;
-
- CNetAddr(const struct in6_addr& pipv6Addr, const uint32_t scope = 0);
- bool GetIn6Addr(struct in6_addr* pipv6Addr) const;
-
- friend bool operator==(const CNetAddr& a, const CNetAddr& b);
- friend bool operator!=(const CNetAddr& a, const CNetAddr& b);
- friend bool operator<(const CNetAddr& a, const CNetAddr& b);
-
- ADD_SERIALIZE_METHODS;
-
- template <typename Stream, typename Operation>
- inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
- READWRITE(FLATDATA(ip));
- }
-
- friend class CSubNet;
-};
-
-class CSubNet
-{
- protected:
- /// Network (base) address
- CNetAddr network;
- /// Netmask, in network byte order
- uint8_t netmask[16];
- /// Is this value valid? (only used to signal parse errors)
- bool valid;
-
- public:
- CSubNet();
- explicit CSubNet(const std::string &strSubnet);
-
- //constructor for single ip subnet (<ipv4>/32 or <ipv6>/128)
- explicit CSubNet(const CNetAddr &addr);
-
- bool Match(const CNetAddr &addr) const;
-
- std::string ToString() const;
- bool IsValid() const;
-
- friend bool operator==(const CSubNet& a, const CSubNet& b);
- friend bool operator!=(const CSubNet& a, const CSubNet& b);
- friend bool operator<(const CSubNet& a, const CSubNet& b);
-
- ADD_SERIALIZE_METHODS;
-
- template <typename Stream, typename Operation>
- inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
- READWRITE(network);
- READWRITE(FLATDATA(netmask));
- READWRITE(FLATDATA(valid));
- }
-};
-
-/** A combination of a network address (CNetAddr) and a (TCP) port */
-class CService : public CNetAddr
-{
- protected:
- unsigned short port; // host order
-
- public:
- CService();
- CService(const CNetAddr& ip, unsigned short port);
- CService(const struct in_addr& ipv4Addr, unsigned short port);
- CService(const struct sockaddr_in& addr);
- explicit CService(const char *pszIpPort, int portDefault);
- explicit CService(const char *pszIpPort);
- explicit CService(const std::string& strIpPort, int portDefault);
- explicit CService(const std::string& strIpPort);
- void Init();
- void SetPort(unsigned short portIn);
- unsigned short GetPort() const;
- bool GetSockAddr(struct sockaddr* paddr, socklen_t *addrlen) const;
- bool SetSockAddr(const struct sockaddr* paddr);
- friend bool operator==(const CService& a, const CService& b);
- friend bool operator!=(const CService& a, const CService& b);
- friend bool operator<(const CService& a, const CService& b);
- std::vector<unsigned char> GetKey() const;
- std::string ToString() const;
- std::string ToStringPort() const;
- std::string ToStringIPPort() const;
-
- CService(const struct in6_addr& ipv6Addr, unsigned short port);
- CService(const struct sockaddr_in6& addr);
-
- ADD_SERIALIZE_METHODS;
-
- template <typename Stream, typename Operation>
- inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
- READWRITE(FLATDATA(ip));
- unsigned short portN = htons(port);
- READWRITE(FLATDATA(portN));
- if (ser_action.ForRead())
- port = ntohs(portN);
- }
-};
-
class proxyType
{
public:
@@ -207,9 +46,11 @@ bool IsProxy(const CNetAddr &addr);
bool SetNameProxy(const proxyType &addrProxy);
bool HaveNameProxy();
bool LookupHost(const char *pszName, std::vector<CNetAddr>& vIP, unsigned int nMaxSolutions, bool fAllowLookup);
+bool LookupHost(const char *pszName, CNetAddr& addr, bool fAllowLookup);
bool Lookup(const char *pszName, CService& addr, int portDefault, bool fAllowLookup);
bool Lookup(const char *pszName, std::vector<CService>& vAddr, int portDefault, bool fAllowLookup, unsigned int nMaxSolutions);
-bool LookupNumeric(const char *pszName, CService& addr, int portDefault = 0);
+CService LookupNumeric(const char *pszName, int portDefault = 0);
+bool LookupSubNet(const char *pszName, CSubNet& subnet);
bool ConnectSocket(const CService &addr, SOCKET& hSocketRet, int nTimeout, bool *outProxyConnectionFailed = 0);
bool ConnectSocketByName(CService &addr, SOCKET& hSocketRet, const char *pszDest, int portDefault, int nTimeout, bool *outProxyConnectionFailed = 0);
/** Return readable error string for a network error code */
diff --git a/src/protocol.h b/src/protocol.h
index 15f27e2d2f..015215b2a6 100644
--- a/src/protocol.h
+++ b/src/protocol.h
@@ -10,7 +10,7 @@
#ifndef BITCOIN_PROTOCOL_H
#define BITCOIN_PROTOCOL_H
-#include "netbase.h"
+#include "netaddress.h"
#include "serialize.h"
#include "uint256.h"
#include "version.h"
diff --git a/src/qt/optionsdialog.cpp b/src/qt/optionsdialog.cpp
index f2db398899..f73bb87064 100644
--- a/src/qt/optionsdialog.cpp
+++ b/src/qt/optionsdialog.cpp
@@ -327,7 +327,8 @@ QValidator::State ProxyAddressValidator::validate(QString &input, int &pos) cons
{
Q_UNUSED(pos);
// Validate the proxy
- proxyType addrProxy = proxyType(CService(input.toStdString(), 9050), true);
+ CService serv(LookupNumeric(input.toStdString().c_str(), 9050));
+ proxyType addrProxy = proxyType(serv, true);
if (addrProxy.IsValid())
return QValidator::Acceptable;
diff --git a/src/qt/optionsmodel.cpp b/src/qt/optionsmodel.cpp
index 684db71a8c..d33ab68277 100644
--- a/src/qt/optionsmodel.cpp
+++ b/src/qt/optionsmodel.cpp
@@ -15,6 +15,7 @@
#include "init.h"
#include "main.h" // For DEFAULT_SCRIPTCHECK_THREADS
#include "net.h"
+#include "netbase.h"
#include "txdb.h" // for -dbcache defaults
#ifdef ENABLE_WALLET
diff --git a/src/qt/rpcconsole.cpp b/src/qt/rpcconsole.cpp
index 650ff8b00d..bcaa9164c9 100644
--- a/src/qt/rpcconsole.cpp
+++ b/src/qt/rpcconsole.cpp
@@ -16,6 +16,7 @@
#include "bantablemodel.h"
#include "chainparams.h"
+#include "netbase.h"
#include "rpc/server.h"
#include "rpc/client.h"
#include "util.h"
@@ -898,7 +899,10 @@ void RPCConsole::banSelectedNode(int bantime)
int port = 0;
SplitHostPort(nStr, port, addr);
- CNode::Ban(CNetAddr(addr), BanReasonManuallyAdded, bantime);
+ CNetAddr resolved;
+ if(!LookupHost(addr.c_str(), resolved, false))
+ return;
+ CNode::Ban(resolved, BanReasonManuallyAdded, bantime);
clearSelectedNode();
clientModel->getBanTableModel()->refresh();
@@ -912,8 +916,9 @@ void RPCConsole::unbanSelectedNode()
// Get currently selected ban address
QString strNode = GUIUtil::getEntryData(ui->banlistWidget, 0, BanTableModel::Address);
- CSubNet possibleSubnet(strNode.toStdString());
+ CSubNet possibleSubnet;
+ LookupSubNet(strNode.toStdString().c_str(), possibleSubnet);
if (possibleSubnet.IsValid())
{
CNode::Unban(possibleSubnet);
diff --git a/src/rpc/net.cpp b/src/rpc/net.cpp
index b85c7b2e1a..58cf4a56e0 100644
--- a/src/rpc/net.cpp
+++ b/src/rpc/net.cpp
@@ -494,10 +494,13 @@ UniValue setban(const UniValue& params, bool fHelp)
if (params[0].get_str().find("/") != string::npos)
isSubnet = true;
- if (!isSubnet)
- netAddr = CNetAddr(params[0].get_str());
+ if (!isSubnet) {
+ CNetAddr resolved;
+ LookupHost(params[0].get_str().c_str(), resolved, false);
+ netAddr = resolved;
+ }
else
- subNet = CSubNet(params[0].get_str());
+ LookupSubNet(params[0].get_str().c_str(), subNet);
if (! (isSubnet ? subNet.IsValid() : netAddr.IsValid()) )
throw JSONRPCError(RPC_CLIENT_NODE_ALREADY_ADDED, "Error: Invalid IP/Subnet");
diff --git a/src/test/addrman_tests.cpp b/src/test/addrman_tests.cpp
index b6cec24b57..5f150e4812 100644
--- a/src/test/addrman_tests.cpp
+++ b/src/test/addrman_tests.cpp
@@ -7,6 +7,7 @@
#include <boost/test/unit_test.hpp>
#include "hash.h"
+#include "netbase.h"
#include "random.h"
using namespace std;
@@ -50,6 +51,30 @@ public:
}
};
+static CNetAddr ResolveIP(const char* ip)
+{
+ CNetAddr addr;
+ BOOST_CHECK_MESSAGE(LookupHost(ip, addr, false), strprintf("failed to resolve: %s", ip));
+ return addr;
+}
+
+static CNetAddr ResolveIP(std::string ip)
+{
+ return ResolveIP(ip.c_str());
+}
+
+static CService ResolveService(const char* ip, int port = 0)
+{
+ CService serv;
+ BOOST_CHECK_MESSAGE(Lookup(ip, serv, port, false), strprintf("failed to resolve: %s:%i", ip, port));
+ return serv;
+}
+
+static CService ResolveService(std::string ip, int port = 0)
+{
+ return ResolveService(ip.c_str(), port);
+}
+
BOOST_FIXTURE_TEST_SUITE(addrman_tests, BasicTestingSetup)
BOOST_AUTO_TEST_CASE(addrman_simple)
@@ -59,7 +84,7 @@ BOOST_AUTO_TEST_CASE(addrman_simple)
// Set addrman addr placement to be deterministic.
addrman.MakeDeterministic();
- CNetAddr source = CNetAddr("252.2.2.2");
+ CNetAddr source = ResolveIP("252.2.2.2");
// Test 1: Does Addrman respond correctly when empty.
BOOST_CHECK(addrman.size() == 0);
@@ -67,7 +92,7 @@ BOOST_AUTO_TEST_CASE(addrman_simple)
BOOST_CHECK(addr_null.ToString() == "[::]:0");
// Test 2: Does Addrman::Add work as expected.
- CService addr1 = CService("250.1.1.1", 8333);
+ CService addr1 = ResolveService("250.1.1.1", 8333);
addrman.Add(CAddress(addr1, NODE_NONE), source);
BOOST_CHECK(addrman.size() == 1);
CAddrInfo addr_ret1 = addrman.Select();
@@ -75,14 +100,14 @@ BOOST_AUTO_TEST_CASE(addrman_simple)
// Test 3: Does IP address deduplication work correctly.
// Expected dup IP should not be added.
- CService addr1_dup = CService("250.1.1.1", 8333);
+ CService addr1_dup = ResolveService("250.1.1.1", 8333);
addrman.Add(CAddress(addr1_dup, NODE_NONE), source);
BOOST_CHECK(addrman.size() == 1);
// Test 5: New table has one addr and we add a diff addr we should
// have two addrs.
- CService addr2 = CService("250.1.1.2", 8333);
+ CService addr2 = ResolveService("250.1.1.2", 8333);
addrman.Add(CAddress(addr2, NODE_NONE), source);
BOOST_CHECK(addrman.size() == 2);
@@ -100,16 +125,16 @@ BOOST_AUTO_TEST_CASE(addrman_ports)
// Set addrman addr placement to be deterministic.
addrman.MakeDeterministic();
- CNetAddr source = CNetAddr("252.2.2.2");
+ CNetAddr source = ResolveIP("252.2.2.2");
BOOST_CHECK(addrman.size() == 0);
// Test 7; Addr with same IP but diff port does not replace existing addr.
- CService addr1 = CService("250.1.1.1", 8333);
+ CService addr1 = ResolveService("250.1.1.1", 8333);
addrman.Add(CAddress(addr1, NODE_NONE), source);
BOOST_CHECK(addrman.size() == 1);
- CService addr1_port = CService("250.1.1.1", 8334);
+ CService addr1_port = ResolveService("250.1.1.1", 8334);
addrman.Add(CAddress(addr1_port, NODE_NONE), source);
BOOST_CHECK(addrman.size() == 1);
CAddrInfo addr_ret2 = addrman.Select();
@@ -132,10 +157,10 @@ BOOST_AUTO_TEST_CASE(addrman_select)
// Set addrman addr placement to be deterministic.
addrman.MakeDeterministic();
- CNetAddr source = CNetAddr("252.2.2.2");
+ CNetAddr source = ResolveIP("252.2.2.2");
// Test 9: Select from new with 1 addr in new.
- CService addr1 = CService("250.1.1.1", 8333);
+ CService addr1 = ResolveService("250.1.1.1", 8333);
addrman.Add(CAddress(addr1, NODE_NONE), source);
BOOST_CHECK(addrman.size() == 1);
@@ -156,24 +181,24 @@ BOOST_AUTO_TEST_CASE(addrman_select)
// Add three addresses to new table.
- CService addr2 = CService("250.3.1.1", 8333);
- CService addr3 = CService("250.3.2.2", 9999);
- CService addr4 = CService("250.3.3.3", 9999);
+ CService addr2 = ResolveService("250.3.1.1", 8333);
+ CService addr3 = ResolveService("250.3.2.2", 9999);
+ CService addr4 = ResolveService("250.3.3.3", 9999);
- addrman.Add(CAddress(addr2, NODE_NONE), CService("250.3.1.1", 8333));
- addrman.Add(CAddress(addr3, NODE_NONE), CService("250.3.1.1", 8333));
- addrman.Add(CAddress(addr4, NODE_NONE), CService("250.4.1.1", 8333));
+ addrman.Add(CAddress(addr2, NODE_NONE), ResolveService("250.3.1.1", 8333));
+ addrman.Add(CAddress(addr3, NODE_NONE), ResolveService("250.3.1.1", 8333));
+ addrman.Add(CAddress(addr4, NODE_NONE), ResolveService("250.4.1.1", 8333));
// Add three addresses to tried table.
- CService addr5 = CService("250.4.4.4", 8333);
- CService addr6 = CService("250.4.5.5", 7777);
- CService addr7 = CService("250.4.6.6", 8333);
+ CService addr5 = ResolveService("250.4.4.4", 8333);
+ CService addr6 = ResolveService("250.4.5.5", 7777);
+ CService addr7 = ResolveService("250.4.6.6", 8333);
- addrman.Add(CAddress(addr5, NODE_NONE), CService("250.3.1.1", 8333));
+ addrman.Add(CAddress(addr5, NODE_NONE), ResolveService("250.3.1.1", 8333));
addrman.Good(CAddress(addr5, NODE_NONE));
- addrman.Add(CAddress(addr6, NODE_NONE), CService("250.3.1.1", 8333));
+ addrman.Add(CAddress(addr6, NODE_NONE), ResolveService("250.3.1.1", 8333));
addrman.Good(CAddress(addr6, NODE_NONE));
- addrman.Add(CAddress(addr7, NODE_NONE), CService("250.1.1.3", 8333));
+ addrman.Add(CAddress(addr7, NODE_NONE), ResolveService("250.1.1.3", 8333));
addrman.Good(CAddress(addr7, NODE_NONE));
// Test 11: 6 addrs + 1 addr from last test = 7.
@@ -193,12 +218,12 @@ BOOST_AUTO_TEST_CASE(addrman_new_collisions)
// Set addrman addr placement to be deterministic.
addrman.MakeDeterministic();
- CNetAddr source = CNetAddr("252.2.2.2");
+ CNetAddr source = ResolveIP("252.2.2.2");
BOOST_CHECK(addrman.size() == 0);
for (unsigned int i = 1; i < 18; i++) {
- CService addr = CService("250.1.1." + boost::to_string(i));
+ CService addr = ResolveService("250.1.1." + boost::to_string(i));
addrman.Add(CAddress(addr, NODE_NONE), source);
//Test 13: No collision in new table yet.
@@ -206,11 +231,11 @@ BOOST_AUTO_TEST_CASE(addrman_new_collisions)
}
//Test 14: new table collision!
- CService addr1 = CService("250.1.1.18");
+ CService addr1 = ResolveService("250.1.1.18");
addrman.Add(CAddress(addr1, NODE_NONE), source);
BOOST_CHECK(addrman.size() == 17);
- CService addr2 = CService("250.1.1.19");
+ CService addr2 = ResolveService("250.1.1.19");
addrman.Add(CAddress(addr2, NODE_NONE), source);
BOOST_CHECK(addrman.size() == 18);
}
@@ -222,12 +247,12 @@ BOOST_AUTO_TEST_CASE(addrman_tried_collisions)
// Set addrman addr placement to be deterministic.
addrman.MakeDeterministic();
- CNetAddr source = CNetAddr("252.2.2.2");
+ CNetAddr source = ResolveIP("252.2.2.2");
BOOST_CHECK(addrman.size() == 0);
for (unsigned int i = 1; i < 80; i++) {
- CService addr = CService("250.1.1." + boost::to_string(i));
+ CService addr = ResolveService("250.1.1." + boost::to_string(i));
addrman.Add(CAddress(addr, NODE_NONE), source);
addrman.Good(CAddress(addr, NODE_NONE));
@@ -237,11 +262,11 @@ BOOST_AUTO_TEST_CASE(addrman_tried_collisions)
}
//Test 16: tried table collision!
- CService addr1 = CService("250.1.1.80");
+ CService addr1 = ResolveService("250.1.1.80");
addrman.Add(CAddress(addr1, NODE_NONE), source);
BOOST_CHECK(addrman.size() == 79);
- CService addr2 = CService("250.1.1.81");
+ CService addr2 = ResolveService("250.1.1.81");
addrman.Add(CAddress(addr2, NODE_NONE), source);
BOOST_CHECK(addrman.size() == 80);
}
@@ -255,12 +280,12 @@ BOOST_AUTO_TEST_CASE(addrman_find)
BOOST_CHECK(addrman.size() == 0);
- CAddress addr1 = CAddress(CService("250.1.2.1", 8333), NODE_NONE);
- CAddress addr2 = CAddress(CService("250.1.2.1", 9999), NODE_NONE);
- CAddress addr3 = CAddress(CService("251.255.2.1", 8333), NODE_NONE);
+ CAddress addr1 = CAddress(ResolveService("250.1.2.1", 8333), NODE_NONE);
+ CAddress addr2 = CAddress(ResolveService("250.1.2.1", 9999), NODE_NONE);
+ CAddress addr3 = CAddress(ResolveService("251.255.2.1", 8333), NODE_NONE);
- CNetAddr source1 = CNetAddr("250.1.2.1");
- CNetAddr source2 = CNetAddr("250.1.2.2");
+ CNetAddr source1 = ResolveIP("250.1.2.1");
+ CNetAddr source2 = ResolveIP("250.1.2.2");
addrman.Add(addr1, source1);
addrman.Add(addr2, source2);
@@ -294,8 +319,8 @@ BOOST_AUTO_TEST_CASE(addrman_create)
BOOST_CHECK(addrman.size() == 0);
- CAddress addr1 = CAddress(CService("250.1.2.1", 8333), NODE_NONE);
- CNetAddr source1 = CNetAddr("250.1.2.1");
+ CAddress addr1 = CAddress(ResolveService("250.1.2.1", 8333), NODE_NONE);
+ CNetAddr source1 = ResolveIP("250.1.2.1");
int nId;
CAddrInfo* pinfo = addrman.Create(addr1, source1, &nId);
@@ -317,8 +342,8 @@ BOOST_AUTO_TEST_CASE(addrman_delete)
BOOST_CHECK(addrman.size() == 0);
- CAddress addr1 = CAddress(CService("250.1.2.1", 8333), NODE_NONE);
- CNetAddr source1 = CNetAddr("250.1.2.1");
+ CAddress addr1 = CAddress(ResolveService("250.1.2.1", 8333), NODE_NONE);
+ CNetAddr source1 = ResolveIP("250.1.2.1");
int nId;
addrman.Create(addr1, source1, &nId);
@@ -344,18 +369,18 @@ BOOST_AUTO_TEST_CASE(addrman_getaddr)
vector<CAddress> vAddr1 = addrman.GetAddr();
BOOST_CHECK(vAddr1.size() == 0);
- CAddress addr1 = CAddress(CService("250.250.2.1", 8333), NODE_NONE);
+ CAddress addr1 = CAddress(ResolveService("250.250.2.1", 8333), NODE_NONE);
addr1.nTime = GetAdjustedTime(); // Set time so isTerrible = false
- CAddress addr2 = CAddress(CService("250.251.2.2", 9999), NODE_NONE);
+ CAddress addr2 = CAddress(ResolveService("250.251.2.2", 9999), NODE_NONE);
addr2.nTime = GetAdjustedTime();
- CAddress addr3 = CAddress(CService("251.252.2.3", 8333), NODE_NONE);
+ CAddress addr3 = CAddress(ResolveService("251.252.2.3", 8333), NODE_NONE);
addr3.nTime = GetAdjustedTime();
- CAddress addr4 = CAddress(CService("252.253.3.4", 8333), NODE_NONE);
+ CAddress addr4 = CAddress(ResolveService("252.253.3.4", 8333), NODE_NONE);
addr4.nTime = GetAdjustedTime();
- CAddress addr5 = CAddress(CService("252.254.4.5", 8333), NODE_NONE);
+ CAddress addr5 = CAddress(ResolveService("252.254.4.5", 8333), NODE_NONE);
addr5.nTime = GetAdjustedTime();
- CNetAddr source1 = CNetAddr("250.1.2.1");
- CNetAddr source2 = CNetAddr("250.2.3.3");
+ CNetAddr source1 = ResolveIP("250.1.2.1");
+ CNetAddr source2 = ResolveIP("250.2.3.3");
// Test 23: Ensure GetAddr works with new addresses.
addrman.Add(addr1, source1);
@@ -378,11 +403,11 @@ BOOST_AUTO_TEST_CASE(addrman_getaddr)
int octet2 = (i / 256) % 256;
int octet3 = (i / (256 * 2)) % 256;
string strAddr = boost::to_string(octet1) + "." + boost::to_string(octet2) + "." + boost::to_string(octet3) + ".23";
- CAddress addr = CAddress(CService(strAddr), NODE_NONE);
+ CAddress addr = CAddress(ResolveService(strAddr), NODE_NONE);
// Ensure that for all addrs in addrman, isTerrible == false.
addr.nTime = GetAdjustedTime();
- addrman.Add(addr, CNetAddr(strAddr));
+ addrman.Add(addr, ResolveIP(strAddr));
if (i % 8 == 0)
addrman.Good(addr);
}
@@ -403,10 +428,10 @@ BOOST_AUTO_TEST_CASE(caddrinfo_get_tried_bucket)
// Set addrman addr placement to be deterministic.
addrman.MakeDeterministic();
- CAddress addr1 = CAddress(CService("250.1.1.1", 8333), NODE_NONE);
- CAddress addr2 = CAddress(CService("250.1.1.1", 9999), NODE_NONE);
+ CAddress addr1 = CAddress(ResolveService("250.1.1.1", 8333), NODE_NONE);
+ CAddress addr2 = CAddress(ResolveService("250.1.1.1", 9999), NODE_NONE);
- CNetAddr source1 = CNetAddr("250.1.1.1");
+ CNetAddr source1 = ResolveIP("250.1.1.1");
CAddrInfo info1 = CAddrInfo(addr1, source1);
@@ -431,8 +456,8 @@ BOOST_AUTO_TEST_CASE(caddrinfo_get_tried_bucket)
set<int> buckets;
for (int i = 0; i < 255; i++) {
CAddrInfo infoi = CAddrInfo(
- CAddress(CService("250.1.1." + boost::to_string(i)), NODE_NONE),
- CNetAddr("250.1.1." + boost::to_string(i)));
+ CAddress(ResolveService("250.1.1." + boost::to_string(i)), NODE_NONE),
+ ResolveIP("250.1.1." + boost::to_string(i)));
int bucket = infoi.GetTriedBucket(nKey1);
buckets.insert(bucket);
}
@@ -443,8 +468,8 @@ BOOST_AUTO_TEST_CASE(caddrinfo_get_tried_bucket)
buckets.clear();
for (int j = 0; j < 255; j++) {
CAddrInfo infoj = CAddrInfo(
- CAddress(CService("250." + boost::to_string(j) + ".1.1"), NODE_NONE),
- CNetAddr("250." + boost::to_string(j) + ".1.1"));
+ CAddress(ResolveService("250." + boost::to_string(j) + ".1.1"), NODE_NONE),
+ ResolveIP("250." + boost::to_string(j) + ".1.1"));
int bucket = infoj.GetTriedBucket(nKey1);
buckets.insert(bucket);
}
@@ -460,10 +485,10 @@ BOOST_AUTO_TEST_CASE(caddrinfo_get_new_bucket)
// Set addrman addr placement to be deterministic.
addrman.MakeDeterministic();
- CAddress addr1 = CAddress(CService("250.1.2.1", 8333), NODE_NONE);
- CAddress addr2 = CAddress(CService("250.1.2.1", 9999), NODE_NONE);
+ CAddress addr1 = CAddress(ResolveService("250.1.2.1", 8333), NODE_NONE);
+ CAddress addr2 = CAddress(ResolveService("250.1.2.1", 9999), NODE_NONE);
- CNetAddr source1 = CNetAddr("250.1.2.1");
+ CNetAddr source1 = ResolveIP("250.1.2.1");
CAddrInfo info1 = CAddrInfo(addr1, source1);
@@ -484,8 +509,8 @@ BOOST_AUTO_TEST_CASE(caddrinfo_get_new_bucket)
set<int> buckets;
for (int i = 0; i < 255; i++) {
CAddrInfo infoi = CAddrInfo(
- CAddress(CService("250.1.1." + boost::to_string(i)), NODE_NONE),
- CNetAddr("250.1.1." + boost::to_string(i)));
+ CAddress(ResolveService("250.1.1." + boost::to_string(i)), NODE_NONE),
+ ResolveIP("250.1.1." + boost::to_string(i)));
int bucket = infoi.GetNewBucket(nKey1);
buckets.insert(bucket);
}
@@ -496,9 +521,9 @@ BOOST_AUTO_TEST_CASE(caddrinfo_get_new_bucket)
buckets.clear();
for (int j = 0; j < 4 * 255; j++) {
CAddrInfo infoj = CAddrInfo(CAddress(
- CService(
+ ResolveService(
boost::to_string(250 + (j / 255)) + "." + boost::to_string(j % 256) + ".1.1"), NODE_NONE),
- CNetAddr("251.4.1.1"));
+ ResolveIP("251.4.1.1"));
int bucket = infoj.GetNewBucket(nKey1);
buckets.insert(bucket);
}
@@ -509,8 +534,8 @@ BOOST_AUTO_TEST_CASE(caddrinfo_get_new_bucket)
buckets.clear();
for (int p = 0; p < 255; p++) {
CAddrInfo infoj = CAddrInfo(
- CAddress(CService("250.1.1.1"), NODE_NONE),
- CNetAddr("250." + boost::to_string(p) + ".1.1"));
+ CAddress(ResolveService("250.1.1.1"), NODE_NONE),
+ ResolveIP("250." + boost::to_string(p) + ".1.1"));
int bucket = infoj.GetNewBucket(nKey1);
buckets.insert(bucket);
}
diff --git a/src/test/net_tests.cpp b/src/test/net_tests.cpp
index d005d6a163..6511e6ffa2 100644
--- a/src/test/net_tests.cpp
+++ b/src/test/net_tests.cpp
@@ -9,6 +9,7 @@
#include "serialize.h"
#include "streams.h"
#include "net.h"
+#include "netbase.h"
#include "chainparams.h"
using namespace std;
@@ -51,8 +52,12 @@ public:
int nUBuckets = ADDRMAN_NEW_BUCKET_COUNT ^ (1 << 30);
s << nUBuckets;
- CAddress addr = CAddress(CService("252.1.1.1", 7777), NODE_NONE);
- CAddrInfo info = CAddrInfo(addr, CNetAddr("252.2.2.2"));
+ CService serv;
+ Lookup("252.1.1.1", serv, 7777, false);
+ CAddress addr = CAddress(serv, NODE_NONE);
+ CNetAddr resolved;
+ LookupHost("252.2.2.2", resolved, false);
+ CAddrInfo info = CAddrInfo(addr, resolved);
s << info;
}
};
@@ -74,14 +79,17 @@ BOOST_AUTO_TEST_CASE(caddrdb_read)
CAddrManUncorrupted addrmanUncorrupted;
addrmanUncorrupted.MakeDeterministic();
- CService addr1 = CService("250.7.1.1", 8333);
- CService addr2 = CService("250.7.2.2", 9999);
- CService addr3 = CService("250.7.3.3", 9999);
+ CService addr1, addr2, addr3;
+ Lookup("250.7.1.1", addr1, 8333, false);
+ Lookup("250.7.2.2", addr2, 9999, false);
+ Lookup("250.7.3.3", addr3, 9999, false);
// Add three addresses to new table.
- addrmanUncorrupted.Add(CAddress(addr1, NODE_NONE), CService("252.5.1.1", 8333));
- addrmanUncorrupted.Add(CAddress(addr2, NODE_NONE), CService("252.5.1.1", 8333));
- addrmanUncorrupted.Add(CAddress(addr3, NODE_NONE), CService("252.5.1.1", 8333));
+ CService source;
+ Lookup("252.5.1.1", source, 8333, false);
+ addrmanUncorrupted.Add(CAddress(addr1, NODE_NONE), source);
+ addrmanUncorrupted.Add(CAddress(addr2, NODE_NONE), source);
+ addrmanUncorrupted.Add(CAddress(addr3, NODE_NONE), source);
// Test that the de-serialization does not throw an exception.
CDataStream ssPeers1 = AddrmanToStream(addrmanUncorrupted);
diff --git a/src/test/netbase_tests.cpp b/src/test/netbase_tests.cpp
index 4168f75e9a..18ad5dc90b 100644
--- a/src/test/netbase_tests.cpp
+++ b/src/test/netbase_tests.cpp
@@ -14,37 +14,54 @@ using namespace std;
BOOST_FIXTURE_TEST_SUITE(netbase_tests, BasicTestingSetup)
+static CNetAddr ResolveIP(const char* ip)
+{
+ CNetAddr addr;
+ LookupHost(ip, addr, false);
+ return addr;
+}
+
+static CSubNet ResolveSubNet(const char* subnet)
+{
+ CSubNet ret;
+ LookupSubNet(subnet, ret);
+ return ret;
+}
+
BOOST_AUTO_TEST_CASE(netbase_networks)
{
- BOOST_CHECK(CNetAddr("127.0.0.1").GetNetwork() == NET_UNROUTABLE);
- BOOST_CHECK(CNetAddr("::1").GetNetwork() == NET_UNROUTABLE);
- BOOST_CHECK(CNetAddr("8.8.8.8").GetNetwork() == NET_IPV4);
- BOOST_CHECK(CNetAddr("2001::8888").GetNetwork() == NET_IPV6);
- BOOST_CHECK(CNetAddr("FD87:D87E:EB43:edb1:8e4:3588:e546:35ca").GetNetwork() == NET_TOR);
+ BOOST_CHECK(ResolveIP("127.0.0.1").GetNetwork() == NET_UNROUTABLE);
+ BOOST_CHECK(ResolveIP("::1").GetNetwork() == NET_UNROUTABLE);
+ BOOST_CHECK(ResolveIP("8.8.8.8").GetNetwork() == NET_IPV4);
+ BOOST_CHECK(ResolveIP("2001::8888").GetNetwork() == NET_IPV6);
+ BOOST_CHECK(ResolveIP("FD87:D87E:EB43:edb1:8e4:3588:e546:35ca").GetNetwork() == NET_TOR);
+
}
BOOST_AUTO_TEST_CASE(netbase_properties)
{
- BOOST_CHECK(CNetAddr("127.0.0.1").IsIPv4());
- BOOST_CHECK(CNetAddr("::FFFF:192.168.1.1").IsIPv4());
- BOOST_CHECK(CNetAddr("::1").IsIPv6());
- BOOST_CHECK(CNetAddr("10.0.0.1").IsRFC1918());
- BOOST_CHECK(CNetAddr("192.168.1.1").IsRFC1918());
- BOOST_CHECK(CNetAddr("172.31.255.255").IsRFC1918());
- BOOST_CHECK(CNetAddr("2001:0DB8::").IsRFC3849());
- BOOST_CHECK(CNetAddr("169.254.1.1").IsRFC3927());
- BOOST_CHECK(CNetAddr("2002::1").IsRFC3964());
- BOOST_CHECK(CNetAddr("FC00::").IsRFC4193());
- BOOST_CHECK(CNetAddr("2001::2").IsRFC4380());
- BOOST_CHECK(CNetAddr("2001:10::").IsRFC4843());
- BOOST_CHECK(CNetAddr("FE80::").IsRFC4862());
- BOOST_CHECK(CNetAddr("64:FF9B::").IsRFC6052());
- BOOST_CHECK(CNetAddr("FD87:D87E:EB43:edb1:8e4:3588:e546:35ca").IsTor());
- BOOST_CHECK(CNetAddr("127.0.0.1").IsLocal());
- BOOST_CHECK(CNetAddr("::1").IsLocal());
- BOOST_CHECK(CNetAddr("8.8.8.8").IsRoutable());
- BOOST_CHECK(CNetAddr("2001::1").IsRoutable());
- BOOST_CHECK(CNetAddr("127.0.0.1").IsValid());
+
+ BOOST_CHECK(ResolveIP("127.0.0.1").IsIPv4());
+ BOOST_CHECK(ResolveIP("::FFFF:192.168.1.1").IsIPv4());
+ BOOST_CHECK(ResolveIP("::1").IsIPv6());
+ BOOST_CHECK(ResolveIP("10.0.0.1").IsRFC1918());
+ BOOST_CHECK(ResolveIP("192.168.1.1").IsRFC1918());
+ BOOST_CHECK(ResolveIP("172.31.255.255").IsRFC1918());
+ BOOST_CHECK(ResolveIP("2001:0DB8::").IsRFC3849());
+ BOOST_CHECK(ResolveIP("169.254.1.1").IsRFC3927());
+ BOOST_CHECK(ResolveIP("2002::1").IsRFC3964());
+ BOOST_CHECK(ResolveIP("FC00::").IsRFC4193());
+ BOOST_CHECK(ResolveIP("2001::2").IsRFC4380());
+ BOOST_CHECK(ResolveIP("2001:10::").IsRFC4843());
+ BOOST_CHECK(ResolveIP("FE80::").IsRFC4862());
+ BOOST_CHECK(ResolveIP("64:FF9B::").IsRFC6052());
+ BOOST_CHECK(ResolveIP("FD87:D87E:EB43:edb1:8e4:3588:e546:35ca").IsTor());
+ BOOST_CHECK(ResolveIP("127.0.0.1").IsLocal());
+ BOOST_CHECK(ResolveIP("::1").IsLocal());
+ BOOST_CHECK(ResolveIP("8.8.8.8").IsRoutable());
+ BOOST_CHECK(ResolveIP("2001::1").IsRoutable());
+ BOOST_CHECK(ResolveIP("127.0.0.1").IsValid());
+
}
bool static TestSplitHost(string test, string host, int port)
@@ -76,9 +93,7 @@ BOOST_AUTO_TEST_CASE(netbase_splithost)
bool static TestParse(string src, string canon)
{
- CService addr;
- if (!LookupNumeric(src.c_str(), addr, 65535))
- return canon == "";
+ CService addr(LookupNumeric(src.c_str(), 65535));
return canon == addr.ToString();
}
@@ -90,165 +105,185 @@ BOOST_AUTO_TEST_CASE(netbase_lookupnumeric)
BOOST_CHECK(TestParse("::", "[::]:65535"));
BOOST_CHECK(TestParse("[::]:8333", "[::]:8333"));
BOOST_CHECK(TestParse("[127.0.0.1]", "127.0.0.1:65535"));
- BOOST_CHECK(TestParse(":::", ""));
+ BOOST_CHECK(TestParse(":::", "[::]:0"));
}
BOOST_AUTO_TEST_CASE(onioncat_test)
{
+
// values from https://web.archive.org/web/20121122003543/http://www.cypherpunk.at/onioncat/wiki/OnionCat
- CNetAddr addr1("5wyqrzbvrdsumnok.onion");
- CNetAddr addr2("FD87:D87E:EB43:edb1:8e4:3588:e546:35ca");
+ CNetAddr addr1(ResolveIP("5wyqrzbvrdsumnok.onion"));
+ CNetAddr addr2(ResolveIP("FD87:D87E:EB43:edb1:8e4:3588:e546:35ca"));
BOOST_CHECK(addr1 == addr2);
BOOST_CHECK(addr1.IsTor());
BOOST_CHECK(addr1.ToStringIP() == "5wyqrzbvrdsumnok.onion");
BOOST_CHECK(addr1.IsRoutable());
+
}
BOOST_AUTO_TEST_CASE(subnet_test)
{
- BOOST_CHECK(CSubNet("1.2.3.0/24") == CSubNet("1.2.3.0/255.255.255.0"));
- BOOST_CHECK(CSubNet("1.2.3.0/24") != CSubNet("1.2.4.0/255.255.255.0"));
- BOOST_CHECK(CSubNet("1.2.3.0/24").Match(CNetAddr("1.2.3.4")));
- BOOST_CHECK(!CSubNet("1.2.2.0/24").Match(CNetAddr("1.2.3.4")));
- BOOST_CHECK(CSubNet("1.2.3.4").Match(CNetAddr("1.2.3.4")));
- BOOST_CHECK(CSubNet("1.2.3.4/32").Match(CNetAddr("1.2.3.4")));
- BOOST_CHECK(!CSubNet("1.2.3.4").Match(CNetAddr("5.6.7.8")));
- BOOST_CHECK(!CSubNet("1.2.3.4/32").Match(CNetAddr("5.6.7.8")));
- BOOST_CHECK(CSubNet("::ffff:127.0.0.1").Match(CNetAddr("127.0.0.1")));
- BOOST_CHECK(CSubNet("1:2:3:4:5:6:7:8").Match(CNetAddr("1:2:3:4:5:6:7:8")));
- BOOST_CHECK(!CSubNet("1:2:3:4:5:6:7:8").Match(CNetAddr("1:2:3:4:5:6:7:9")));
- BOOST_CHECK(CSubNet("1:2:3:4:5:6:7:0/112").Match(CNetAddr("1:2:3:4:5:6:7:1234")));
- BOOST_CHECK(CSubNet("192.168.0.1/24").Match(CNetAddr("192.168.0.2")));
- BOOST_CHECK(CSubNet("192.168.0.20/29").Match(CNetAddr("192.168.0.18")));
- BOOST_CHECK(CSubNet("1.2.2.1/24").Match(CNetAddr("1.2.2.4")));
- BOOST_CHECK(CSubNet("1.2.2.110/31").Match(CNetAddr("1.2.2.111")));
- BOOST_CHECK(CSubNet("1.2.2.20/26").Match(CNetAddr("1.2.2.63")));
+
+ BOOST_CHECK(ResolveSubNet("1.2.3.0/24") == ResolveSubNet("1.2.3.0/255.255.255.0"));
+ BOOST_CHECK(ResolveSubNet("1.2.3.0/24") != ResolveSubNet("1.2.4.0/255.255.255.0"));
+ BOOST_CHECK(ResolveSubNet("1.2.3.0/24").Match(ResolveIP("1.2.3.4")));
+ BOOST_CHECK(!ResolveSubNet("1.2.2.0/24").Match(ResolveIP("1.2.3.4")));
+ BOOST_CHECK(ResolveSubNet("1.2.3.4").Match(ResolveIP("1.2.3.4")));
+ BOOST_CHECK(ResolveSubNet("1.2.3.4/32").Match(ResolveIP("1.2.3.4")));
+ BOOST_CHECK(!ResolveSubNet("1.2.3.4").Match(ResolveIP("5.6.7.8")));
+ BOOST_CHECK(!ResolveSubNet("1.2.3.4/32").Match(ResolveIP("5.6.7.8")));
+ BOOST_CHECK(ResolveSubNet("::ffff:127.0.0.1").Match(ResolveIP("127.0.0.1")));
+ BOOST_CHECK(ResolveSubNet("1:2:3:4:5:6:7:8").Match(ResolveIP("1:2:3:4:5:6:7:8")));
+ BOOST_CHECK(!ResolveSubNet("1:2:3:4:5:6:7:8").Match(ResolveIP("1:2:3:4:5:6:7:9")));
+ BOOST_CHECK(ResolveSubNet("1:2:3:4:5:6:7:0/112").Match(ResolveIP("1:2:3:4:5:6:7:1234")));
+ BOOST_CHECK(ResolveSubNet("192.168.0.1/24").Match(ResolveIP("192.168.0.2")));
+ BOOST_CHECK(ResolveSubNet("192.168.0.20/29").Match(ResolveIP("192.168.0.18")));
+ BOOST_CHECK(ResolveSubNet("1.2.2.1/24").Match(ResolveIP("1.2.2.4")));
+ BOOST_CHECK(ResolveSubNet("1.2.2.110/31").Match(ResolveIP("1.2.2.111")));
+ BOOST_CHECK(ResolveSubNet("1.2.2.20/26").Match(ResolveIP("1.2.2.63")));
// All-Matching IPv6 Matches arbitrary IPv4 and IPv6
- BOOST_CHECK(CSubNet("::/0").Match(CNetAddr("1:2:3:4:5:6:7:1234")));
- BOOST_CHECK(CSubNet("::/0").Match(CNetAddr("1.2.3.4")));
+ BOOST_CHECK(ResolveSubNet("::/0").Match(ResolveIP("1:2:3:4:5:6:7:1234")));
+ BOOST_CHECK(ResolveSubNet("::/0").Match(ResolveIP("1.2.3.4")));
// All-Matching IPv4 does not Match IPv6
- BOOST_CHECK(!CSubNet("0.0.0.0/0").Match(CNetAddr("1:2:3:4:5:6:7:1234")));
+ BOOST_CHECK(!ResolveSubNet("0.0.0.0/0").Match(ResolveIP("1:2:3:4:5:6:7:1234")));
// Invalid subnets Match nothing (not even invalid addresses)
- BOOST_CHECK(!CSubNet().Match(CNetAddr("1.2.3.4")));
- BOOST_CHECK(!CSubNet("").Match(CNetAddr("4.5.6.7")));
- BOOST_CHECK(!CSubNet("bloop").Match(CNetAddr("0.0.0.0")));
- BOOST_CHECK(!CSubNet("bloop").Match(CNetAddr("hab")));
+ BOOST_CHECK(!CSubNet().Match(ResolveIP("1.2.3.4")));
+ BOOST_CHECK(!ResolveSubNet("").Match(ResolveIP("4.5.6.7")));
+ BOOST_CHECK(!ResolveSubNet("bloop").Match(ResolveIP("0.0.0.0")));
+ BOOST_CHECK(!ResolveSubNet("bloop").Match(ResolveIP("hab")));
// Check valid/invalid
- BOOST_CHECK(CSubNet("1.2.3.0/0").IsValid());
- BOOST_CHECK(!CSubNet("1.2.3.0/-1").IsValid());
- BOOST_CHECK(CSubNet("1.2.3.0/32").IsValid());
- BOOST_CHECK(!CSubNet("1.2.3.0/33").IsValid());
- BOOST_CHECK(CSubNet("1:2:3:4:5:6:7:8/0").IsValid());
- BOOST_CHECK(CSubNet("1:2:3:4:5:6:7:8/33").IsValid());
- BOOST_CHECK(!CSubNet("1:2:3:4:5:6:7:8/-1").IsValid());
- BOOST_CHECK(CSubNet("1:2:3:4:5:6:7:8/128").IsValid());
- BOOST_CHECK(!CSubNet("1:2:3:4:5:6:7:8/129").IsValid());
- BOOST_CHECK(!CSubNet("fuzzy").IsValid());
+ BOOST_CHECK(ResolveSubNet("1.2.3.0/0").IsValid());
+ BOOST_CHECK(!ResolveSubNet("1.2.3.0/-1").IsValid());
+ BOOST_CHECK(ResolveSubNet("1.2.3.0/32").IsValid());
+ BOOST_CHECK(!ResolveSubNet("1.2.3.0/33").IsValid());
+ BOOST_CHECK(ResolveSubNet("1:2:3:4:5:6:7:8/0").IsValid());
+ BOOST_CHECK(ResolveSubNet("1:2:3:4:5:6:7:8/33").IsValid());
+ BOOST_CHECK(!ResolveSubNet("1:2:3:4:5:6:7:8/-1").IsValid());
+ BOOST_CHECK(ResolveSubNet("1:2:3:4:5:6:7:8/128").IsValid());
+ BOOST_CHECK(!ResolveSubNet("1:2:3:4:5:6:7:8/129").IsValid());
+ BOOST_CHECK(!ResolveSubNet("fuzzy").IsValid());
//CNetAddr constructor test
- BOOST_CHECK(CSubNet(CNetAddr("127.0.0.1")).IsValid());
- BOOST_CHECK(CSubNet(CNetAddr("127.0.0.1")).Match(CNetAddr("127.0.0.1")));
- BOOST_CHECK(!CSubNet(CNetAddr("127.0.0.1")).Match(CNetAddr("127.0.0.2")));
- BOOST_CHECK(CSubNet(CNetAddr("127.0.0.1")).ToString() == "127.0.0.1/32");
+ BOOST_CHECK(CSubNet(ResolveIP("127.0.0.1")).IsValid());
+ BOOST_CHECK(CSubNet(ResolveIP("127.0.0.1")).Match(ResolveIP("127.0.0.1")));
+ BOOST_CHECK(!CSubNet(ResolveIP("127.0.0.1")).Match(ResolveIP("127.0.0.2")));
+ BOOST_CHECK(CSubNet(ResolveIP("127.0.0.1")).ToString() == "127.0.0.1/32");
- BOOST_CHECK(CSubNet(CNetAddr("1:2:3:4:5:6:7:8")).IsValid());
- BOOST_CHECK(CSubNet(CNetAddr("1:2:3:4:5:6:7:8")).Match(CNetAddr("1:2:3:4:5:6:7:8")));
- BOOST_CHECK(!CSubNet(CNetAddr("1:2:3:4:5:6:7:8")).Match(CNetAddr("1:2:3:4:5:6:7:9")));
- BOOST_CHECK(CSubNet(CNetAddr("1:2:3:4:5:6:7:8")).ToString() == "1:2:3:4:5:6:7:8/128");
+ CSubNet subnet = CSubNet(ResolveIP("1.2.3.4"), 32);
+ BOOST_CHECK_EQUAL(subnet.ToString(), "1.2.3.4/32");
+ subnet = CSubNet(ResolveIP("1.2.3.4"), 8);
+ BOOST_CHECK_EQUAL(subnet.ToString(), "1.0.0.0/8");
+ subnet = CSubNet(ResolveIP("1.2.3.4"), 0);
+ BOOST_CHECK_EQUAL(subnet.ToString(), "0.0.0.0/0");
- CSubNet subnet = CSubNet("1.2.3.4/255.255.255.255");
+ subnet = CSubNet(ResolveIP("1.2.3.4"), ResolveIP("255.255.255.255"));
BOOST_CHECK_EQUAL(subnet.ToString(), "1.2.3.4/32");
- subnet = CSubNet("1.2.3.4/255.255.255.254");
+ subnet = CSubNet(ResolveIP("1.2.3.4"), ResolveIP("255.0.0.0"));
+ BOOST_CHECK_EQUAL(subnet.ToString(), "1.0.0.0/8");
+ subnet = CSubNet(ResolveIP("1.2.3.4"), ResolveIP("0.0.0.0"));
+ BOOST_CHECK_EQUAL(subnet.ToString(), "0.0.0.0/0");
+
+ BOOST_CHECK(CSubNet(ResolveIP("1:2:3:4:5:6:7:8")).IsValid());
+ BOOST_CHECK(CSubNet(ResolveIP("1:2:3:4:5:6:7:8")).Match(ResolveIP("1:2:3:4:5:6:7:8")));
+ BOOST_CHECK(!CSubNet(ResolveIP("1:2:3:4:5:6:7:8")).Match(ResolveIP("1:2:3:4:5:6:7:9")));
+ BOOST_CHECK(CSubNet(ResolveIP("1:2:3:4:5:6:7:8")).ToString() == "1:2:3:4:5:6:7:8/128");
+
+ subnet = ResolveSubNet("1.2.3.4/255.255.255.255");
+ BOOST_CHECK_EQUAL(subnet.ToString(), "1.2.3.4/32");
+ subnet = ResolveSubNet("1.2.3.4/255.255.255.254");
BOOST_CHECK_EQUAL(subnet.ToString(), "1.2.3.4/31");
- subnet = CSubNet("1.2.3.4/255.255.255.252");
+ subnet = ResolveSubNet("1.2.3.4/255.255.255.252");
BOOST_CHECK_EQUAL(subnet.ToString(), "1.2.3.4/30");
- subnet = CSubNet("1.2.3.4/255.255.255.248");
+ subnet = ResolveSubNet("1.2.3.4/255.255.255.248");
BOOST_CHECK_EQUAL(subnet.ToString(), "1.2.3.0/29");
- subnet = CSubNet("1.2.3.4/255.255.255.240");
+ subnet = ResolveSubNet("1.2.3.4/255.255.255.240");
BOOST_CHECK_EQUAL(subnet.ToString(), "1.2.3.0/28");
- subnet = CSubNet("1.2.3.4/255.255.255.224");
+ subnet = ResolveSubNet("1.2.3.4/255.255.255.224");
BOOST_CHECK_EQUAL(subnet.ToString(), "1.2.3.0/27");
- subnet = CSubNet("1.2.3.4/255.255.255.192");
+ subnet = ResolveSubNet("1.2.3.4/255.255.255.192");
BOOST_CHECK_EQUAL(subnet.ToString(), "1.2.3.0/26");
- subnet = CSubNet("1.2.3.4/255.255.255.128");
+ subnet = ResolveSubNet("1.2.3.4/255.255.255.128");
BOOST_CHECK_EQUAL(subnet.ToString(), "1.2.3.0/25");
- subnet = CSubNet("1.2.3.4/255.255.255.0");
+ subnet = ResolveSubNet("1.2.3.4/255.255.255.0");
BOOST_CHECK_EQUAL(subnet.ToString(), "1.2.3.0/24");
- subnet = CSubNet("1.2.3.4/255.255.254.0");
+ subnet = ResolveSubNet("1.2.3.4/255.255.254.0");
BOOST_CHECK_EQUAL(subnet.ToString(), "1.2.2.0/23");
- subnet = CSubNet("1.2.3.4/255.255.252.0");
+ subnet = ResolveSubNet("1.2.3.4/255.255.252.0");
BOOST_CHECK_EQUAL(subnet.ToString(), "1.2.0.0/22");
- subnet = CSubNet("1.2.3.4/255.255.248.0");
+ subnet = ResolveSubNet("1.2.3.4/255.255.248.0");
BOOST_CHECK_EQUAL(subnet.ToString(), "1.2.0.0/21");
- subnet = CSubNet("1.2.3.4/255.255.240.0");
+ subnet = ResolveSubNet("1.2.3.4/255.255.240.0");
BOOST_CHECK_EQUAL(subnet.ToString(), "1.2.0.0/20");
- subnet = CSubNet("1.2.3.4/255.255.224.0");
+ subnet = ResolveSubNet("1.2.3.4/255.255.224.0");
BOOST_CHECK_EQUAL(subnet.ToString(), "1.2.0.0/19");
- subnet = CSubNet("1.2.3.4/255.255.192.0");
+ subnet = ResolveSubNet("1.2.3.4/255.255.192.0");
BOOST_CHECK_EQUAL(subnet.ToString(), "1.2.0.0/18");
- subnet = CSubNet("1.2.3.4/255.255.128.0");
+ subnet = ResolveSubNet("1.2.3.4/255.255.128.0");
BOOST_CHECK_EQUAL(subnet.ToString(), "1.2.0.0/17");
- subnet = CSubNet("1.2.3.4/255.255.0.0");
+ subnet = ResolveSubNet("1.2.3.4/255.255.0.0");
BOOST_CHECK_EQUAL(subnet.ToString(), "1.2.0.0/16");
- subnet = CSubNet("1.2.3.4/255.254.0.0");
+ subnet = ResolveSubNet("1.2.3.4/255.254.0.0");
BOOST_CHECK_EQUAL(subnet.ToString(), "1.2.0.0/15");
- subnet = CSubNet("1.2.3.4/255.252.0.0");
+ subnet = ResolveSubNet("1.2.3.4/255.252.0.0");
BOOST_CHECK_EQUAL(subnet.ToString(), "1.0.0.0/14");
- subnet = CSubNet("1.2.3.4/255.248.0.0");
+ subnet = ResolveSubNet("1.2.3.4/255.248.0.0");
BOOST_CHECK_EQUAL(subnet.ToString(), "1.0.0.0/13");
- subnet = CSubNet("1.2.3.4/255.240.0.0");
+ subnet = ResolveSubNet("1.2.3.4/255.240.0.0");
BOOST_CHECK_EQUAL(subnet.ToString(), "1.0.0.0/12");
- subnet = CSubNet("1.2.3.4/255.224.0.0");
+ subnet = ResolveSubNet("1.2.3.4/255.224.0.0");
BOOST_CHECK_EQUAL(subnet.ToString(), "1.0.0.0/11");
- subnet = CSubNet("1.2.3.4/255.192.0.0");
+ subnet = ResolveSubNet("1.2.3.4/255.192.0.0");
BOOST_CHECK_EQUAL(subnet.ToString(), "1.0.0.0/10");
- subnet = CSubNet("1.2.3.4/255.128.0.0");
+ subnet = ResolveSubNet("1.2.3.4/255.128.0.0");
BOOST_CHECK_EQUAL(subnet.ToString(), "1.0.0.0/9");
- subnet = CSubNet("1.2.3.4/255.0.0.0");
+ subnet = ResolveSubNet("1.2.3.4/255.0.0.0");
BOOST_CHECK_EQUAL(subnet.ToString(), "1.0.0.0/8");
- subnet = CSubNet("1.2.3.4/254.0.0.0");
+ subnet = ResolveSubNet("1.2.3.4/254.0.0.0");
BOOST_CHECK_EQUAL(subnet.ToString(), "0.0.0.0/7");
- subnet = CSubNet("1.2.3.4/252.0.0.0");
+ subnet = ResolveSubNet("1.2.3.4/252.0.0.0");
BOOST_CHECK_EQUAL(subnet.ToString(), "0.0.0.0/6");
- subnet = CSubNet("1.2.3.4/248.0.0.0");
+ subnet = ResolveSubNet("1.2.3.4/248.0.0.0");
BOOST_CHECK_EQUAL(subnet.ToString(), "0.0.0.0/5");
- subnet = CSubNet("1.2.3.4/240.0.0.0");
+ subnet = ResolveSubNet("1.2.3.4/240.0.0.0");
BOOST_CHECK_EQUAL(subnet.ToString(), "0.0.0.0/4");
- subnet = CSubNet("1.2.3.4/224.0.0.0");
+ subnet = ResolveSubNet("1.2.3.4/224.0.0.0");
BOOST_CHECK_EQUAL(subnet.ToString(), "0.0.0.0/3");
- subnet = CSubNet("1.2.3.4/192.0.0.0");
+ subnet = ResolveSubNet("1.2.3.4/192.0.0.0");
BOOST_CHECK_EQUAL(subnet.ToString(), "0.0.0.0/2");
- subnet = CSubNet("1.2.3.4/128.0.0.0");
+ subnet = ResolveSubNet("1.2.3.4/128.0.0.0");
BOOST_CHECK_EQUAL(subnet.ToString(), "0.0.0.0/1");
- subnet = CSubNet("1.2.3.4/0.0.0.0");
+ subnet = ResolveSubNet("1.2.3.4/0.0.0.0");
BOOST_CHECK_EQUAL(subnet.ToString(), "0.0.0.0/0");
- subnet = CSubNet("1:2:3:4:5:6:7:8/ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff");
+ subnet = ResolveSubNet("1:2:3:4:5:6:7:8/ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff");
BOOST_CHECK_EQUAL(subnet.ToString(), "1:2:3:4:5:6:7:8/128");
- subnet = CSubNet("1:2:3:4:5:6:7:8/ffff:0000:0000:0000:0000:0000:0000:0000");
+ subnet = ResolveSubNet("1:2:3:4:5:6:7:8/ffff:0000:0000:0000:0000:0000:0000:0000");
BOOST_CHECK_EQUAL(subnet.ToString(), "1::/16");
- subnet = CSubNet("1:2:3:4:5:6:7:8/0000:0000:0000:0000:0000:0000:0000:0000");
+ subnet = ResolveSubNet("1:2:3:4:5:6:7:8/0000:0000:0000:0000:0000:0000:0000:0000");
BOOST_CHECK_EQUAL(subnet.ToString(), "::/0");
- subnet = CSubNet("1.2.3.4/255.255.232.0");
+ subnet = ResolveSubNet("1.2.3.4/255.255.232.0");
BOOST_CHECK_EQUAL(subnet.ToString(), "1.2.0.0/255.255.232.0");
- subnet = CSubNet("1:2:3:4:5:6:7:8/ffff:ffff:ffff:fffe:ffff:ffff:ffff:ff0f");
+ subnet = ResolveSubNet("1:2:3:4:5:6:7:8/ffff:ffff:ffff:fffe:ffff:ffff:ffff:ff0f");
BOOST_CHECK_EQUAL(subnet.ToString(), "1:2:3:4:5:6:7:8/ffff:ffff:ffff:fffe:ffff:ffff:ffff:ff0f");
+
}
BOOST_AUTO_TEST_CASE(netbase_getgroup)
{
- BOOST_CHECK(CNetAddr("127.0.0.1").GetGroup() == boost::assign::list_of(0)); // Local -> !Routable()
- BOOST_CHECK(CNetAddr("257.0.0.1").GetGroup() == boost::assign::list_of(0)); // !Valid -> !Routable()
- BOOST_CHECK(CNetAddr("10.0.0.1").GetGroup() == boost::assign::list_of(0)); // RFC1918 -> !Routable()
- BOOST_CHECK(CNetAddr("169.254.1.1").GetGroup() == boost::assign::list_of(0)); // RFC3927 -> !Routable()
- BOOST_CHECK(CNetAddr("1.2.3.4").GetGroup() == boost::assign::list_of((unsigned char)NET_IPV4)(1)(2)); // IPv4
- BOOST_CHECK(CNetAddr("::FFFF:0:102:304").GetGroup() == boost::assign::list_of((unsigned char)NET_IPV4)(1)(2)); // RFC6145
- BOOST_CHECK(CNetAddr("64:FF9B::102:304").GetGroup() == boost::assign::list_of((unsigned char)NET_IPV4)(1)(2)); // RFC6052
- BOOST_CHECK(CNetAddr("2002:102:304:9999:9999:9999:9999:9999").GetGroup() == boost::assign::list_of((unsigned char)NET_IPV4)(1)(2)); // RFC3964
- BOOST_CHECK(CNetAddr("2001:0:9999:9999:9999:9999:FEFD:FCFB").GetGroup() == boost::assign::list_of((unsigned char)NET_IPV4)(1)(2)); // RFC4380
- BOOST_CHECK(CNetAddr("FD87:D87E:EB43:edb1:8e4:3588:e546:35ca").GetGroup() == boost::assign::list_of((unsigned char)NET_TOR)(239)); // Tor
- BOOST_CHECK(CNetAddr("2001:470:abcd:9999:9999:9999:9999:9999").GetGroup() == boost::assign::list_of((unsigned char)NET_IPV6)(32)(1)(4)(112)(175)); //he.net
- BOOST_CHECK(CNetAddr("2001:2001:9999:9999:9999:9999:9999:9999").GetGroup() == boost::assign::list_of((unsigned char)NET_IPV6)(32)(1)(32)(1)); //IPv6
+
+ BOOST_CHECK(ResolveIP("127.0.0.1").GetGroup() == boost::assign::list_of(0)); // Local -> !Routable()
+ BOOST_CHECK(ResolveIP("257.0.0.1").GetGroup() == boost::assign::list_of(0)); // !Valid -> !Routable()
+ BOOST_CHECK(ResolveIP("10.0.0.1").GetGroup() == boost::assign::list_of(0)); // RFC1918 -> !Routable()
+ BOOST_CHECK(ResolveIP("169.254.1.1").GetGroup() == boost::assign::list_of(0)); // RFC3927 -> !Routable()
+ BOOST_CHECK(ResolveIP("1.2.3.4").GetGroup() == boost::assign::list_of((unsigned char)NET_IPV4)(1)(2)); // IPv4
+ BOOST_CHECK(ResolveIP("::FFFF:0:102:304").GetGroup() == boost::assign::list_of((unsigned char)NET_IPV4)(1)(2)); // RFC6145
+ BOOST_CHECK(ResolveIP("64:FF9B::102:304").GetGroup() == boost::assign::list_of((unsigned char)NET_IPV4)(1)(2)); // RFC6052
+ BOOST_CHECK(ResolveIP("2002:102:304:9999:9999:9999:9999:9999").GetGroup() == boost::assign::list_of((unsigned char)NET_IPV4)(1)(2)); // RFC3964
+ BOOST_CHECK(ResolveIP("2001:0:9999:9999:9999:9999:FEFD:FCFB").GetGroup() == boost::assign::list_of((unsigned char)NET_IPV4)(1)(2)); // RFC4380
+ BOOST_CHECK(ResolveIP("FD87:D87E:EB43:edb1:8e4:3588:e546:35ca").GetGroup() == boost::assign::list_of((unsigned char)NET_TOR)(239)); // Tor
+ BOOST_CHECK(ResolveIP("2001:470:abcd:9999:9999:9999:9999:9999").GetGroup() == boost::assign::list_of((unsigned char)NET_IPV6)(32)(1)(4)(112)(175)); //he.net
+ BOOST_CHECK(ResolveIP("2001:2001:9999:9999:9999:9999:9999:9999").GetGroup() == boost::assign::list_of((unsigned char)NET_IPV6)(32)(1)(32)(1)); //IPv6
+
}
BOOST_AUTO_TEST_SUITE_END()
diff --git a/src/timedata.cpp b/src/timedata.cpp
index b6bcf86fbf..25fc494121 100644
--- a/src/timedata.cpp
+++ b/src/timedata.cpp
@@ -8,7 +8,7 @@
#include "timedata.h"
-#include "netbase.h"
+#include "netaddress.h"
#include "sync.h"
#include "ui_interface.h"
#include "util.h"
diff --git a/src/torcontrol.cpp b/src/torcontrol.cpp
index 0d6b655675..99c45d489c 100644
--- a/src/torcontrol.cpp
+++ b/src/torcontrol.cpp
@@ -4,6 +4,7 @@
#include "torcontrol.h"
#include "utilstrencodings.h"
+#include "netbase.h"
#include "net.h"
#include "util.h"
#include "crypto/hmac_sha256.h"
@@ -437,8 +438,7 @@ void TorController::add_onion_cb(TorControlConnection& conn, const TorControlRep
if ((i = m.find("PrivateKey")) != m.end())
private_key = i->second;
}
-
- service = CService(service_id+".onion", GetListenPort());
+ service = LookupNumeric(std::string(service_id+".onion").c_str(), GetListenPort());
LogPrintf("tor: Got service ID %s, advertising service %s\n", service_id, service.ToString());
if (WriteBinaryFile(GetPrivateKeyFile(), private_key)) {
LogPrint("tor", "tor: Cached service private key to %s\n", GetPrivateKeyFile());
@@ -462,7 +462,8 @@ void TorController::auth_cb(TorControlConnection& conn, const TorControlReply& r
// Now that we know Tor is running setup the proxy for onion addresses
// if -onion isn't set to something else.
if (GetArg("-onion", "") == "") {
- proxyType addrOnion = proxyType(CService("127.0.0.1", 9050), true);
+ CService resolved(LookupNumeric("127.0.0.1", 9050));
+ proxyType addrOnion = proxyType(resolved, true);
SetProxy(NET_TOR, addrOnion);
SetLimited(NET_TOR, false);
}
diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp
index a90807e514..aa0a9374c1 100644
--- a/src/wallet/rpcwallet.cpp
+++ b/src/wallet/rpcwallet.cpp
@@ -10,7 +10,6 @@
#include "init.h"
#include "main.h"
#include "net.h"
-#include "netbase.h"
#include "policy/rbf.h"
#include "rpc/server.h"
#include "timedata.h"