aboutsummaryrefslogtreecommitdiff
path: root/src/netbase.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/netbase.cpp')
-rw-r--r--src/netbase.cpp112
1 files changed, 47 insertions, 65 deletions
diff --git a/src/netbase.cpp b/src/netbase.cpp
index b66c366641..9e7307204a 100644
--- a/src/netbase.cpp
+++ b/src/netbase.cpp
@@ -5,20 +5,21 @@
#include "netbase.h"
#include "util.h"
+#include "sync.h"
#ifndef WIN32
#include <sys/fcntl.h>
#endif
-#include "strlcpy.h"
#include <boost/algorithm/string/case_conv.hpp> // for to_lower()
+#include <boost/algorithm/string/predicate.hpp> // for startswith() and endswith()
using namespace std;
// Settings
-typedef std::pair<CService, int> proxyType;
static proxyType proxyInfo[NET_MAX];
static proxyType nameproxyInfo;
+static CCriticalSection cs_proxyInfos;
int nConnectTimeout = 5000;
bool fNameLookup = false;
@@ -29,7 +30,6 @@ enum Network ParseNetwork(std::string net) {
if (net == "ipv4") return NET_IPV4;
if (net == "ipv6") return NET_IPV6;
if (net == "tor") return NET_TOR;
- if (net == "i2p") return NET_I2P;
return NET_UNROUTABLE;
}
@@ -118,18 +118,16 @@ bool static LookupIntern(const char *pszName, std::vector<CNetAddr>& vIP, unsign
bool LookupHost(const char *pszName, std::vector<CNetAddr>& vIP, unsigned int nMaxSolutions, bool fAllowLookup)
{
- if (pszName[0] == 0)
+ std::string str(pszName);
+ std::string strHost = str;
+ if (str.empty())
return false;
- char psz[256];
- char *pszHost = psz;
- strlcpy(psz, pszName, sizeof(psz));
- if (psz[0] == '[' && psz[strlen(psz)-1] == ']')
+ if (boost::algorithm::starts_with(str, "[") && boost::algorithm::ends_with(str, "]"))
{
- pszHost = psz+1;
- psz[strlen(psz)-1] = 0;
+ strHost = str.substr(1, str.size() - 2);
}
- return LookupIntern(pszHost, vIP, nMaxSolutions, fAllowLookup);
+ return LookupIntern(strHost.c_str(), vIP, nMaxSolutions, fAllowLookup);
}
bool LookupHostNumeric(const char *pszName, std::vector<CNetAddr>& vIP, unsigned int nMaxSolutions)
@@ -246,7 +244,7 @@ bool static Socks5(string strDest, int port, SOCKET& hSocket)
string strSocks5("\5\1");
strSocks5 += '\000'; strSocks5 += '\003';
strSocks5 += static_cast<char>(std::min((int)strDest.size(), 255));
- strSocks5 += strDest;
+ strSocks5 += strDest;
strSocks5 += static_cast<char>((port >> 8) & 0xFF);
strSocks5 += static_cast<char>((port >> 0) & 0xFF);
ret = send(hSocket, strSocks5.c_str(), strSocks5.size(), MSG_NOSIGNAL);
@@ -432,15 +430,17 @@ bool SetProxy(enum Network net, CService addrProxy, int nSocksVersion) {
return false;
if (nSocksVersion != 0 && !addrProxy.IsValid())
return false;
+ LOCK(cs_proxyInfos);
proxyInfo[net] = std::make_pair(addrProxy, nSocksVersion);
return true;
}
-bool GetProxy(enum Network net, CService &addrProxy) {
+bool GetProxy(enum Network net, proxyType &proxyInfoOut) {
assert(net >= 0 && net < NET_MAX);
+ LOCK(cs_proxyInfos);
if (!proxyInfo[net].second)
return false;
- addrProxy = proxyInfo[net].first;
+ proxyInfoOut = proxyInfo[net];
return true;
}
@@ -449,16 +449,27 @@ bool SetNameProxy(CService addrProxy, int nSocksVersion) {
return false;
if (nSocksVersion != 0 && !addrProxy.IsValid())
return false;
+ LOCK(cs_proxyInfos);
nameproxyInfo = std::make_pair(addrProxy, nSocksVersion);
return true;
}
-bool GetNameProxy() {
+bool GetNameProxy(proxyType &nameproxyInfoOut) {
+ LOCK(cs_proxyInfos);
+ if (!nameproxyInfo.second)
+ return false;
+ nameproxyInfoOut = nameproxyInfo;
+ return true;
+}
+
+bool HaveNameProxy() {
+ LOCK(cs_proxyInfos);
return nameproxyInfo.second != 0;
}
bool IsProxy(const CNetAddr &addr) {
- for (int i=0; i<NET_MAX; i++) {
+ LOCK(cs_proxyInfos);
+ for (int i = 0; i < NET_MAX; i++) {
if (proxyInfo[i].second && (addr == (CNetAddr)proxyInfo[i].first))
return true;
}
@@ -467,10 +478,10 @@ bool IsProxy(const CNetAddr &addr) {
bool ConnectSocket(const CService &addrDest, SOCKET& hSocketRet, int nTimeout)
{
- const proxyType &proxy = proxyInfo[addrDest.GetNetwork()];
+ proxyType proxy;
// no proxy needed
- if (!proxy.second)
+ if (!GetProxy(addrDest.GetNetwork(), proxy))
return ConnectSocketDirectly(addrDest, hSocketRet, nTimeout);
SOCKET hSocket = INVALID_SOCKET;
@@ -478,7 +489,7 @@ bool ConnectSocket(const CService &addrDest, SOCKET& hSocketRet, int nTimeout)
// first connect to proxy server
if (!ConnectSocketDirectly(proxy.first, hSocket, nTimeout))
return false;
-
+
// do socks negotiation
switch (proxy.second) {
case 4:
@@ -504,19 +515,22 @@ bool ConnectSocketByName(CService &addr, SOCKET& hSocketRet, const char *pszDest
SplitHostPort(string(pszDest), port, strDest);
SOCKET hSocket = INVALID_SOCKET;
- CService addrResolved(CNetAddr(strDest, fNameLookup && !nameproxyInfo.second), port);
+
+ proxyType nameproxy;
+ GetNameProxy(nameproxy);
+
+ CService addrResolved(CNetAddr(strDest, fNameLookup && !nameproxy.second), port);
if (addrResolved.IsValid()) {
addr = addrResolved;
return ConnectSocket(addr, hSocketRet, nTimeout);
}
addr = CService("0.0.0.0:0");
- if (!nameproxyInfo.second)
+ if (!nameproxy.second)
return false;
- if (!ConnectSocketDirectly(nameproxyInfo.first, hSocket, nTimeout))
+ if (!ConnectSocketDirectly(nameproxy.first, hSocket, nTimeout))
return false;
- switch(nameproxyInfo.second)
- {
+ switch(nameproxy.second) {
default:
case 4: return false;
case 5:
@@ -531,7 +545,7 @@ bool ConnectSocketByName(CService &addr, SOCKET& hSocketRet, const char *pszDest
void CNetAddr::Init()
{
- memset(ip, 0, 16);
+ memset(ip, 0, sizeof(ip));
}
void CNetAddr::SetIP(const CNetAddr& ipIn)
@@ -540,7 +554,6 @@ void CNetAddr::SetIP(const CNetAddr& ipIn)
}
static const unsigned char pchOnionCat[] = {0xFD,0x87,0xD8,0x7E,0xEB,0x43};
-static const unsigned char pchGarliCat[] = {0xFD,0x60,0xDB,0x4D,0xDD,0xB5};
bool CNetAddr::SetSpecial(const std::string &strName)
{
@@ -553,15 +566,6 @@ bool CNetAddr::SetSpecial(const std::string &strName)
ip[i + sizeof(pchOnionCat)] = vchAddr[i];
return true;
}
- if (strName.size()>11 && strName.substr(strName.size() - 11, 11) == ".oc.b32.i2p") {
- std::vector<unsigned char> vchAddr = DecodeBase32(strName.substr(0, strName.size() - 11).c_str());
- if (vchAddr.size() != 16-sizeof(pchGarliCat))
- return false;
- memcpy(ip, pchOnionCat, sizeof(pchGarliCat));
- for (unsigned int i=0; i<16-sizeof(pchGarliCat); i++)
- ip[i + sizeof(pchGarliCat)] = vchAddr[i];
- return true;
- }
return false;
}
@@ -599,7 +603,7 @@ CNetAddr::CNetAddr(const std::string &strIp, bool fAllowLookup)
*this = vIP[0];
}
-int CNetAddr::GetByte(int n) const
+unsigned int CNetAddr::GetByte(int n) const
{
return ip[15-n];
}
@@ -611,14 +615,14 @@ bool CNetAddr::IsIPv4() const
bool CNetAddr::IsIPv6() const
{
- return (!IsIPv4() && !IsTor() && !IsI2P());
+ return (!IsIPv4() && !IsTor());
}
bool CNetAddr::IsRFC1918() const
{
return IsIPv4() && (
- GetByte(3) == 10 ||
- (GetByte(3) == 192 && GetByte(2) == 168) ||
+ GetByte(3) == 10 ||
+ (GetByte(3) == 192 && GetByte(2) == 168) ||
(GetByte(3) == 172 && (GetByte(2) >= 16 && GetByte(2) <= 31)));
}
@@ -675,11 +679,6 @@ bool CNetAddr::IsTor() const
return (memcmp(ip, pchOnionCat, sizeof(pchOnionCat)) == 0);
}
-bool CNetAddr::IsI2P() const
-{
- return (memcmp(ip, pchGarliCat, sizeof(pchGarliCat)) == 0);
-}
-
bool CNetAddr::IsLocal() const
{
// IPv4 loopback
@@ -738,7 +737,7 @@ bool CNetAddr::IsValid() const
bool CNetAddr::IsRoutable() const
{
- return IsValid() && !(IsRFC1918() || IsRFC3927() || IsRFC4862() || (IsRFC4193() && !IsTor() && !IsI2P()) || IsRFC4843() || IsLocal());
+ return IsValid() && !(IsRFC1918() || IsRFC3927() || IsRFC4862() || (IsRFC4193() && !IsTor()) || IsRFC4843() || IsLocal());
}
enum Network CNetAddr::GetNetwork() const
@@ -752,9 +751,6 @@ enum Network CNetAddr::GetNetwork() const
if (IsTor())
return NET_TOR;
- if (IsI2P())
- return NET_I2P;
-
return NET_IPV6;
}
@@ -762,8 +758,6 @@ std::string CNetAddr::ToStringIP() const
{
if (IsTor())
return EncodeBase32(&ip[6], 10) + ".onion";
- if (IsI2P())
- return EncodeBase32(&ip[6], 10) + ".oc.b32.i2p";
CService serv(*this, 0);
#ifdef USE_IPV6
struct sockaddr_storage sockaddr;
@@ -871,12 +865,6 @@ std::vector<unsigned char> CNetAddr::GetGroup() const
nStartByte = 6;
nBits = 4;
}
- else if (IsI2P())
- {
- nClass = NET_I2P;
- nStartByte = 6;
- nBits = 4;
- }
// for he.net, use /36 groups
else if (GetByte(15) == 0x20 && GetByte(14) == 0x11 && GetByte(13) == 0x04 && GetByte(12) == 0x70)
nBits = 36;
@@ -962,11 +950,6 @@ int CNetAddr::GetReachabilityFrom(const CNetAddr *paddrPartner) const
case NET_IPV4: return REACH_IPV4; // Tor users can connect to IPv4 as well
case NET_TOR: return REACH_PRIVATE;
}
- case NET_I2P:
- switch(ourNet) {
- default: return REACH_DEFAULT;
- case NET_I2P: return REACH_PRIVATE;
- }
case NET_TEREDO:
switch(ourNet) {
default: return REACH_DEFAULT;
@@ -982,8 +965,7 @@ int CNetAddr::GetReachabilityFrom(const CNetAddr *paddrPartner) const
case NET_TEREDO: return REACH_TEREDO;
case NET_IPV6: return REACH_IPV6_WEAK;
case NET_IPV4: return REACH_IPV4;
- case NET_I2P: return REACH_PRIVATE; // assume connections from unroutable addresses are
- case NET_TOR: return REACH_PRIVATE; // either from Tor/I2P, or don't care about our address
+ case NET_TOR: return REACH_PRIVATE; // either from Tor, or don't care about our address
}
}
}
@@ -1135,12 +1117,12 @@ std::vector<unsigned char> CService::GetKey() const
std::string CService::ToStringPort() const
{
- return strprintf("%i", port);
+ return strprintf("%u", port);
}
std::string CService::ToStringIPPort() const
{
- if (IsIPv4() || IsTor() || IsI2P()) {
+ if (IsIPv4() || IsTor()) {
return ToStringIP() + ":" + ToStringPort();
} else {
return "[" + ToStringIP() + "]:" + ToStringPort();