Changeset View
Changeset View
Standalone View
Standalone View
src/seeder/netbase.cpp
Show All 18 Lines | |||||
typedef std::pair<CSeederService, int> proxyType; | typedef std::pair<CSeederService, int> proxyType; | ||||
static proxyType proxyInfo[NET_MAX]; | static proxyType proxyInfo[NET_MAX]; | ||||
static proxyType nameproxyInfo; | static proxyType nameproxyInfo; | ||||
int nConnectTimeout = 5000; | int nConnectTimeout = 5000; | ||||
bool fNameLookup = false; | bool fNameLookup = false; | ||||
static const uint8_t pchIPv4[12] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff}; | static const uint8_t pchIPv4[12] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff}; | ||||
enum Network ParseNetwork(std::string net) { | static void SplitHostPort(std::string in, int &portOut, std::string &hostOut) { | ||||
boost::to_lower(net); | |||||
if (net == "ipv4") return NET_IPV4; | |||||
if (net == "ipv6") return NET_IPV6; | |||||
if (net == "tor") return NET_TOR; | |||||
return NET_UNROUTABLE; | |||||
} | |||||
void SplitHostPort(std::string in, int &portOut, std::string &hostOut) { | |||||
size_t colon = in.find_last_of(':'); | size_t colon = in.find_last_of(':'); | ||||
// if a : is found, and it either follows a [...], or no other : is in the | // if a : is found, and it either follows a [...], or no other : is in the | ||||
// string, treat it as port separator | // string, treat it as port separator | ||||
bool fHaveColon = colon != in.npos; | bool fHaveColon = colon != in.npos; | ||||
// if there is a colon, and in[0]=='[', colon is not 0, so in[colon-1] is | // if there is a colon, and in[0]=='[', colon is not 0, so in[colon-1] is | ||||
// safe | // safe | ||||
bool fBracketed = fHaveColon && (in[0] == '[' && in[colon - 1] == ']'); | bool fBracketed = fHaveColon && (in[0] == '[' && in[colon - 1] == ']'); | ||||
bool fMultiColon = | bool fMultiColon = | ||||
▲ Show 20 Lines • Show All 72 Lines • ▼ Show 20 Lines | bool LookupHost(const char *pszName, std::vector<CNetAddr> &vIP, | ||||
if (psz[0] == '[' && psz[strlen(psz) - 1] == ']') { | if (psz[0] == '[' && psz[strlen(psz) - 1] == ']') { | ||||
pszHost = psz + 1; | pszHost = psz + 1; | ||||
psz[strlen(psz) - 1] = 0; | psz[strlen(psz) - 1] = 0; | ||||
} | } | ||||
return LookupIntern(pszHost, vIP, nMaxSolutions, fAllowLookup); | return LookupIntern(pszHost, vIP, nMaxSolutions, fAllowLookup); | ||||
} | } | ||||
bool LookupHostNumeric(const char *pszName, std::vector<CNetAddr> &vIP, | static bool Lookup(const char *pszName, std::vector<CSeederService> &vAddr, | ||||
int portDefault, bool fAllowLookup, | |||||
unsigned int nMaxSolutions) { | unsigned int nMaxSolutions) { | ||||
return LookupHost(pszName, vIP, nMaxSolutions, false); | |||||
} | |||||
bool Lookup(const char *pszName, std::vector<CSeederService> &vAddr, | |||||
int portDefault, bool fAllowLookup, unsigned int nMaxSolutions) { | |||||
if (pszName[0] == 0) return false; | if (pszName[0] == 0) return false; | ||||
int port = portDefault; | int port = portDefault; | ||||
std::string hostname = ""; | std::string hostname = ""; | ||||
SplitHostPort(std::string(pszName), port, hostname); | SplitHostPort(std::string(pszName), port, hostname); | ||||
std::vector<CNetAddr> vIP; | std::vector<CNetAddr> vIP; | ||||
bool fRet = | bool fRet = | ||||
LookupIntern(hostname.c_str(), vIP, nMaxSolutions, fAllowLookup); | LookupIntern(hostname.c_str(), vIP, nMaxSolutions, fAllowLookup); | ||||
if (!fRet) return false; | if (!fRet) return false; | ||||
vAddr.resize(vIP.size()); | vAddr.resize(vIP.size()); | ||||
for (unsigned int i = 0; i < vIP.size(); i++) | for (unsigned int i = 0; i < vIP.size(); i++) | ||||
vAddr[i] = CSeederService(vIP[i], port); | vAddr[i] = CSeederService(vIP[i], port); | ||||
return true; | return true; | ||||
} | } | ||||
bool Lookup(const char *pszName, CSeederService &addr, int portDefault, | static bool Lookup(const char *pszName, CSeederService &addr, int portDefault, | ||||
bool fAllowLookup) { | bool fAllowLookup) { | ||||
std::vector<CSeederService> vService; | std::vector<CSeederService> vService; | ||||
bool fRet = Lookup(pszName, vService, portDefault, fAllowLookup, 1); | bool fRet = Lookup(pszName, vService, portDefault, fAllowLookup, 1); | ||||
if (!fRet) return false; | if (!fRet) return false; | ||||
addr = vService[0]; | addr = vService[0]; | ||||
return true; | return true; | ||||
} | } | ||||
bool LookupNumeric(const char *pszName, CSeederService &addr, int portDefault) { | |||||
return Lookup(pszName, addr, portDefault, false); | |||||
} | |||||
static bool Socks4(const CSeederService &addrDest, SOCKET &hSocket) { | static bool Socks4(const CSeederService &addrDest, SOCKET &hSocket) { | ||||
printf("SOCKS4 connecting %s\n", addrDest.ToString().c_str()); | printf("SOCKS4 connecting %s\n", addrDest.ToString().c_str()); | ||||
if (!addrDest.IsIPv4()) { | if (!addrDest.IsIPv4()) { | ||||
closesocket(hSocket); | closesocket(hSocket); | ||||
return error("Proxy destination is not IPv4"); | return error("Proxy destination is not IPv4"); | ||||
} | } | ||||
char pszSocks4IP[] = "\4\1\0\0\0\0\0\0user"; | char pszSocks4IP[] = "\4\1\0\0\0\0\0\0user"; | ||||
struct sockaddr_in addr; | struct sockaddr_in addr; | ||||
▲ Show 20 Lines • Show All 242 Lines • ▼ Show 20 Lines | bool SetProxy(enum Network net, CSeederService addrProxy, int nSocksVersion) { | ||||
assert(net >= 0 && net < NET_MAX); | assert(net >= 0 && net < NET_MAX); | ||||
if (nSocksVersion != 0 && nSocksVersion != 4 && nSocksVersion != 5) | if (nSocksVersion != 0 && nSocksVersion != 4 && nSocksVersion != 5) | ||||
return false; | return false; | ||||
if (nSocksVersion != 0 && !addrProxy.IsValid()) return false; | if (nSocksVersion != 0 && !addrProxy.IsValid()) return false; | ||||
proxyInfo[net] = std::make_pair(addrProxy, nSocksVersion); | proxyInfo[net] = std::make_pair(addrProxy, nSocksVersion); | ||||
return true; | return true; | ||||
} | } | ||||
bool GetProxy(enum Network net, CSeederService &addrProxy) { | |||||
assert(net >= 0 && net < NET_MAX); | |||||
if (!proxyInfo[net].second) return false; | |||||
addrProxy = proxyInfo[net].first; | |||||
return true; | |||||
} | |||||
bool SetNameProxy(CSeederService addrProxy, int nSocksVersion) { | |||||
if (nSocksVersion != 0 && nSocksVersion != 5) return false; | |||||
if (nSocksVersion != 0 && !addrProxy.IsValid()) return false; | |||||
nameproxyInfo = std::make_pair(addrProxy, nSocksVersion); | |||||
return true; | |||||
} | |||||
bool GetNameProxy() { | |||||
return nameproxyInfo.second != 0; | |||||
} | |||||
bool IsProxy(const CNetAddr &addr) { | |||||
for (int i = 0; i < NET_MAX; i++) { | |||||
if (proxyInfo[i].second && (addr == (CNetAddr)proxyInfo[i].first)) | |||||
return true; | |||||
} | |||||
return false; | |||||
} | |||||
bool ConnectSocket(const CSeederService &addrDest, SOCKET &hSocketRet, | bool ConnectSocket(const CSeederService &addrDest, SOCKET &hSocketRet, | ||||
int nTimeout) { | int nTimeout) { | ||||
const proxyType &proxy = proxyInfo[addrDest.GetNetwork()]; | const proxyType &proxy = proxyInfo[addrDest.GetNetwork()]; | ||||
// no proxy needed | // no proxy needed | ||||
if (!proxy.second) | if (!proxy.second) | ||||
return ConnectSocketDirectly(addrDest, hSocketRet, nTimeout); | return ConnectSocketDirectly(addrDest, hSocketRet, nTimeout); | ||||
Show All 14 Lines | switch (proxy.second) { | ||||
default: | default: | ||||
return false; | return false; | ||||
} | } | ||||
hSocketRet = hSocket; | hSocketRet = hSocket; | ||||
return true; | return true; | ||||
} | } | ||||
bool ConnectSocketByName(CSeederService &addr, SOCKET &hSocketRet, | |||||
const char *pszDest, int portDefault, int nTimeout) { | |||||
std::string strDest; | |||||
int port = portDefault; | |||||
SplitHostPort(std::string(pszDest), port, strDest); | |||||
SOCKET hSocket = INVALID_SOCKET; | |||||
CSeederService addrResolved; | |||||
if (Lookup(strDest.c_str(), addrResolved, port, | |||||
fNameLookup && !nameproxyInfo.second)) { | |||||
if (addrResolved.IsValid()) { | |||||
addr = addrResolved; | |||||
return ConnectSocket(addr, hSocketRet, nTimeout); | |||||
} | |||||
} | |||||
addr = CSeederService("0.0.0.0:0"); | |||||
if (!nameproxyInfo.second) return false; | |||||
if (!ConnectSocketDirectly(nameproxyInfo.first, hSocket, nTimeout)) | |||||
return false; | |||||
switch (nameproxyInfo.second) { | |||||
default: | |||||
case 4: | |||||
return false; | |||||
case 5: | |||||
if (!Socks5(strDest, port, hSocket)) return false; | |||||
break; | |||||
} | |||||
hSocketRet = hSocket; | |||||
return true; | |||||
} | |||||
void CSeederService::Init() { | void CSeederService::Init() { | ||||
port = 0; | port = 0; | ||||
} | } | ||||
CSeederService::CSeederService() { | CSeederService::CSeederService() { | ||||
Init(); | Init(); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 135 Lines • Show Last 20 Lines |