typedef SSIZE_T ssize_t;
#endif
-#include <boost/algorithm/string/case_conv.hpp> // for to_lower()
-#include <boost/algorithm/string/predicate.hpp> // for startswith() and endswith()
-
using namespace std;
// Settings
static proxyType proxyInfo[NET_MAX];
-static proxyType nameproxyInfo;
+static CService nameProxy;
static CCriticalSection cs_proxyInfos;
int nConnectTimeout = 5000;
bool fNameLookup = false;
static const unsigned char pchIPv4[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff };
enum Network ParseNetwork(std::string net) {
- boost::to_lower(net);
+ transform(net.begin(), net.end(), net.begin(), ::tolower);
if (net == "ipv4") return NET_IPV4;
if (net == "ipv6") return NET_IPV6;
if (net == "tor" || net == "onion") return NET_TOR;
}
void SplitHostPort(std::string in, uint16_t &portOut, std::string &hostOut) {
- size_t colon = in.find_last_of(':');
+ auto colon = in.find_last_of(':');
// if a : is found, and it either follows a [...], or no other : is in the string, treat it as port separator
bool fHaveColon = colon != in.npos;
bool fBracketed = fHaveColon && (in[0]=='[' && in[colon-1]==']'); // if there is a colon, and in[0]=='[', colon is not 0, so in[colon-1] is safe
return (vIP.size() > 0);
}
-bool LookupHost(const char *pszName, std::vector<CNetAddr>& vIP, unsigned int nMaxSolutions, bool fAllowLookup)
+bool LookupHost(const string& strName, std::vector<CNetAddr>& vIP, unsigned int nMaxSolutions, bool fAllowLookup)
{
- std::string strHost(pszName);
+ std::string strHost(strName);
if (strHost.empty())
return false;
- if (boost::algorithm::starts_with(strHost, "[") && boost::algorithm::ends_with(strHost, "]"))
+ if ((strHost.front() == '[') && (strHost.back() == ']'))
{
strHost = strHost.substr(1, strHost.size() - 2);
}
return LookupIntern(strHost.c_str(), vIP, nMaxSolutions, fAllowLookup);
}
-bool LookupHostNumeric(const char *pszName, std::vector<CNetAddr>& vIP, unsigned int nMaxSolutions)
+bool LookupHost(const char *pszName, std::vector<CNetAddr>& vIP, unsigned int nMaxSolutions, bool fAllowLookup)
{
- return LookupHost(pszName, vIP, nMaxSolutions, false);
+ std::string strHost(pszName);
+ if (strHost.empty())
+ return false;
+ if ((strHost.front() == '[') && (strHost.back() == ']'))
+ {
+ strHost = strHost.substr(1, strHost.size() - 2);
+ }
+
+ return LookupIntern(strHost.c_str(), vIP, nMaxSolutions, fAllowLookup);
}
bool Lookup(const char *pszName, std::vector<CService>& vAddr, uint16_t portDefault, bool fAllowLookup, unsigned int nMaxSolutions)
{
if (pszName[0] == 0)
return false;
- uint16_t port = portDefault;
+ auto port = portDefault;
std::string hostname = "";
SplitHostPort(std::string(pszName), port, hostname);
return Lookup(pszName, addr, portDefault, false);
}
-bool static Socks4(const CService &addrDest, SOCKET& hSocket)
-{
- printf("SOCKS4 connecting %s\n", addrDest.ToString().c_str());
- if (!addrDest.IsIPv4())
- {
- CloseSocket(hSocket);
- return error("Proxy destination is not IPv4");
- }
- char pszSocks4IP[] = "\4\1\0\0\0\0\0\0user";
- struct sockaddr_in addr;
- socklen_t len = sizeof(addr);
- if (!addrDest.GetSockAddr((struct sockaddr*)&addr, &len) || addr.sin_family != AF_INET)
- {
- CloseSocket(hSocket);
- return error("Cannot get proxy destination address");
- }
- memcpy(pszSocks4IP + 2, &addr.sin_port, 2);
- memcpy(pszSocks4IP + 4, &addr.sin_addr, 4);
- char* pszSocks4 = pszSocks4IP;
- int nSize = sizeof(pszSocks4IP);
-
- int ret = send(hSocket, pszSocks4, nSize, MSG_NOSIGNAL);
- if (ret != nSize)
- {
- CloseSocket(hSocket);
- return error("Error sending to proxy");
- }
- char pchRet[8];
- if (recv(hSocket, pchRet, 8, 0) != 8)
- {
- CloseSocket(hSocket);
- return error("Error reading proxy response");
- }
- if (pchRet[1] != 0x5a)
- {
- CloseSocket(hSocket);
- if (pchRet[1] != 0x5b)
- printf("ERROR: Proxy returned error %d\n", pchRet[1]);
- return false;
- }
- printf("SOCKS4 connected %s\n", addrDest.ToString().c_str());
- return true;
-}
-
bool static Socks5(string strDest, uint16_t port, SOCKET& hSocket)
{
printf("SOCKS5 connecting %s\n", strDest.c_str());
CloseSocket(hSocket);
return error("Hostname too long");
}
- char pszSocks5Init[] = "\5\1\0";
- ssize_t nSize = sizeof(pszSocks5Init) - 1;
-
- ssize_t ret = send(hSocket, pszSocks5Init, nSize, MSG_NOSIGNAL);
- if (ret != nSize)
+ const char pszSocks5Init[] = "\5\1\0";
+ ssize_t ret = send(hSocket, pszSocks5Init, 3, MSG_NOSIGNAL);
+ if (ret != 3)
{
CloseSocket(hSocket);
return error("Error sending to proxy");
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);
+ ret = send(hSocket, strSocks5.data(), strSocks5.size(), MSG_NOSIGNAL);
if (ret != (ssize_t)strSocks5.size())
{
CloseSocket(hSocket);
if (connect(hSocket, (struct sockaddr*)&sockaddr, len) == SOCKET_ERROR)
{
+ int nErr = WSAGetLastError();
// WSAEINVAL is here because some legacy version of winsock uses it
- if (WSAGetLastError() == WSAEINPROGRESS || WSAGetLastError() == WSAEWOULDBLOCK || WSAGetLastError() == WSAEINVAL)
+ if (nErr == WSAEINPROGRESS || nErr == WSAEWOULDBLOCK || nErr == WSAEINVAL)
{
struct timeval timeout;
timeout.tv_sec = nTimeout / 1000;
return true;
}
-bool SetProxy(enum Network net, CService addrProxy, int nSocksVersion) {
+bool SetProxy(enum Network net, CService addrProxy) {
assert(net >= 0 && net < NET_MAX);
- if (nSocksVersion != 0 && nSocksVersion != 4 && nSocksVersion != 5)
- return false;
- if (nSocksVersion != 0 && !addrProxy.IsValid())
+ if (!addrProxy.IsValid())
return false;
LOCK(cs_proxyInfos);
- proxyInfo[net] = std::make_pair(addrProxy, nSocksVersion);
+ proxyInfo[net] = addrProxy;
return true;
}
bool GetProxy(enum Network net, proxyType &proxyInfoOut) {
assert(net >= 0 && net < NET_MAX);
LOCK(cs_proxyInfos);
- if (!proxyInfo[net].second)
+ if (!proxyInfo[net].IsValid())
return false;
proxyInfoOut = proxyInfo[net];
return true;
}
-bool SetNameProxy(CService addrProxy, int nSocksVersion) {
- if (nSocksVersion != 0 && nSocksVersion != 5)
- return false;
- if (nSocksVersion != 0 && !addrProxy.IsValid())
+bool SetNameProxy(CService addrProxy) {
+ if (!addrProxy.IsValid())
return false;
LOCK(cs_proxyInfos);
- nameproxyInfo = std::make_pair(addrProxy, nSocksVersion);
+ nameProxy = addrProxy;
return true;
}
-bool GetNameProxy(proxyType &nameproxyInfoOut) {
+bool GetNameProxy(CService &nameProxyOut) {
LOCK(cs_proxyInfos);
- if (!nameproxyInfo.second)
+ if (!nameProxy.IsValid())
return false;
- nameproxyInfoOut = nameproxyInfo;
+ nameProxyOut = nameProxy;
return true;
}
bool HaveNameProxy() {
LOCK(cs_proxyInfos);
- return nameproxyInfo.second != 0;
+ return nameProxy.IsValid();
}
bool IsProxy(const CNetAddr &addr) {
LOCK(cs_proxyInfos);
for (int i = 0; i < NET_MAX; i++) {
- if (proxyInfo[i].second && (addr == (CNetAddr)proxyInfo[i].first))
+ if (addr == (CNetAddr)proxyInfo[i])
return true;
}
return false;
SOCKET hSocket = INVALID_SOCKET;
// first connect to proxy server
- if (!ConnectSocketDirectly(proxy.first, hSocket, nTimeout))
+ if (!ConnectSocketDirectly(proxy, hSocket, nTimeout))
return false;
// do socks negotiation
- switch (proxy.second) {
- case 4:
- if (!Socks4(addrDest, hSocket))
- return false;
- break;
- case 5:
- if (!Socks5(addrDest.ToStringIP(), addrDest.GetPort(), hSocket))
- return false;
- break;
- default:
- CloseSocket(hSocket);
+ if (!Socks5(addrDest.ToStringIP(), addrDest.GetPort(), hSocket))
return false;
- }
hSocketRet = hSocket;
return true;
bool ConnectSocketByName(CService &addr, SOCKET& hSocketRet, const char *pszDest, uint16_t portDefault, int nTimeout)
{
string strDest;
- uint16_t port = portDefault;
+ auto port = portDefault;
SplitHostPort(string(pszDest), port, strDest);
SOCKET hSocket = INVALID_SOCKET;
- proxyType nameproxy;
- GetNameProxy(nameproxy);
+ CService nameProxy;
+ GetNameProxy(nameProxy);
- CService addrResolved(CNetAddr(strDest, fNameLookup && !nameproxy.second), port);
+ CService addrResolved(CNetAddr(strDest, fNameLookup && !HaveNameProxy()), port);
if (addrResolved.IsValid()) {
addr = addrResolved;
return ConnectSocket(addr, hSocketRet, nTimeout);
}
addr = CService("0.0.0.0:0");
- if (!nameproxy.second)
+ if (!HaveNameProxy())
return false;
- if (!ConnectSocketDirectly(nameproxy.first, hSocket, nTimeout))
+ // first connect to name proxy server
+ if (!ConnectSocketDirectly(nameProxy, hSocket, nTimeout))
+ return false;
+ // do socks negotiation
+ if (!Socks5(strDest, port, hSocket))
return false;
-
- switch(nameproxy.second) {
- default:
- case 4:
- CloseSocket(hSocket);
- return false;
- case 5:
- if (!Socks5(strDest, port, hSocket))
- return false;
- break;
- }
hSocketRet = hSocket;
return true;
{
Init();
std::vector<CNetAddr> vIP;
- if (LookupHost(strIp.c_str(), vIP, 1, fAllowLookup))
+ if (LookupHost(strIp, vIP, 1, fAllowLookup))
*this = vIP[0];
}
uint64_t CNetAddr::GetHash() const
{
- uint256 hash = Hash(&ip[0], &ip[16]);
+ auto hash = Hash(&ip[0], &ip[16]);
uint64_t nRet;
memcpy(&nRet, &hash, sizeof(nRet));
return nRet;
}
-void CNetAddr::print() const
-{
- printf("CNetAddr(%s)\n", ToString().c_str());
-}
-
// private extensions to enum Network, only returned by GetExtNetwork,
// and only used in GetReachabilityFrom
static const int NET_UNKNOWN = NET_MAX + 0;
*this = ip;
}
-unsigned short CService::GetPort() const
+uint16_t CService::GetPort() const
{
return port;
}
return ToStringIPPort();
}
-void CService::print() const
-{
- printf("CService(%s)\n", ToString().c_str());
-}
-
-void CService::SetPort(unsigned short portIn)
+void CService::SetupPort(uint16_t portIn)
{
port = portIn;
}
#endif
hSocket = INVALID_SOCKET;
return ret != SOCKET_ERROR;
-}
\ No newline at end of file
+}