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)
This commit is contained in:
commit
1030fa718c
21 changed files with 1277 additions and 1167 deletions
|
@ -105,6 +105,7 @@ BITCOIN_CORE_H = \
|
||||||
merkleblock.h \
|
merkleblock.h \
|
||||||
miner.h \
|
miner.h \
|
||||||
net.h \
|
net.h \
|
||||||
|
netaddress.h \
|
||||||
netbase.h \
|
netbase.h \
|
||||||
noui.h \
|
noui.h \
|
||||||
policy/fees.h \
|
policy/fees.h \
|
||||||
|
@ -289,6 +290,7 @@ libbitcoin_common_a_SOURCES = \
|
||||||
core_write.cpp \
|
core_write.cpp \
|
||||||
key.cpp \
|
key.cpp \
|
||||||
keystore.cpp \
|
keystore.cpp \
|
||||||
|
netaddress.cpp \
|
||||||
netbase.cpp \
|
netbase.cpp \
|
||||||
protocol.cpp \
|
protocol.cpp \
|
||||||
scheduler.cpp \
|
scheduler.cpp \
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
#ifndef BITCOIN_ADDRMAN_H
|
#ifndef BITCOIN_ADDRMAN_H
|
||||||
#define BITCOIN_ADDRMAN_H
|
#define BITCOIN_ADDRMAN_H
|
||||||
|
|
||||||
#include "netbase.h"
|
#include "netaddress.h"
|
||||||
#include "protocol.h"
|
#include "protocol.h"
|
||||||
#include "random.h"
|
#include "random.h"
|
||||||
#include "sync.h"
|
#include "sync.h"
|
||||||
|
|
|
@ -197,12 +197,17 @@ static bool ClientAllowed(const CNetAddr& netaddr)
|
||||||
static bool InitHTTPAllowList()
|
static bool InitHTTPAllowList()
|
||||||
{
|
{
|
||||||
rpc_allow_subnets.clear();
|
rpc_allow_subnets.clear();
|
||||||
rpc_allow_subnets.push_back(CSubNet("127.0.0.0/8")); // always allow IPv4 local subnet
|
CNetAddr localv4;
|
||||||
rpc_allow_subnets.push_back(CSubNet("::1")); // always allow IPv6 localhost
|
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")) {
|
if (mapMultiArgs.count("-rpcallowip")) {
|
||||||
const std::vector<std::string>& vAllow = mapMultiArgs["-rpcallowip"];
|
const std::vector<std::string>& vAllow = mapMultiArgs["-rpcallowip"];
|
||||||
for (std::string strAllow : vAllow) {
|
for (std::string strAllow : vAllow) {
|
||||||
CSubNet subnet(strAllow);
|
CSubNet subnet;
|
||||||
|
LookupSubNet(strAllow.c_str(), subnet);
|
||||||
if (!subnet.IsValid()) {
|
if (!subnet.IsValid()) {
|
||||||
uiInterface.ThreadSafeMessageBox(
|
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),
|
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 = "";
|
const char* address = "";
|
||||||
uint16_t port = 0;
|
uint16_t port = 0;
|
||||||
evhttp_connection_get_peer(con, (char**)&address, &port);
|
evhttp_connection_get_peer(con, (char**)&address, &port);
|
||||||
peer = CService(address, port);
|
peer = LookupNumeric(address, port);
|
||||||
}
|
}
|
||||||
return peer;
|
return peer;
|
||||||
}
|
}
|
||||||
|
|
10
src/init.cpp
10
src/init.cpp
|
@ -21,6 +21,7 @@
|
||||||
#include "key.h"
|
#include "key.h"
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
#include "miner.h"
|
#include "miner.h"
|
||||||
|
#include "netbase.h"
|
||||||
#include "net.h"
|
#include "net.h"
|
||||||
#include "policy/policy.h"
|
#include "policy/policy.h"
|
||||||
#include "rpc/server.h"
|
#include "rpc/server.h"
|
||||||
|
@ -1134,7 +1135,8 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
|
||||||
|
|
||||||
if (mapArgs.count("-whitelist")) {
|
if (mapArgs.count("-whitelist")) {
|
||||||
BOOST_FOREACH(const std::string& net, mapMultiArgs["-whitelist"]) {
|
BOOST_FOREACH(const std::string& net, mapMultiArgs["-whitelist"]) {
|
||||||
CSubNet subnet(net);
|
CSubNet subnet;
|
||||||
|
LookupSubNet(net.c_str(), subnet);
|
||||||
if (!subnet.IsValid())
|
if (!subnet.IsValid())
|
||||||
return InitError(strprintf(_("Invalid netmask specified in -whitelist: '%s'"), net));
|
return InitError(strprintf(_("Invalid netmask specified in -whitelist: '%s'"), net));
|
||||||
CNode::AddWhitelistedRange(subnet);
|
CNode::AddWhitelistedRange(subnet);
|
||||||
|
@ -1147,7 +1149,8 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
|
||||||
std::string proxyArg = GetArg("-proxy", "");
|
std::string proxyArg = GetArg("-proxy", "");
|
||||||
SetLimited(NET_TOR);
|
SetLimited(NET_TOR);
|
||||||
if (proxyArg != "" && proxyArg != "0") {
|
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())
|
if (!addrProxy.IsValid())
|
||||||
return InitError(strprintf(_("Invalid -proxy address: '%s'"), proxyArg));
|
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
|
if (onionArg == "0") { // Handle -noonion/-onion=0
|
||||||
SetLimited(NET_TOR); // set onions as unreachable
|
SetLimited(NET_TOR); // set onions as unreachable
|
||||||
} else {
|
} else {
|
||||||
proxyType addrOnion = proxyType(CService(onionArg, 9050), proxyRandomize);
|
CService resolved(LookupNumeric(onionArg.c_str(), 9050));
|
||||||
|
proxyType addrOnion = proxyType(resolved, proxyRandomize);
|
||||||
if (!addrOnion.IsValid())
|
if (!addrOnion.IsValid())
|
||||||
return InitError(strprintf(_("Invalid -onion address: '%s'"), onionArg));
|
return InitError(strprintf(_("Invalid -onion address: '%s'"), onionArg));
|
||||||
SetProxy(NET_TOR, addrOnion);
|
SetProxy(NET_TOR, addrOnion);
|
||||||
|
|
27
src/net.cpp
27
src/net.cpp
|
@ -17,6 +17,7 @@
|
||||||
#include "crypto/sha256.h"
|
#include "crypto/sha256.h"
|
||||||
#include "hash.h"
|
#include "hash.h"
|
||||||
#include "primitives/transaction.h"
|
#include "primitives/transaction.h"
|
||||||
|
#include "netbase.h"
|
||||||
#include "scheduler.h"
|
#include "scheduler.h"
|
||||||
#include "ui_interface.h"
|
#include "ui_interface.h"
|
||||||
#include "utilstrencodings.h"
|
#include "utilstrencodings.h"
|
||||||
|
@ -175,7 +176,7 @@ static std::vector<CAddress> convertSeed6(const std::vector<SeedSpec6> &vSeedsIn
|
||||||
// one by discovery.
|
// one by discovery.
|
||||||
CAddress GetLocalAddress(const CNetAddr *paddrPeer)
|
CAddress GetLocalAddress(const CNetAddr *paddrPeer)
|
||||||
{
|
{
|
||||||
CAddress ret(CService("0.0.0.0",GetListenPort()), NODE_NONE);
|
CAddress ret(CService(CNetAddr(),GetListenPort()), NODE_NONE);
|
||||||
CService addr;
|
CService addr;
|
||||||
if (GetLocal(addr, paddrPeer))
|
if (GetLocal(addr, paddrPeer))
|
||||||
{
|
{
|
||||||
|
@ -494,7 +495,7 @@ void CNode::PushVersion()
|
||||||
int nBestHeight = GetNodeSignals().GetHeight().get_value_or(0);
|
int nBestHeight = GetNodeSignals().GetHeight().get_value_or(0);
|
||||||
|
|
||||||
int64_t nTime = (fInbound ? GetAdjustedTime() : GetTime());
|
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);
|
CAddress addrMe = GetLocalAddress(&addr);
|
||||||
GetRandBytes((unsigned char*)&nLocalHostNonce, sizeof(nLocalHostNonce));
|
GetRandBytes((unsigned char*)&nLocalHostNonce, sizeof(nLocalHostNonce));
|
||||||
if (fLogIPs)
|
if (fLogIPs)
|
||||||
|
@ -1396,8 +1397,11 @@ void ThreadMapPort()
|
||||||
{
|
{
|
||||||
if(externalIPAddress[0])
|
if(externalIPAddress[0])
|
||||||
{
|
{
|
||||||
LogPrintf("UPnP: ExternalIPAddress = %s\n", externalIPAddress);
|
CNetAddr resolved;
|
||||||
AddLocal(CNetAddr(externalIPAddress), LOCAL_UPNP);
|
if(LookupHost(externalIPAddress, resolved, false)) {
|
||||||
|
LogPrintf("UPnP: ExternalIPAddress = %s\n", resolved.ToString().c_str());
|
||||||
|
AddLocal(resolved, LOCAL_UPNP);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
LogPrintf("UPnP: GetExternalIPAddress failed.\n");
|
LogPrintf("UPnP: GetExternalIPAddress failed.\n");
|
||||||
|
@ -1623,7 +1627,9 @@ void ThreadOpenConnections()
|
||||||
static bool done = false;
|
static bool done = false;
|
||||||
if (!done) {
|
if (!done) {
|
||||||
LogPrintf("Adding fixed seed nodes as DNS doesn't seem to be available.\n");
|
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;
|
done = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1722,7 +1728,7 @@ std::vector<AddedNodeInfo> GetAddedNodeInfo()
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_FOREACH(const std::string& strAddNode, lAddresses) {
|
BOOST_FOREACH(const std::string& strAddNode, lAddresses) {
|
||||||
CService service(strAddNode, Params().GetDefaultPort());
|
CService service(LookupNumeric(strAddNode.c_str(), Params().GetDefaultPort()));
|
||||||
if (service.IsValid()) {
|
if (service.IsValid()) {
|
||||||
// strAddNode is an IP:port
|
// strAddNode is an IP:port
|
||||||
auto it = mapConnected.find(service);
|
auto it = mapConnected.find(service);
|
||||||
|
@ -1760,7 +1766,7 @@ void ThreadOpenAddedConnections()
|
||||||
CSemaphoreGrant grant(*semOutbound);
|
CSemaphoreGrant grant(*semOutbound);
|
||||||
// If strAddedNode is an IP/port, decode it immediately, so
|
// If strAddedNode is an IP/port, decode it immediately, so
|
||||||
// OpenNetworkConnection can detect existing connections to that IP/port.
|
// 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);
|
OpenNetworkConnection(CAddress(service, NODE_NONE), false, &grant, info.strAddedNode.c_str(), false);
|
||||||
MilliSleep(500);
|
MilliSleep(500);
|
||||||
}
|
}
|
||||||
|
@ -2060,8 +2066,11 @@ void StartNode(boost::thread_group& threadGroup, CScheduler& scheduler)
|
||||||
semOutbound = new CSemaphore(nMaxOutbound);
|
semOutbound = new CSemaphore(nMaxOutbound);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pnodeLocalHost == NULL)
|
if (pnodeLocalHost == NULL) {
|
||||||
pnodeLocalHost = new CNode(INVALID_SOCKET, CAddress(CService("127.0.0.1", 0), nLocalServices));
|
CNetAddr local;
|
||||||
|
LookupHost("127.0.0.1", local, false);
|
||||||
|
pnodeLocalHost = new CNode(INVALID_SOCKET, CAddress(CService(local, 0), nLocalServices));
|
||||||
|
}
|
||||||
|
|
||||||
Discover(threadGroup);
|
Discover(threadGroup);
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
#include "bloom.h"
|
#include "bloom.h"
|
||||||
#include "compat.h"
|
#include "compat.h"
|
||||||
#include "limitedmap.h"
|
#include "limitedmap.h"
|
||||||
#include "netbase.h"
|
#include "netaddress.h"
|
||||||
#include "protocol.h"
|
#include "protocol.h"
|
||||||
#include "random.h"
|
#include "random.h"
|
||||||
#include "streams.h"
|
#include "streams.h"
|
||||||
|
|
716
src/netaddress.cpp
Normal file
716
src/netaddress.cpp
Normal file
|
@ -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));
|
||||||
|
}
|
171
src/netaddress.h
Normal file
171
src/netaddress.h
Normal file
|
@ -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
|
782
src/netbase.cpp
782
src/netbase.cpp
|
@ -42,8 +42,6 @@ static CCriticalSection cs_proxyInfos;
|
||||||
int nConnectTimeout = DEFAULT_CONNECT_TIMEOUT;
|
int nConnectTimeout = DEFAULT_CONNECT_TIMEOUT;
|
||||||
bool fNameLookup = DEFAULT_NAME_LOOKUP;
|
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)
|
// Need ample time for negotiation for very slow proxies such as Tor (milliseconds)
|
||||||
static const int SOCKS5_RECV_TIMEOUT = 20 * 1000;
|
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);
|
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)
|
bool Lookup(const char *pszName, std::vector<CService>& vAddr, int portDefault, bool fAllowLookup, unsigned int nMaxSolutions)
|
||||||
{
|
{
|
||||||
if (pszName[0] == 0)
|
if (pszName[0] == 0)
|
||||||
|
@ -223,9 +231,14 @@ bool Lookup(const char *pszName, CService& addr, int portDefault, bool fAllowLoo
|
||||||
return true;
|
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)
|
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())
|
if (!HaveNameProxy())
|
||||||
return false;
|
return false;
|
||||||
return ConnectThroughProxy(nameProxy, strDest, port, hSocketRet, nTimeout, outProxyConnectionFailed);
|
return ConnectThroughProxy(nameProxy, strDest, port, hSocketRet, nTimeout, outProxyConnectionFailed);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CNetAddr::Init()
|
bool LookupSubNet(const char* pszName, CSubNet& ret)
|
||||||
{
|
|
||||||
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)
|
|
||||||
{
|
{
|
||||||
|
std::string strSubnet(pszName);
|
||||||
size_t slash = strSubnet.find_last_of('/');
|
size_t slash = strSubnet.find_last_of('/');
|
||||||
std::vector<CNetAddr> vIP;
|
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);
|
std::string strAddress = strSubnet.substr(0, slash);
|
||||||
if (LookupHost(strAddress.c_str(), vIP, 1, false))
|
if (LookupHost(strAddress.c_str(), vIP, 1, false))
|
||||||
{
|
{
|
||||||
network = vIP[0];
|
CNetAddr network = vIP[0];
|
||||||
if (slash != strSubnet.npos)
|
if (slash != strSubnet.npos)
|
||||||
{
|
{
|
||||||
std::string strNetmask = strSubnet.substr(slash + 1);
|
std::string strNetmask = strSubnet.substr(slash + 1);
|
||||||
int32_t n;
|
int32_t n;
|
||||||
// IPv4 addresses start at offset 12, and first 12 bytes must match, so just offset 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 syntax
|
||||||
if (ParseInt32(strNetmask, &n)) // If valid number, assume /24 symtex
|
ret = CSubNet(network, n);
|
||||||
{
|
return ret.IsValid();
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else // If not a valid number, try full netmask syntax
|
else // If not a valid number, try full netmask syntax
|
||||||
{
|
{
|
||||||
if (LookupHost(strNetmask.c_str(), vIP, 1, false)) // Never allow lookup for netmask
|
// Never allow lookup for netmask
|
||||||
{
|
if (LookupHost(strNetmask.c_str(), vIP, 1, false)) {
|
||||||
// Copy only the *last* four bytes in case of IPv4, the rest of the mask should stay 1's as
|
ret = CSubNet(network, vIP[0]);
|
||||||
// we don't want pchIPv4 to be part of the mask.
|
return ret.IsValid();
|
||||||
for(int x=astartofs; x<16; ++x)
|
|
||||||
netmask[x] = vIP[0].ip[x];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
valid = false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
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
|
else
|
||||||
cidr += bits;
|
{
|
||||||
++n;
|
ret = CSubNet(network);
|
||||||
|
return ret.IsValid();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
for (; n < 16 && valid_cidr; ++n)
|
return false;
|
||||||
if (netmask[n] != 0x00)
|
|
||||||
valid_cidr = false;
|
|
||||||
|
|
||||||
/* Format output */
|
|
||||||
std::string strNetmask;
|
|
||||||
if (valid_cidr) {
|
|
||||||
strNetmask = strprintf("%u", cidr);
|
|
||||||
} else {
|
|
||||||
if (network.IsIPv4())
|
|
||||||
strNetmask = strprintf("%u.%u.%u.%u", netmask[12], netmask[13], netmask[14], netmask[15]);
|
|
||||||
else
|
|
||||||
strNetmask = strprintf("%x:%x:%x:%x:%x:%x:%x:%x",
|
|
||||||
netmask[0] << 8 | netmask[1], netmask[2] << 8 | netmask[3],
|
|
||||||
netmask[4] << 8 | netmask[5], netmask[6] << 8 | netmask[7],
|
|
||||||
netmask[8] << 8 | netmask[9], netmask[10] << 8 | netmask[11],
|
|
||||||
netmask[12] << 8 | netmask[13], netmask[14] << 8 | netmask[15]);
|
|
||||||
}
|
|
||||||
|
|
||||||
return network.ToString() + "/" + strNetmask;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CSubNet::IsValid() const
|
|
||||||
{
|
|
||||||
return valid;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool operator==(const CSubNet& a, const CSubNet& b)
|
|
||||||
{
|
|
||||||
return a.valid == b.valid && a.network == b.network && !memcmp(a.netmask, b.netmask, 16);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool operator!=(const CSubNet& a, const CSubNet& b)
|
|
||||||
{
|
|
||||||
return !(a==b);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool operator<(const CSubNet& a, const CSubNet& b)
|
|
||||||
{
|
|
||||||
return (a.network < b.network || (a.network == b.network && memcmp(a.netmask, b.netmask, 16) < 0));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
|
|
167
src/netbase.h
167
src/netbase.h
|
@ -10,6 +10,7 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "compat.h"
|
#include "compat.h"
|
||||||
|
#include "netaddress.h"
|
||||||
#include "serialize.h"
|
#include "serialize.h"
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
@ -24,168 +25,6 @@ static const int DEFAULT_CONNECT_TIMEOUT = 5000;
|
||||||
//! -dns default
|
//! -dns default
|
||||||
static const int DEFAULT_NAME_LOOKUP = true;
|
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
|
class proxyType
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -207,9 +46,11 @@ bool IsProxy(const CNetAddr &addr);
|
||||||
bool SetNameProxy(const proxyType &addrProxy);
|
bool SetNameProxy(const proxyType &addrProxy);
|
||||||
bool HaveNameProxy();
|
bool HaveNameProxy();
|
||||||
bool LookupHost(const char *pszName, std::vector<CNetAddr>& vIP, unsigned int nMaxSolutions, bool fAllowLookup);
|
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, CService& addr, int portDefault, bool fAllowLookup);
|
||||||
bool Lookup(const char *pszName, std::vector<CService>& vAddr, int portDefault, bool fAllowLookup, unsigned int nMaxSolutions);
|
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 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);
|
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 */
|
/** Return readable error string for a network error code */
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
#ifndef BITCOIN_PROTOCOL_H
|
#ifndef BITCOIN_PROTOCOL_H
|
||||||
#define BITCOIN_PROTOCOL_H
|
#define BITCOIN_PROTOCOL_H
|
||||||
|
|
||||||
#include "netbase.h"
|
#include "netaddress.h"
|
||||||
#include "serialize.h"
|
#include "serialize.h"
|
||||||
#include "uint256.h"
|
#include "uint256.h"
|
||||||
#include "version.h"
|
#include "version.h"
|
||||||
|
|
|
@ -327,7 +327,8 @@ QValidator::State ProxyAddressValidator::validate(QString &input, int &pos) cons
|
||||||
{
|
{
|
||||||
Q_UNUSED(pos);
|
Q_UNUSED(pos);
|
||||||
// Validate the proxy
|
// 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())
|
if (addrProxy.IsValid())
|
||||||
return QValidator::Acceptable;
|
return QValidator::Acceptable;
|
||||||
|
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
#include "init.h"
|
#include "init.h"
|
||||||
#include "main.h" // For DEFAULT_SCRIPTCHECK_THREADS
|
#include "main.h" // For DEFAULT_SCRIPTCHECK_THREADS
|
||||||
#include "net.h"
|
#include "net.h"
|
||||||
|
#include "netbase.h"
|
||||||
#include "txdb.h" // for -dbcache defaults
|
#include "txdb.h" // for -dbcache defaults
|
||||||
|
|
||||||
#ifdef ENABLE_WALLET
|
#ifdef ENABLE_WALLET
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
#include "bantablemodel.h"
|
#include "bantablemodel.h"
|
||||||
|
|
||||||
#include "chainparams.h"
|
#include "chainparams.h"
|
||||||
|
#include "netbase.h"
|
||||||
#include "rpc/server.h"
|
#include "rpc/server.h"
|
||||||
#include "rpc/client.h"
|
#include "rpc/client.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
@ -898,7 +899,10 @@ void RPCConsole::banSelectedNode(int bantime)
|
||||||
int port = 0;
|
int port = 0;
|
||||||
SplitHostPort(nStr, port, addr);
|
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();
|
clearSelectedNode();
|
||||||
clientModel->getBanTableModel()->refresh();
|
clientModel->getBanTableModel()->refresh();
|
||||||
|
@ -912,8 +916,9 @@ void RPCConsole::unbanSelectedNode()
|
||||||
|
|
||||||
// Get currently selected ban address
|
// Get currently selected ban address
|
||||||
QString strNode = GUIUtil::getEntryData(ui->banlistWidget, 0, BanTableModel::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())
|
if (possibleSubnet.IsValid())
|
||||||
{
|
{
|
||||||
CNode::Unban(possibleSubnet);
|
CNode::Unban(possibleSubnet);
|
||||||
|
|
|
@ -494,10 +494,13 @@ UniValue setban(const UniValue& params, bool fHelp)
|
||||||
if (params[0].get_str().find("/") != string::npos)
|
if (params[0].get_str().find("/") != string::npos)
|
||||||
isSubnet = true;
|
isSubnet = true;
|
||||||
|
|
||||||
if (!isSubnet)
|
if (!isSubnet) {
|
||||||
netAddr = CNetAddr(params[0].get_str());
|
CNetAddr resolved;
|
||||||
|
LookupHost(params[0].get_str().c_str(), resolved, false);
|
||||||
|
netAddr = resolved;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
subNet = CSubNet(params[0].get_str());
|
LookupSubNet(params[0].get_str().c_str(), subNet);
|
||||||
|
|
||||||
if (! (isSubnet ? subNet.IsValid() : netAddr.IsValid()) )
|
if (! (isSubnet ? subNet.IsValid() : netAddr.IsValid()) )
|
||||||
throw JSONRPCError(RPC_CLIENT_NODE_ALREADY_ADDED, "Error: Invalid IP/Subnet");
|
throw JSONRPCError(RPC_CLIENT_NODE_ALREADY_ADDED, "Error: Invalid IP/Subnet");
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
#include <boost/test/unit_test.hpp>
|
#include <boost/test/unit_test.hpp>
|
||||||
|
|
||||||
#include "hash.h"
|
#include "hash.h"
|
||||||
|
#include "netbase.h"
|
||||||
#include "random.h"
|
#include "random.h"
|
||||||
|
|
||||||
using namespace std;
|
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_FIXTURE_TEST_SUITE(addrman_tests, BasicTestingSetup)
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(addrman_simple)
|
BOOST_AUTO_TEST_CASE(addrman_simple)
|
||||||
|
@ -59,7 +84,7 @@ BOOST_AUTO_TEST_CASE(addrman_simple)
|
||||||
// Set addrman addr placement to be deterministic.
|
// Set addrman addr placement to be deterministic.
|
||||||
addrman.MakeDeterministic();
|
addrman.MakeDeterministic();
|
||||||
|
|
||||||
CNetAddr source = CNetAddr("252.2.2.2");
|
CNetAddr source = ResolveIP("252.2.2.2");
|
||||||
|
|
||||||
// Test 1: Does Addrman respond correctly when empty.
|
// Test 1: Does Addrman respond correctly when empty.
|
||||||
BOOST_CHECK(addrman.size() == 0);
|
BOOST_CHECK(addrman.size() == 0);
|
||||||
|
@ -67,7 +92,7 @@ BOOST_AUTO_TEST_CASE(addrman_simple)
|
||||||
BOOST_CHECK(addr_null.ToString() == "[::]:0");
|
BOOST_CHECK(addr_null.ToString() == "[::]:0");
|
||||||
|
|
||||||
// Test 2: Does Addrman::Add work as expected.
|
// 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);
|
addrman.Add(CAddress(addr1, NODE_NONE), source);
|
||||||
BOOST_CHECK(addrman.size() == 1);
|
BOOST_CHECK(addrman.size() == 1);
|
||||||
CAddrInfo addr_ret1 = addrman.Select();
|
CAddrInfo addr_ret1 = addrman.Select();
|
||||||
|
@ -75,14 +100,14 @@ BOOST_AUTO_TEST_CASE(addrman_simple)
|
||||||
|
|
||||||
// Test 3: Does IP address deduplication work correctly.
|
// Test 3: Does IP address deduplication work correctly.
|
||||||
// Expected dup IP should not be added.
|
// 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);
|
addrman.Add(CAddress(addr1_dup, NODE_NONE), source);
|
||||||
BOOST_CHECK(addrman.size() == 1);
|
BOOST_CHECK(addrman.size() == 1);
|
||||||
|
|
||||||
|
|
||||||
// Test 5: New table has one addr and we add a diff addr we should
|
// Test 5: New table has one addr and we add a diff addr we should
|
||||||
// have two addrs.
|
// 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);
|
addrman.Add(CAddress(addr2, NODE_NONE), source);
|
||||||
BOOST_CHECK(addrman.size() == 2);
|
BOOST_CHECK(addrman.size() == 2);
|
||||||
|
|
||||||
|
@ -100,16 +125,16 @@ BOOST_AUTO_TEST_CASE(addrman_ports)
|
||||||
// Set addrman addr placement to be deterministic.
|
// Set addrman addr placement to be deterministic.
|
||||||
addrman.MakeDeterministic();
|
addrman.MakeDeterministic();
|
||||||
|
|
||||||
CNetAddr source = CNetAddr("252.2.2.2");
|
CNetAddr source = ResolveIP("252.2.2.2");
|
||||||
|
|
||||||
BOOST_CHECK(addrman.size() == 0);
|
BOOST_CHECK(addrman.size() == 0);
|
||||||
|
|
||||||
// Test 7; Addr with same IP but diff port does not replace existing addr.
|
// 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);
|
addrman.Add(CAddress(addr1, NODE_NONE), source);
|
||||||
BOOST_CHECK(addrman.size() == 1);
|
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);
|
addrman.Add(CAddress(addr1_port, NODE_NONE), source);
|
||||||
BOOST_CHECK(addrman.size() == 1);
|
BOOST_CHECK(addrman.size() == 1);
|
||||||
CAddrInfo addr_ret2 = addrman.Select();
|
CAddrInfo addr_ret2 = addrman.Select();
|
||||||
|
@ -132,10 +157,10 @@ BOOST_AUTO_TEST_CASE(addrman_select)
|
||||||
// Set addrman addr placement to be deterministic.
|
// Set addrman addr placement to be deterministic.
|
||||||
addrman.MakeDeterministic();
|
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.
|
// 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);
|
addrman.Add(CAddress(addr1, NODE_NONE), source);
|
||||||
BOOST_CHECK(addrman.size() == 1);
|
BOOST_CHECK(addrman.size() == 1);
|
||||||
|
|
||||||
|
@ -156,24 +181,24 @@ BOOST_AUTO_TEST_CASE(addrman_select)
|
||||||
|
|
||||||
|
|
||||||
// Add three addresses to new table.
|
// Add three addresses to new table.
|
||||||
CService addr2 = CService("250.3.1.1", 8333);
|
CService addr2 = ResolveService("250.3.1.1", 8333);
|
||||||
CService addr3 = CService("250.3.2.2", 9999);
|
CService addr3 = ResolveService("250.3.2.2", 9999);
|
||||||
CService addr4 = CService("250.3.3.3", 9999);
|
CService addr4 = ResolveService("250.3.3.3", 9999);
|
||||||
|
|
||||||
addrman.Add(CAddress(addr2, NODE_NONE), CService("250.3.1.1", 8333));
|
addrman.Add(CAddress(addr2, NODE_NONE), ResolveService("250.3.1.1", 8333));
|
||||||
addrman.Add(CAddress(addr3, NODE_NONE), CService("250.3.1.1", 8333));
|
addrman.Add(CAddress(addr3, NODE_NONE), ResolveService("250.3.1.1", 8333));
|
||||||
addrman.Add(CAddress(addr4, NODE_NONE), CService("250.4.1.1", 8333));
|
addrman.Add(CAddress(addr4, NODE_NONE), ResolveService("250.4.1.1", 8333));
|
||||||
|
|
||||||
// Add three addresses to tried table.
|
// Add three addresses to tried table.
|
||||||
CService addr5 = CService("250.4.4.4", 8333);
|
CService addr5 = ResolveService("250.4.4.4", 8333);
|
||||||
CService addr6 = CService("250.4.5.5", 7777);
|
CService addr6 = ResolveService("250.4.5.5", 7777);
|
||||||
CService addr7 = CService("250.4.6.6", 8333);
|
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.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.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));
|
addrman.Good(CAddress(addr7, NODE_NONE));
|
||||||
|
|
||||||
// Test 11: 6 addrs + 1 addr from last test = 7.
|
// 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.
|
// Set addrman addr placement to be deterministic.
|
||||||
addrman.MakeDeterministic();
|
addrman.MakeDeterministic();
|
||||||
|
|
||||||
CNetAddr source = CNetAddr("252.2.2.2");
|
CNetAddr source = ResolveIP("252.2.2.2");
|
||||||
|
|
||||||
BOOST_CHECK(addrman.size() == 0);
|
BOOST_CHECK(addrman.size() == 0);
|
||||||
|
|
||||||
for (unsigned int i = 1; i < 18; i++) {
|
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);
|
addrman.Add(CAddress(addr, NODE_NONE), source);
|
||||||
|
|
||||||
//Test 13: No collision in new table yet.
|
//Test 13: No collision in new table yet.
|
||||||
|
@ -206,11 +231,11 @@ BOOST_AUTO_TEST_CASE(addrman_new_collisions)
|
||||||
}
|
}
|
||||||
|
|
||||||
//Test 14: new table collision!
|
//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);
|
addrman.Add(CAddress(addr1, NODE_NONE), source);
|
||||||
BOOST_CHECK(addrman.size() == 17);
|
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);
|
addrman.Add(CAddress(addr2, NODE_NONE), source);
|
||||||
BOOST_CHECK(addrman.size() == 18);
|
BOOST_CHECK(addrman.size() == 18);
|
||||||
}
|
}
|
||||||
|
@ -222,12 +247,12 @@ BOOST_AUTO_TEST_CASE(addrman_tried_collisions)
|
||||||
// Set addrman addr placement to be deterministic.
|
// Set addrman addr placement to be deterministic.
|
||||||
addrman.MakeDeterministic();
|
addrman.MakeDeterministic();
|
||||||
|
|
||||||
CNetAddr source = CNetAddr("252.2.2.2");
|
CNetAddr source = ResolveIP("252.2.2.2");
|
||||||
|
|
||||||
BOOST_CHECK(addrman.size() == 0);
|
BOOST_CHECK(addrman.size() == 0);
|
||||||
|
|
||||||
for (unsigned int i = 1; i < 80; i++) {
|
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.Add(CAddress(addr, NODE_NONE), source);
|
||||||
addrman.Good(CAddress(addr, NODE_NONE));
|
addrman.Good(CAddress(addr, NODE_NONE));
|
||||||
|
|
||||||
|
@ -237,11 +262,11 @@ BOOST_AUTO_TEST_CASE(addrman_tried_collisions)
|
||||||
}
|
}
|
||||||
|
|
||||||
//Test 16: tried table collision!
|
//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);
|
addrman.Add(CAddress(addr1, NODE_NONE), source);
|
||||||
BOOST_CHECK(addrman.size() == 79);
|
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);
|
addrman.Add(CAddress(addr2, NODE_NONE), source);
|
||||||
BOOST_CHECK(addrman.size() == 80);
|
BOOST_CHECK(addrman.size() == 80);
|
||||||
}
|
}
|
||||||
|
@ -255,12 +280,12 @@ BOOST_AUTO_TEST_CASE(addrman_find)
|
||||||
|
|
||||||
BOOST_CHECK(addrman.size() == 0);
|
BOOST_CHECK(addrman.size() == 0);
|
||||||
|
|
||||||
CAddress addr1 = CAddress(CService("250.1.2.1", 8333), NODE_NONE);
|
CAddress addr1 = CAddress(ResolveService("250.1.2.1", 8333), NODE_NONE);
|
||||||
CAddress addr2 = CAddress(CService("250.1.2.1", 9999), NODE_NONE);
|
CAddress addr2 = CAddress(ResolveService("250.1.2.1", 9999), NODE_NONE);
|
||||||
CAddress addr3 = CAddress(CService("251.255.2.1", 8333), NODE_NONE);
|
CAddress addr3 = CAddress(ResolveService("251.255.2.1", 8333), NODE_NONE);
|
||||||
|
|
||||||
CNetAddr source1 = CNetAddr("250.1.2.1");
|
CNetAddr source1 = ResolveIP("250.1.2.1");
|
||||||
CNetAddr source2 = CNetAddr("250.1.2.2");
|
CNetAddr source2 = ResolveIP("250.1.2.2");
|
||||||
|
|
||||||
addrman.Add(addr1, source1);
|
addrman.Add(addr1, source1);
|
||||||
addrman.Add(addr2, source2);
|
addrman.Add(addr2, source2);
|
||||||
|
@ -294,8 +319,8 @@ BOOST_AUTO_TEST_CASE(addrman_create)
|
||||||
|
|
||||||
BOOST_CHECK(addrman.size() == 0);
|
BOOST_CHECK(addrman.size() == 0);
|
||||||
|
|
||||||
CAddress addr1 = CAddress(CService("250.1.2.1", 8333), NODE_NONE);
|
CAddress addr1 = CAddress(ResolveService("250.1.2.1", 8333), NODE_NONE);
|
||||||
CNetAddr source1 = CNetAddr("250.1.2.1");
|
CNetAddr source1 = ResolveIP("250.1.2.1");
|
||||||
|
|
||||||
int nId;
|
int nId;
|
||||||
CAddrInfo* pinfo = addrman.Create(addr1, source1, &nId);
|
CAddrInfo* pinfo = addrman.Create(addr1, source1, &nId);
|
||||||
|
@ -317,8 +342,8 @@ BOOST_AUTO_TEST_CASE(addrman_delete)
|
||||||
|
|
||||||
BOOST_CHECK(addrman.size() == 0);
|
BOOST_CHECK(addrman.size() == 0);
|
||||||
|
|
||||||
CAddress addr1 = CAddress(CService("250.1.2.1", 8333), NODE_NONE);
|
CAddress addr1 = CAddress(ResolveService("250.1.2.1", 8333), NODE_NONE);
|
||||||
CNetAddr source1 = CNetAddr("250.1.2.1");
|
CNetAddr source1 = ResolveIP("250.1.2.1");
|
||||||
|
|
||||||
int nId;
|
int nId;
|
||||||
addrman.Create(addr1, source1, &nId);
|
addrman.Create(addr1, source1, &nId);
|
||||||
|
@ -344,18 +369,18 @@ BOOST_AUTO_TEST_CASE(addrman_getaddr)
|
||||||
vector<CAddress> vAddr1 = addrman.GetAddr();
|
vector<CAddress> vAddr1 = addrman.GetAddr();
|
||||||
BOOST_CHECK(vAddr1.size() == 0);
|
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
|
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();
|
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();
|
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();
|
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();
|
addr5.nTime = GetAdjustedTime();
|
||||||
CNetAddr source1 = CNetAddr("250.1.2.1");
|
CNetAddr source1 = ResolveIP("250.1.2.1");
|
||||||
CNetAddr source2 = CNetAddr("250.2.3.3");
|
CNetAddr source2 = ResolveIP("250.2.3.3");
|
||||||
|
|
||||||
// Test 23: Ensure GetAddr works with new addresses.
|
// Test 23: Ensure GetAddr works with new addresses.
|
||||||
addrman.Add(addr1, source1);
|
addrman.Add(addr1, source1);
|
||||||
|
@ -378,11 +403,11 @@ BOOST_AUTO_TEST_CASE(addrman_getaddr)
|
||||||
int octet2 = (i / 256) % 256;
|
int octet2 = (i / 256) % 256;
|
||||||
int octet3 = (i / (256 * 2)) % 256;
|
int octet3 = (i / (256 * 2)) % 256;
|
||||||
string strAddr = boost::to_string(octet1) + "." + boost::to_string(octet2) + "." + boost::to_string(octet3) + ".23";
|
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.
|
// Ensure that for all addrs in addrman, isTerrible == false.
|
||||||
addr.nTime = GetAdjustedTime();
|
addr.nTime = GetAdjustedTime();
|
||||||
addrman.Add(addr, CNetAddr(strAddr));
|
addrman.Add(addr, ResolveIP(strAddr));
|
||||||
if (i % 8 == 0)
|
if (i % 8 == 0)
|
||||||
addrman.Good(addr);
|
addrman.Good(addr);
|
||||||
}
|
}
|
||||||
|
@ -403,10 +428,10 @@ BOOST_AUTO_TEST_CASE(caddrinfo_get_tried_bucket)
|
||||||
// Set addrman addr placement to be deterministic.
|
// Set addrman addr placement to be deterministic.
|
||||||
addrman.MakeDeterministic();
|
addrman.MakeDeterministic();
|
||||||
|
|
||||||
CAddress addr1 = CAddress(CService("250.1.1.1", 8333), NODE_NONE);
|
CAddress addr1 = CAddress(ResolveService("250.1.1.1", 8333), NODE_NONE);
|
||||||
CAddress addr2 = CAddress(CService("250.1.1.1", 9999), 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);
|
CAddrInfo info1 = CAddrInfo(addr1, source1);
|
||||||
|
@ -431,8 +456,8 @@ BOOST_AUTO_TEST_CASE(caddrinfo_get_tried_bucket)
|
||||||
set<int> buckets;
|
set<int> buckets;
|
||||||
for (int i = 0; i < 255; i++) {
|
for (int i = 0; i < 255; i++) {
|
||||||
CAddrInfo infoi = CAddrInfo(
|
CAddrInfo infoi = CAddrInfo(
|
||||||
CAddress(CService("250.1.1." + boost::to_string(i)), NODE_NONE),
|
CAddress(ResolveService("250.1.1." + boost::to_string(i)), NODE_NONE),
|
||||||
CNetAddr("250.1.1." + boost::to_string(i)));
|
ResolveIP("250.1.1." + boost::to_string(i)));
|
||||||
int bucket = infoi.GetTriedBucket(nKey1);
|
int bucket = infoi.GetTriedBucket(nKey1);
|
||||||
buckets.insert(bucket);
|
buckets.insert(bucket);
|
||||||
}
|
}
|
||||||
|
@ -443,8 +468,8 @@ BOOST_AUTO_TEST_CASE(caddrinfo_get_tried_bucket)
|
||||||
buckets.clear();
|
buckets.clear();
|
||||||
for (int j = 0; j < 255; j++) {
|
for (int j = 0; j < 255; j++) {
|
||||||
CAddrInfo infoj = CAddrInfo(
|
CAddrInfo infoj = CAddrInfo(
|
||||||
CAddress(CService("250." + boost::to_string(j) + ".1.1"), NODE_NONE),
|
CAddress(ResolveService("250." + boost::to_string(j) + ".1.1"), NODE_NONE),
|
||||||
CNetAddr("250." + boost::to_string(j) + ".1.1"));
|
ResolveIP("250." + boost::to_string(j) + ".1.1"));
|
||||||
int bucket = infoj.GetTriedBucket(nKey1);
|
int bucket = infoj.GetTriedBucket(nKey1);
|
||||||
buckets.insert(bucket);
|
buckets.insert(bucket);
|
||||||
}
|
}
|
||||||
|
@ -460,10 +485,10 @@ BOOST_AUTO_TEST_CASE(caddrinfo_get_new_bucket)
|
||||||
// Set addrman addr placement to be deterministic.
|
// Set addrman addr placement to be deterministic.
|
||||||
addrman.MakeDeterministic();
|
addrman.MakeDeterministic();
|
||||||
|
|
||||||
CAddress addr1 = CAddress(CService("250.1.2.1", 8333), NODE_NONE);
|
CAddress addr1 = CAddress(ResolveService("250.1.2.1", 8333), NODE_NONE);
|
||||||
CAddress addr2 = CAddress(CService("250.1.2.1", 9999), 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);
|
CAddrInfo info1 = CAddrInfo(addr1, source1);
|
||||||
|
|
||||||
|
@ -484,8 +509,8 @@ BOOST_AUTO_TEST_CASE(caddrinfo_get_new_bucket)
|
||||||
set<int> buckets;
|
set<int> buckets;
|
||||||
for (int i = 0; i < 255; i++) {
|
for (int i = 0; i < 255; i++) {
|
||||||
CAddrInfo infoi = CAddrInfo(
|
CAddrInfo infoi = CAddrInfo(
|
||||||
CAddress(CService("250.1.1." + boost::to_string(i)), NODE_NONE),
|
CAddress(ResolveService("250.1.1." + boost::to_string(i)), NODE_NONE),
|
||||||
CNetAddr("250.1.1." + boost::to_string(i)));
|
ResolveIP("250.1.1." + boost::to_string(i)));
|
||||||
int bucket = infoi.GetNewBucket(nKey1);
|
int bucket = infoi.GetNewBucket(nKey1);
|
||||||
buckets.insert(bucket);
|
buckets.insert(bucket);
|
||||||
}
|
}
|
||||||
|
@ -496,9 +521,9 @@ BOOST_AUTO_TEST_CASE(caddrinfo_get_new_bucket)
|
||||||
buckets.clear();
|
buckets.clear();
|
||||||
for (int j = 0; j < 4 * 255; j++) {
|
for (int j = 0; j < 4 * 255; j++) {
|
||||||
CAddrInfo infoj = CAddrInfo(CAddress(
|
CAddrInfo infoj = CAddrInfo(CAddress(
|
||||||
CService(
|
ResolveService(
|
||||||
boost::to_string(250 + (j / 255)) + "." + boost::to_string(j % 256) + ".1.1"), NODE_NONE),
|
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);
|
int bucket = infoj.GetNewBucket(nKey1);
|
||||||
buckets.insert(bucket);
|
buckets.insert(bucket);
|
||||||
}
|
}
|
||||||
|
@ -509,8 +534,8 @@ BOOST_AUTO_TEST_CASE(caddrinfo_get_new_bucket)
|
||||||
buckets.clear();
|
buckets.clear();
|
||||||
for (int p = 0; p < 255; p++) {
|
for (int p = 0; p < 255; p++) {
|
||||||
CAddrInfo infoj = CAddrInfo(
|
CAddrInfo infoj = CAddrInfo(
|
||||||
CAddress(CService("250.1.1.1"), NODE_NONE),
|
CAddress(ResolveService("250.1.1.1"), NODE_NONE),
|
||||||
CNetAddr("250." + boost::to_string(p) + ".1.1"));
|
ResolveIP("250." + boost::to_string(p) + ".1.1"));
|
||||||
int bucket = infoj.GetNewBucket(nKey1);
|
int bucket = infoj.GetNewBucket(nKey1);
|
||||||
buckets.insert(bucket);
|
buckets.insert(bucket);
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
#include "serialize.h"
|
#include "serialize.h"
|
||||||
#include "streams.h"
|
#include "streams.h"
|
||||||
#include "net.h"
|
#include "net.h"
|
||||||
|
#include "netbase.h"
|
||||||
#include "chainparams.h"
|
#include "chainparams.h"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
@ -51,8 +52,12 @@ public:
|
||||||
int nUBuckets = ADDRMAN_NEW_BUCKET_COUNT ^ (1 << 30);
|
int nUBuckets = ADDRMAN_NEW_BUCKET_COUNT ^ (1 << 30);
|
||||||
s << nUBuckets;
|
s << nUBuckets;
|
||||||
|
|
||||||
CAddress addr = CAddress(CService("252.1.1.1", 7777), NODE_NONE);
|
CService serv;
|
||||||
CAddrInfo info = CAddrInfo(addr, CNetAddr("252.2.2.2"));
|
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;
|
s << info;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -74,14 +79,17 @@ BOOST_AUTO_TEST_CASE(caddrdb_read)
|
||||||
CAddrManUncorrupted addrmanUncorrupted;
|
CAddrManUncorrupted addrmanUncorrupted;
|
||||||
addrmanUncorrupted.MakeDeterministic();
|
addrmanUncorrupted.MakeDeterministic();
|
||||||
|
|
||||||
CService addr1 = CService("250.7.1.1", 8333);
|
CService addr1, addr2, addr3;
|
||||||
CService addr2 = CService("250.7.2.2", 9999);
|
Lookup("250.7.1.1", addr1, 8333, false);
|
||||||
CService addr3 = CService("250.7.3.3", 9999);
|
Lookup("250.7.2.2", addr2, 9999, false);
|
||||||
|
Lookup("250.7.3.3", addr3, 9999, false);
|
||||||
|
|
||||||
// Add three addresses to new table.
|
// Add three addresses to new table.
|
||||||
addrmanUncorrupted.Add(CAddress(addr1, NODE_NONE), CService("252.5.1.1", 8333));
|
CService source;
|
||||||
addrmanUncorrupted.Add(CAddress(addr2, NODE_NONE), CService("252.5.1.1", 8333));
|
Lookup("252.5.1.1", source, 8333, false);
|
||||||
addrmanUncorrupted.Add(CAddress(addr3, NODE_NONE), CService("252.5.1.1", 8333));
|
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.
|
// Test that the de-serialization does not throw an exception.
|
||||||
CDataStream ssPeers1 = AddrmanToStream(addrmanUncorrupted);
|
CDataStream ssPeers1 = AddrmanToStream(addrmanUncorrupted);
|
||||||
|
|
|
@ -14,37 +14,54 @@ using namespace std;
|
||||||
|
|
||||||
BOOST_FIXTURE_TEST_SUITE(netbase_tests, BasicTestingSetup)
|
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_AUTO_TEST_CASE(netbase_networks)
|
||||||
{
|
{
|
||||||
BOOST_CHECK(CNetAddr("127.0.0.1").GetNetwork() == NET_UNROUTABLE);
|
BOOST_CHECK(ResolveIP("127.0.0.1").GetNetwork() == NET_UNROUTABLE);
|
||||||
BOOST_CHECK(CNetAddr("::1").GetNetwork() == NET_UNROUTABLE);
|
BOOST_CHECK(ResolveIP("::1").GetNetwork() == NET_UNROUTABLE);
|
||||||
BOOST_CHECK(CNetAddr("8.8.8.8").GetNetwork() == NET_IPV4);
|
BOOST_CHECK(ResolveIP("8.8.8.8").GetNetwork() == NET_IPV4);
|
||||||
BOOST_CHECK(CNetAddr("2001::8888").GetNetwork() == NET_IPV6);
|
BOOST_CHECK(ResolveIP("2001::8888").GetNetwork() == NET_IPV6);
|
||||||
BOOST_CHECK(CNetAddr("FD87:D87E:EB43:edb1:8e4:3588:e546:35ca").GetNetwork() == NET_TOR);
|
BOOST_CHECK(ResolveIP("FD87:D87E:EB43:edb1:8e4:3588:e546:35ca").GetNetwork() == NET_TOR);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(netbase_properties)
|
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(ResolveIP("127.0.0.1").IsIPv4());
|
||||||
BOOST_CHECK(CNetAddr("::1").IsIPv6());
|
BOOST_CHECK(ResolveIP("::FFFF:192.168.1.1").IsIPv4());
|
||||||
BOOST_CHECK(CNetAddr("10.0.0.1").IsRFC1918());
|
BOOST_CHECK(ResolveIP("::1").IsIPv6());
|
||||||
BOOST_CHECK(CNetAddr("192.168.1.1").IsRFC1918());
|
BOOST_CHECK(ResolveIP("10.0.0.1").IsRFC1918());
|
||||||
BOOST_CHECK(CNetAddr("172.31.255.255").IsRFC1918());
|
BOOST_CHECK(ResolveIP("192.168.1.1").IsRFC1918());
|
||||||
BOOST_CHECK(CNetAddr("2001:0DB8::").IsRFC3849());
|
BOOST_CHECK(ResolveIP("172.31.255.255").IsRFC1918());
|
||||||
BOOST_CHECK(CNetAddr("169.254.1.1").IsRFC3927());
|
BOOST_CHECK(ResolveIP("2001:0DB8::").IsRFC3849());
|
||||||
BOOST_CHECK(CNetAddr("2002::1").IsRFC3964());
|
BOOST_CHECK(ResolveIP("169.254.1.1").IsRFC3927());
|
||||||
BOOST_CHECK(CNetAddr("FC00::").IsRFC4193());
|
BOOST_CHECK(ResolveIP("2002::1").IsRFC3964());
|
||||||
BOOST_CHECK(CNetAddr("2001::2").IsRFC4380());
|
BOOST_CHECK(ResolveIP("FC00::").IsRFC4193());
|
||||||
BOOST_CHECK(CNetAddr("2001:10::").IsRFC4843());
|
BOOST_CHECK(ResolveIP("2001::2").IsRFC4380());
|
||||||
BOOST_CHECK(CNetAddr("FE80::").IsRFC4862());
|
BOOST_CHECK(ResolveIP("2001:10::").IsRFC4843());
|
||||||
BOOST_CHECK(CNetAddr("64:FF9B::").IsRFC6052());
|
BOOST_CHECK(ResolveIP("FE80::").IsRFC4862());
|
||||||
BOOST_CHECK(CNetAddr("FD87:D87E:EB43:edb1:8e4:3588:e546:35ca").IsTor());
|
BOOST_CHECK(ResolveIP("64:FF9B::").IsRFC6052());
|
||||||
BOOST_CHECK(CNetAddr("127.0.0.1").IsLocal());
|
BOOST_CHECK(ResolveIP("FD87:D87E:EB43:edb1:8e4:3588:e546:35ca").IsTor());
|
||||||
BOOST_CHECK(CNetAddr("::1").IsLocal());
|
BOOST_CHECK(ResolveIP("127.0.0.1").IsLocal());
|
||||||
BOOST_CHECK(CNetAddr("8.8.8.8").IsRoutable());
|
BOOST_CHECK(ResolveIP("::1").IsLocal());
|
||||||
BOOST_CHECK(CNetAddr("2001::1").IsRoutable());
|
BOOST_CHECK(ResolveIP("8.8.8.8").IsRoutable());
|
||||||
BOOST_CHECK(CNetAddr("127.0.0.1").IsValid());
|
BOOST_CHECK(ResolveIP("2001::1").IsRoutable());
|
||||||
|
BOOST_CHECK(ResolveIP("127.0.0.1").IsValid());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool static TestSplitHost(string test, string host, int port)
|
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)
|
bool static TestParse(string src, string canon)
|
||||||
{
|
{
|
||||||
CService addr;
|
CService addr(LookupNumeric(src.c_str(), 65535));
|
||||||
if (!LookupNumeric(src.c_str(), addr, 65535))
|
|
||||||
return canon == "";
|
|
||||||
return canon == addr.ToString();
|
return canon == addr.ToString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -90,165 +105,185 @@ BOOST_AUTO_TEST_CASE(netbase_lookupnumeric)
|
||||||
BOOST_CHECK(TestParse("::", "[::]:65535"));
|
BOOST_CHECK(TestParse("::", "[::]:65535"));
|
||||||
BOOST_CHECK(TestParse("[::]:8333", "[::]:8333"));
|
BOOST_CHECK(TestParse("[::]:8333", "[::]:8333"));
|
||||||
BOOST_CHECK(TestParse("[127.0.0.1]", "127.0.0.1:65535"));
|
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)
|
BOOST_AUTO_TEST_CASE(onioncat_test)
|
||||||
{
|
{
|
||||||
|
|
||||||
// values from https://web.archive.org/web/20121122003543/http://www.cypherpunk.at/onioncat/wiki/OnionCat
|
// values from https://web.archive.org/web/20121122003543/http://www.cypherpunk.at/onioncat/wiki/OnionCat
|
||||||
CNetAddr addr1("5wyqrzbvrdsumnok.onion");
|
CNetAddr addr1(ResolveIP("5wyqrzbvrdsumnok.onion"));
|
||||||
CNetAddr addr2("FD87:D87E:EB43:edb1:8e4:3588:e546:35ca");
|
CNetAddr addr2(ResolveIP("FD87:D87E:EB43:edb1:8e4:3588:e546:35ca"));
|
||||||
BOOST_CHECK(addr1 == addr2);
|
BOOST_CHECK(addr1 == addr2);
|
||||||
BOOST_CHECK(addr1.IsTor());
|
BOOST_CHECK(addr1.IsTor());
|
||||||
BOOST_CHECK(addr1.ToStringIP() == "5wyqrzbvrdsumnok.onion");
|
BOOST_CHECK(addr1.ToStringIP() == "5wyqrzbvrdsumnok.onion");
|
||||||
BOOST_CHECK(addr1.IsRoutable());
|
BOOST_CHECK(addr1.IsRoutable());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(subnet_test)
|
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(ResolveSubNet("1.2.3.0/24") == ResolveSubNet("1.2.3.0/255.255.255.0"));
|
||||||
BOOST_CHECK(CSubNet("1.2.3.0/24").Match(CNetAddr("1.2.3.4")));
|
BOOST_CHECK(ResolveSubNet("1.2.3.0/24") != ResolveSubNet("1.2.4.0/255.255.255.0"));
|
||||||
BOOST_CHECK(!CSubNet("1.2.2.0/24").Match(CNetAddr("1.2.3.4")));
|
BOOST_CHECK(ResolveSubNet("1.2.3.0/24").Match(ResolveIP("1.2.3.4")));
|
||||||
BOOST_CHECK(CSubNet("1.2.3.4").Match(CNetAddr("1.2.3.4")));
|
BOOST_CHECK(!ResolveSubNet("1.2.2.0/24").Match(ResolveIP("1.2.3.4")));
|
||||||
BOOST_CHECK(CSubNet("1.2.3.4/32").Match(CNetAddr("1.2.3.4")));
|
BOOST_CHECK(ResolveSubNet("1.2.3.4").Match(ResolveIP("1.2.3.4")));
|
||||||
BOOST_CHECK(!CSubNet("1.2.3.4").Match(CNetAddr("5.6.7.8")));
|
BOOST_CHECK(ResolveSubNet("1.2.3.4/32").Match(ResolveIP("1.2.3.4")));
|
||||||
BOOST_CHECK(!CSubNet("1.2.3.4/32").Match(CNetAddr("5.6.7.8")));
|
BOOST_CHECK(!ResolveSubNet("1.2.3.4").Match(ResolveIP("5.6.7.8")));
|
||||||
BOOST_CHECK(CSubNet("::ffff:127.0.0.1").Match(CNetAddr("127.0.0.1")));
|
BOOST_CHECK(!ResolveSubNet("1.2.3.4/32").Match(ResolveIP("5.6.7.8")));
|
||||||
BOOST_CHECK(CSubNet("1:2:3:4:5:6:7:8").Match(CNetAddr("1:2:3:4:5:6:7:8")));
|
BOOST_CHECK(ResolveSubNet("::ffff:127.0.0.1").Match(ResolveIP("127.0.0.1")));
|
||||||
BOOST_CHECK(!CSubNet("1:2:3:4:5:6:7:8").Match(CNetAddr("1:2:3:4:5:6:7:9")));
|
BOOST_CHECK(ResolveSubNet("1:2:3:4:5:6:7:8").Match(ResolveIP("1:2:3:4:5:6:7:8")));
|
||||||
BOOST_CHECK(CSubNet("1:2:3:4:5:6:7:0/112").Match(CNetAddr("1:2:3:4:5:6:7:1234")));
|
BOOST_CHECK(!ResolveSubNet("1:2:3:4:5:6:7:8").Match(ResolveIP("1:2:3:4:5:6:7:9")));
|
||||||
BOOST_CHECK(CSubNet("192.168.0.1/24").Match(CNetAddr("192.168.0.2")));
|
BOOST_CHECK(ResolveSubNet("1:2:3:4:5:6:7:0/112").Match(ResolveIP("1:2:3:4:5:6:7:1234")));
|
||||||
BOOST_CHECK(CSubNet("192.168.0.20/29").Match(CNetAddr("192.168.0.18")));
|
BOOST_CHECK(ResolveSubNet("192.168.0.1/24").Match(ResolveIP("192.168.0.2")));
|
||||||
BOOST_CHECK(CSubNet("1.2.2.1/24").Match(CNetAddr("1.2.2.4")));
|
BOOST_CHECK(ResolveSubNet("192.168.0.20/29").Match(ResolveIP("192.168.0.18")));
|
||||||
BOOST_CHECK(CSubNet("1.2.2.110/31").Match(CNetAddr("1.2.2.111")));
|
BOOST_CHECK(ResolveSubNet("1.2.2.1/24").Match(ResolveIP("1.2.2.4")));
|
||||||
BOOST_CHECK(CSubNet("1.2.2.20/26").Match(CNetAddr("1.2.2.63")));
|
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
|
// All-Matching IPv6 Matches arbitrary IPv4 and IPv6
|
||||||
BOOST_CHECK(CSubNet("::/0").Match(CNetAddr("1:2:3:4:5:6:7:1234")));
|
BOOST_CHECK(ResolveSubNet("::/0").Match(ResolveIP("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")));
|
||||||
// All-Matching IPv4 does not Match IPv6
|
// 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)
|
// Invalid subnets Match nothing (not even invalid addresses)
|
||||||
BOOST_CHECK(!CSubNet().Match(CNetAddr("1.2.3.4")));
|
BOOST_CHECK(!CSubNet().Match(ResolveIP("1.2.3.4")));
|
||||||
BOOST_CHECK(!CSubNet("").Match(CNetAddr("4.5.6.7")));
|
BOOST_CHECK(!ResolveSubNet("").Match(ResolveIP("4.5.6.7")));
|
||||||
BOOST_CHECK(!CSubNet("bloop").Match(CNetAddr("0.0.0.0")));
|
BOOST_CHECK(!ResolveSubNet("bloop").Match(ResolveIP("0.0.0.0")));
|
||||||
BOOST_CHECK(!CSubNet("bloop").Match(CNetAddr("hab")));
|
BOOST_CHECK(!ResolveSubNet("bloop").Match(ResolveIP("hab")));
|
||||||
// Check valid/invalid
|
// Check valid/invalid
|
||||||
BOOST_CHECK(CSubNet("1.2.3.0/0").IsValid());
|
BOOST_CHECK(ResolveSubNet("1.2.3.0/0").IsValid());
|
||||||
BOOST_CHECK(!CSubNet("1.2.3.0/-1").IsValid());
|
BOOST_CHECK(!ResolveSubNet("1.2.3.0/-1").IsValid());
|
||||||
BOOST_CHECK(CSubNet("1.2.3.0/32").IsValid());
|
BOOST_CHECK(ResolveSubNet("1.2.3.0/32").IsValid());
|
||||||
BOOST_CHECK(!CSubNet("1.2.3.0/33").IsValid());
|
BOOST_CHECK(!ResolveSubNet("1.2.3.0/33").IsValid());
|
||||||
BOOST_CHECK(CSubNet("1:2:3:4:5:6:7:8/0").IsValid());
|
BOOST_CHECK(ResolveSubNet("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(ResolveSubNet("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(!ResolveSubNet("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(ResolveSubNet("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(!ResolveSubNet("1:2:3:4:5:6:7:8/129").IsValid());
|
||||||
BOOST_CHECK(!CSubNet("fuzzy").IsValid());
|
BOOST_CHECK(!ResolveSubNet("fuzzy").IsValid());
|
||||||
|
|
||||||
//CNetAddr constructor test
|
//CNetAddr constructor test
|
||||||
BOOST_CHECK(CSubNet(CNetAddr("127.0.0.1")).IsValid());
|
BOOST_CHECK(CSubNet(ResolveIP("127.0.0.1")).IsValid());
|
||||||
BOOST_CHECK(CSubNet(CNetAddr("127.0.0.1")).Match(CNetAddr("127.0.0.1")));
|
BOOST_CHECK(CSubNet(ResolveIP("127.0.0.1")).Match(ResolveIP("127.0.0.1")));
|
||||||
BOOST_CHECK(!CSubNet(CNetAddr("127.0.0.1")).Match(CNetAddr("127.0.0.2")));
|
BOOST_CHECK(!CSubNet(ResolveIP("127.0.0.1")).Match(ResolveIP("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")).ToString() == "127.0.0.1/32");
|
||||||
|
|
||||||
BOOST_CHECK(CSubNet(CNetAddr("1:2:3:4:5:6:7:8")).IsValid());
|
CSubNet subnet = CSubNet(ResolveIP("1.2.3.4"), 32);
|
||||||
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("1.2.3.4/255.255.255.255");
|
|
||||||
BOOST_CHECK_EQUAL(subnet.ToString(), "1.2.3.4/32");
|
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"), 8);
|
||||||
BOOST_CHECK_EQUAL(subnet.ToString(), "1.2.3.4/31");
|
|
||||||
subnet = CSubNet("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");
|
|
||||||
BOOST_CHECK_EQUAL(subnet.ToString(), "1.2.3.0/29");
|
|
||||||
subnet = CSubNet("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");
|
|
||||||
BOOST_CHECK_EQUAL(subnet.ToString(), "1.2.3.0/27");
|
|
||||||
subnet = CSubNet("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");
|
|
||||||
BOOST_CHECK_EQUAL(subnet.ToString(), "1.2.3.0/25");
|
|
||||||
subnet = CSubNet("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");
|
|
||||||
BOOST_CHECK_EQUAL(subnet.ToString(), "1.2.2.0/23");
|
|
||||||
subnet = CSubNet("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");
|
|
||||||
BOOST_CHECK_EQUAL(subnet.ToString(), "1.2.0.0/21");
|
|
||||||
subnet = CSubNet("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");
|
|
||||||
BOOST_CHECK_EQUAL(subnet.ToString(), "1.2.0.0/19");
|
|
||||||
subnet = CSubNet("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");
|
|
||||||
BOOST_CHECK_EQUAL(subnet.ToString(), "1.2.0.0/17");
|
|
||||||
subnet = CSubNet("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");
|
|
||||||
BOOST_CHECK_EQUAL(subnet.ToString(), "1.2.0.0/15");
|
|
||||||
subnet = CSubNet("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");
|
|
||||||
BOOST_CHECK_EQUAL(subnet.ToString(), "1.0.0.0/13");
|
|
||||||
subnet = CSubNet("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");
|
|
||||||
BOOST_CHECK_EQUAL(subnet.ToString(), "1.0.0.0/11");
|
|
||||||
subnet = CSubNet("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");
|
|
||||||
BOOST_CHECK_EQUAL(subnet.ToString(), "1.0.0.0/9");
|
|
||||||
subnet = CSubNet("1.2.3.4/255.0.0.0");
|
|
||||||
BOOST_CHECK_EQUAL(subnet.ToString(), "1.0.0.0/8");
|
BOOST_CHECK_EQUAL(subnet.ToString(), "1.0.0.0/8");
|
||||||
subnet = CSubNet("1.2.3.4/254.0.0.0");
|
subnet = CSubNet(ResolveIP("1.2.3.4"), 0);
|
||||||
BOOST_CHECK_EQUAL(subnet.ToString(), "0.0.0.0/7");
|
|
||||||
subnet = CSubNet("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");
|
|
||||||
BOOST_CHECK_EQUAL(subnet.ToString(), "0.0.0.0/5");
|
|
||||||
subnet = CSubNet("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");
|
|
||||||
BOOST_CHECK_EQUAL(subnet.ToString(), "0.0.0.0/3");
|
|
||||||
subnet = CSubNet("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");
|
|
||||||
BOOST_CHECK_EQUAL(subnet.ToString(), "0.0.0.0/1");
|
|
||||||
subnet = CSubNet("1.2.3.4/0.0.0.0");
|
|
||||||
BOOST_CHECK_EQUAL(subnet.ToString(), "0.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 = CSubNet(ResolveIP("1.2.3.4"), ResolveIP("255.255.255.255"));
|
||||||
|
BOOST_CHECK_EQUAL(subnet.ToString(), "1.2.3.4/32");
|
||||||
|
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 = ResolveSubNet("1.2.3.4/255.255.255.252");
|
||||||
|
BOOST_CHECK_EQUAL(subnet.ToString(), "1.2.3.4/30");
|
||||||
|
subnet = ResolveSubNet("1.2.3.4/255.255.255.248");
|
||||||
|
BOOST_CHECK_EQUAL(subnet.ToString(), "1.2.3.0/29");
|
||||||
|
subnet = ResolveSubNet("1.2.3.4/255.255.255.240");
|
||||||
|
BOOST_CHECK_EQUAL(subnet.ToString(), "1.2.3.0/28");
|
||||||
|
subnet = ResolveSubNet("1.2.3.4/255.255.255.224");
|
||||||
|
BOOST_CHECK_EQUAL(subnet.ToString(), "1.2.3.0/27");
|
||||||
|
subnet = ResolveSubNet("1.2.3.4/255.255.255.192");
|
||||||
|
BOOST_CHECK_EQUAL(subnet.ToString(), "1.2.3.0/26");
|
||||||
|
subnet = ResolveSubNet("1.2.3.4/255.255.255.128");
|
||||||
|
BOOST_CHECK_EQUAL(subnet.ToString(), "1.2.3.0/25");
|
||||||
|
subnet = ResolveSubNet("1.2.3.4/255.255.255.0");
|
||||||
|
BOOST_CHECK_EQUAL(subnet.ToString(), "1.2.3.0/24");
|
||||||
|
subnet = ResolveSubNet("1.2.3.4/255.255.254.0");
|
||||||
|
BOOST_CHECK_EQUAL(subnet.ToString(), "1.2.2.0/23");
|
||||||
|
subnet = ResolveSubNet("1.2.3.4/255.255.252.0");
|
||||||
|
BOOST_CHECK_EQUAL(subnet.ToString(), "1.2.0.0/22");
|
||||||
|
subnet = ResolveSubNet("1.2.3.4/255.255.248.0");
|
||||||
|
BOOST_CHECK_EQUAL(subnet.ToString(), "1.2.0.0/21");
|
||||||
|
subnet = ResolveSubNet("1.2.3.4/255.255.240.0");
|
||||||
|
BOOST_CHECK_EQUAL(subnet.ToString(), "1.2.0.0/20");
|
||||||
|
subnet = ResolveSubNet("1.2.3.4/255.255.224.0");
|
||||||
|
BOOST_CHECK_EQUAL(subnet.ToString(), "1.2.0.0/19");
|
||||||
|
subnet = ResolveSubNet("1.2.3.4/255.255.192.0");
|
||||||
|
BOOST_CHECK_EQUAL(subnet.ToString(), "1.2.0.0/18");
|
||||||
|
subnet = ResolveSubNet("1.2.3.4/255.255.128.0");
|
||||||
|
BOOST_CHECK_EQUAL(subnet.ToString(), "1.2.0.0/17");
|
||||||
|
subnet = ResolveSubNet("1.2.3.4/255.255.0.0");
|
||||||
|
BOOST_CHECK_EQUAL(subnet.ToString(), "1.2.0.0/16");
|
||||||
|
subnet = ResolveSubNet("1.2.3.4/255.254.0.0");
|
||||||
|
BOOST_CHECK_EQUAL(subnet.ToString(), "1.2.0.0/15");
|
||||||
|
subnet = ResolveSubNet("1.2.3.4/255.252.0.0");
|
||||||
|
BOOST_CHECK_EQUAL(subnet.ToString(), "1.0.0.0/14");
|
||||||
|
subnet = ResolveSubNet("1.2.3.4/255.248.0.0");
|
||||||
|
BOOST_CHECK_EQUAL(subnet.ToString(), "1.0.0.0/13");
|
||||||
|
subnet = ResolveSubNet("1.2.3.4/255.240.0.0");
|
||||||
|
BOOST_CHECK_EQUAL(subnet.ToString(), "1.0.0.0/12");
|
||||||
|
subnet = ResolveSubNet("1.2.3.4/255.224.0.0");
|
||||||
|
BOOST_CHECK_EQUAL(subnet.ToString(), "1.0.0.0/11");
|
||||||
|
subnet = ResolveSubNet("1.2.3.4/255.192.0.0");
|
||||||
|
BOOST_CHECK_EQUAL(subnet.ToString(), "1.0.0.0/10");
|
||||||
|
subnet = ResolveSubNet("1.2.3.4/255.128.0.0");
|
||||||
|
BOOST_CHECK_EQUAL(subnet.ToString(), "1.0.0.0/9");
|
||||||
|
subnet = ResolveSubNet("1.2.3.4/255.0.0.0");
|
||||||
|
BOOST_CHECK_EQUAL(subnet.ToString(), "1.0.0.0/8");
|
||||||
|
subnet = ResolveSubNet("1.2.3.4/254.0.0.0");
|
||||||
|
BOOST_CHECK_EQUAL(subnet.ToString(), "0.0.0.0/7");
|
||||||
|
subnet = ResolveSubNet("1.2.3.4/252.0.0.0");
|
||||||
|
BOOST_CHECK_EQUAL(subnet.ToString(), "0.0.0.0/6");
|
||||||
|
subnet = ResolveSubNet("1.2.3.4/248.0.0.0");
|
||||||
|
BOOST_CHECK_EQUAL(subnet.ToString(), "0.0.0.0/5");
|
||||||
|
subnet = ResolveSubNet("1.2.3.4/240.0.0.0");
|
||||||
|
BOOST_CHECK_EQUAL(subnet.ToString(), "0.0.0.0/4");
|
||||||
|
subnet = ResolveSubNet("1.2.3.4/224.0.0.0");
|
||||||
|
BOOST_CHECK_EQUAL(subnet.ToString(), "0.0.0.0/3");
|
||||||
|
subnet = ResolveSubNet("1.2.3.4/192.0.0.0");
|
||||||
|
BOOST_CHECK_EQUAL(subnet.ToString(), "0.0.0.0/2");
|
||||||
|
subnet = ResolveSubNet("1.2.3.4/128.0.0.0");
|
||||||
|
BOOST_CHECK_EQUAL(subnet.ToString(), "0.0.0.0/1");
|
||||||
|
subnet = ResolveSubNet("1.2.3.4/0.0.0.0");
|
||||||
|
BOOST_CHECK_EQUAL(subnet.ToString(), "0.0.0.0/0");
|
||||||
|
|
||||||
|
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");
|
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");
|
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");
|
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");
|
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_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_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(ResolveIP("127.0.0.1").GetGroup() == boost::assign::list_of(0)); // Local -> !Routable()
|
||||||
BOOST_CHECK(CNetAddr("10.0.0.1").GetGroup() == boost::assign::list_of(0)); // RFC1918 -> !Routable()
|
BOOST_CHECK(ResolveIP("257.0.0.1").GetGroup() == boost::assign::list_of(0)); // !Valid -> !Routable()
|
||||||
BOOST_CHECK(CNetAddr("169.254.1.1").GetGroup() == boost::assign::list_of(0)); // RFC3927 -> !Routable()
|
BOOST_CHECK(ResolveIP("10.0.0.1").GetGroup() == boost::assign::list_of(0)); // RFC1918 -> !Routable()
|
||||||
BOOST_CHECK(CNetAddr("1.2.3.4").GetGroup() == boost::assign::list_of((unsigned char)NET_IPV4)(1)(2)); // IPv4
|
BOOST_CHECK(ResolveIP("169.254.1.1").GetGroup() == boost::assign::list_of(0)); // RFC3927 -> !Routable()
|
||||||
BOOST_CHECK(CNetAddr("::FFFF:0:102:304").GetGroup() == boost::assign::list_of((unsigned char)NET_IPV4)(1)(2)); // RFC6145
|
BOOST_CHECK(ResolveIP("1.2.3.4").GetGroup() == boost::assign::list_of((unsigned char)NET_IPV4)(1)(2)); // IPv4
|
||||||
BOOST_CHECK(CNetAddr("64:FF9B::102:304").GetGroup() == boost::assign::list_of((unsigned char)NET_IPV4)(1)(2)); // RFC6052
|
BOOST_CHECK(ResolveIP("::FFFF:0:102:304").GetGroup() == boost::assign::list_of((unsigned char)NET_IPV4)(1)(2)); // RFC6145
|
||||||
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(ResolveIP("64:FF9B::102:304").GetGroup() == boost::assign::list_of((unsigned char)NET_IPV4)(1)(2)); // RFC6052
|
||||||
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(ResolveIP("2002:102:304:9999:9999:9999:9999:9999").GetGroup() == boost::assign::list_of((unsigned char)NET_IPV4)(1)(2)); // RFC3964
|
||||||
BOOST_CHECK(CNetAddr("FD87:D87E:EB43:edb1:8e4:3588:e546:35ca").GetGroup() == boost::assign::list_of((unsigned char)NET_TOR)(239)); // Tor
|
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(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(ResolveIP("FD87:D87E:EB43:edb1:8e4:3588:e546:35ca").GetGroup() == boost::assign::list_of((unsigned char)NET_TOR)(239)); // Tor
|
||||||
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("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()
|
BOOST_AUTO_TEST_SUITE_END()
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
|
|
||||||
#include "timedata.h"
|
#include "timedata.h"
|
||||||
|
|
||||||
#include "netbase.h"
|
#include "netaddress.h"
|
||||||
#include "sync.h"
|
#include "sync.h"
|
||||||
#include "ui_interface.h"
|
#include "ui_interface.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
|
|
||||||
#include "torcontrol.h"
|
#include "torcontrol.h"
|
||||||
#include "utilstrencodings.h"
|
#include "utilstrencodings.h"
|
||||||
|
#include "netbase.h"
|
||||||
#include "net.h"
|
#include "net.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "crypto/hmac_sha256.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())
|
if ((i = m.find("PrivateKey")) != m.end())
|
||||||
private_key = i->second;
|
private_key = i->second;
|
||||||
}
|
}
|
||||||
|
service = LookupNumeric(std::string(service_id+".onion").c_str(), GetListenPort());
|
||||||
service = CService(service_id+".onion", GetListenPort());
|
|
||||||
LogPrintf("tor: Got service ID %s, advertising service %s\n", service_id, service.ToString());
|
LogPrintf("tor: Got service ID %s, advertising service %s\n", service_id, service.ToString());
|
||||||
if (WriteBinaryFile(GetPrivateKeyFile(), private_key)) {
|
if (WriteBinaryFile(GetPrivateKeyFile(), private_key)) {
|
||||||
LogPrint("tor", "tor: Cached service private key to %s\n", GetPrivateKeyFile());
|
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
|
// Now that we know Tor is running setup the proxy for onion addresses
|
||||||
// if -onion isn't set to something else.
|
// if -onion isn't set to something else.
|
||||||
if (GetArg("-onion", "") == "") {
|
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);
|
SetProxy(NET_TOR, addrOnion);
|
||||||
SetLimited(NET_TOR, false);
|
SetLimited(NET_TOR, false);
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,7 +10,6 @@
|
||||||
#include "init.h"
|
#include "init.h"
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
#include "net.h"
|
#include "net.h"
|
||||||
#include "netbase.h"
|
|
||||||
#include "policy/rbf.h"
|
#include "policy/rbf.h"
|
||||||
#include "rpc/server.h"
|
#include "rpc/server.h"
|
||||||
#include "timedata.h"
|
#include "timedata.h"
|
||||||
|
|
Loading…
Add table
Reference in a new issue