Changeset View
Changeset View
Standalone View
Standalone View
src/netbase.cpp
Show First 20 Lines • Show All 330 Lines • ▼ Show 20 Lines | static bool Socks5(const std::string &strDest, int port, | ||||
ssize_t ret = send(hSocket, (const char *)vSocks5Init.data(), | ssize_t ret = send(hSocket, (const char *)vSocks5Init.data(), | ||||
vSocks5Init.size(), MSG_NOSIGNAL); | vSocks5Init.size(), MSG_NOSIGNAL); | ||||
if (ret != (ssize_t)vSocks5Init.size()) { | if (ret != (ssize_t)vSocks5Init.size()) { | ||||
return error("Error sending to proxy"); | return error("Error sending to proxy"); | ||||
} | } | ||||
uint8_t pchRet1[2]; | uint8_t pchRet1[2]; | ||||
if ((recvr = InterruptibleRecv(pchRet1, 2, SOCKS5_RECV_TIMEOUT, hSocket)) != | if ((recvr = InterruptibleRecv(pchRet1, 2, SOCKS5_RECV_TIMEOUT, hSocket)) != | ||||
IntrRecvError::OK) { | IntrRecvError::OK) { | ||||
LogPrintf("Socks5() connect to %s:%d failed: InterruptibleRecv() " | LogPrint(BCLog::NET, | ||||
"Socks5() connect to %s:%d failed: InterruptibleRecv() " | |||||
"timeout or other failure\n", | "timeout or other failure\n", | ||||
strDest, port); | strDest, port); | ||||
return false; | return false; | ||||
} | } | ||||
if (pchRet1[0] != SOCKSVersion::SOCKS5) { | if (pchRet1[0] != SOCKSVersion::SOCKS5) { | ||||
return error("Proxy failed to initialize"); | return error("Proxy failed to initialize"); | ||||
} | } | ||||
if (pchRet1[1] == SOCKS5Method::USER_PASS && auth) { | if (pchRet1[1] == SOCKS5Method::USER_PASS && auth) { | ||||
// Perform username/password authentication (as described in RFC1929) | // Perform username/password authentication (as described in RFC1929) | ||||
std::vector<uint8_t> vAuth; | std::vector<uint8_t> vAuth; | ||||
▲ Show 20 Lines • Show All 59 Lines • ▼ Show 20 Lines | if ((recvr = InterruptibleRecv(pchRet2, 4, SOCKS5_RECV_TIMEOUT, hSocket)) != | ||||
return error("Error while reading proxy response"); | return error("Error while reading proxy response"); | ||||
} | } | ||||
} | } | ||||
if (pchRet2[0] != SOCKSVersion::SOCKS5) { | if (pchRet2[0] != SOCKSVersion::SOCKS5) { | ||||
return error("Proxy failed to accept request"); | return error("Proxy failed to accept request"); | ||||
} | } | ||||
if (pchRet2[1] != SOCKS5Reply::SUCCEEDED) { | if (pchRet2[1] != SOCKS5Reply::SUCCEEDED) { | ||||
// Failures to connect to a peer that are not proxy errors | // Failures to connect to a peer that are not proxy errors | ||||
LogPrintf("Socks5() connect to %s:%d failed: %s\n", strDest, port, | LogPrint(BCLog::NET, "Socks5() connect to %s:%d failed: %s\n", strDest, | ||||
Socks5ErrorString(pchRet2[1])); | port, Socks5ErrorString(pchRet2[1])); | ||||
return false; | return false; | ||||
} | } | ||||
// Reserved field must be 0 | // Reserved field must be 0 | ||||
if (pchRet2[2] != 0x00) { | if (pchRet2[2] != 0x00) { | ||||
return error("Error: malformed proxy response"); | return error("Error: malformed proxy response"); | ||||
} | } | ||||
uint8_t pchRet3[256]; | uint8_t pchRet3[256]; | ||||
switch (pchRet2[3]) { | switch (pchRet2[3]) { | ||||
Show All 27 Lines | static bool Socks5(const std::string &strDest, int port, | ||||
LogPrint(BCLog::NET, "SOCKS5 connected %s\n", strDest); | LogPrint(BCLog::NET, "SOCKS5 connected %s\n", strDest); | ||||
return true; | return true; | ||||
} | } | ||||
SOCKET CreateSocket(const CService &addrConnect) { | SOCKET CreateSocket(const CService &addrConnect) { | ||||
struct sockaddr_storage sockaddr; | struct sockaddr_storage sockaddr; | ||||
socklen_t len = sizeof(sockaddr); | socklen_t len = sizeof(sockaddr); | ||||
if (!addrConnect.GetSockAddr((struct sockaddr *)&sockaddr, &len)) { | if (!addrConnect.GetSockAddr((struct sockaddr *)&sockaddr, &len)) { | ||||
LogPrintf("Cannot create socket for %s: unsupported network\n", | LogPrint(BCLog::NET, | ||||
"Cannot create socket for %s: unsupported network\n", | |||||
addrConnect.ToString()); | addrConnect.ToString()); | ||||
return INVALID_SOCKET; | return INVALID_SOCKET; | ||||
} | } | ||||
SOCKET hSocket = socket(((struct sockaddr *)&sockaddr)->sa_family, | SOCKET hSocket = socket(((struct sockaddr *)&sockaddr)->sa_family, | ||||
SOCK_STREAM, IPPROTO_TCP); | SOCK_STREAM, IPPROTO_TCP); | ||||
if (hSocket == INVALID_SOCKET) { | if (hSocket == INVALID_SOCKET) { | ||||
return INVALID_SOCKET; | return INVALID_SOCKET; | ||||
} | } | ||||
if (!IsSelectableSocket(hSocket)) { | if (!IsSelectableSocket(hSocket)) { | ||||
CloseSocket(hSocket); | CloseSocket(hSocket); | ||||
LogPrintf("Cannot create connection: non-selectable socket created (fd " | LogPrint(BCLog::NET, | ||||
"Cannot create connection: non-selectable socket created (fd " | |||||
">= FD_SETSIZE ?)\n"); | ">= FD_SETSIZE ?)\n"); | ||||
return INVALID_SOCKET; | return INVALID_SOCKET; | ||||
} | } | ||||
#ifdef SO_NOSIGPIPE | #ifdef SO_NOSIGPIPE | ||||
int set = 1; | int set = 1; | ||||
// Different way of disabling SIGPIPE on BSD | // Different way of disabling SIGPIPE on BSD | ||||
setsockopt(hSocket, SOL_SOCKET, SO_NOSIGPIPE, (sockopt_arg_type)&set, | setsockopt(hSocket, SOL_SOCKET, SO_NOSIGPIPE, (sockopt_arg_type)&set, | ||||
sizeof(int)); | sizeof(int)); | ||||
#endif | #endif | ||||
// Disable Nagle's algorithm | // Disable Nagle's algorithm | ||||
SetSocketNoDelay(hSocket); | SetSocketNoDelay(hSocket); | ||||
// Set to non-blocking | // Set to non-blocking | ||||
if (!SetSocketNonBlocking(hSocket, true)) { | if (!SetSocketNonBlocking(hSocket, true)) { | ||||
CloseSocket(hSocket); | CloseSocket(hSocket); | ||||
LogPrintf("ConnectSocketDirectly: Setting socket to non-blocking " | LogPrint(BCLog::NET, | ||||
"ConnectSocketDirectly: Setting socket to non-blocking " | |||||
"failed, error %s\n", | "failed, error %s\n", | ||||
NetworkErrorString(WSAGetLastError())); | NetworkErrorString(WSAGetLastError())); | ||||
} | } | ||||
return hSocket; | return hSocket; | ||||
} | } | ||||
bool ConnectSocketDirectly(const CService &addrConnect, const SOCKET &hSocket, | bool ConnectSocketDirectly(const CService &addrConnect, const SOCKET &hSocket, | ||||
int nTimeout) { | int nTimeout) { | ||||
struct sockaddr_storage sockaddr; | struct sockaddr_storage sockaddr; | ||||
socklen_t len = sizeof(sockaddr); | socklen_t len = sizeof(sockaddr); | ||||
if (hSocket == INVALID_SOCKET) { | if (hSocket == INVALID_SOCKET) { | ||||
LogPrintf("Cannot connect to %s: invalid socket\n", | LogPrint(BCLog::NET, "Cannot connect to %s: invalid socket\n", | ||||
addrConnect.ToString()); | addrConnect.ToString()); | ||||
return false; | return false; | ||||
} | } | ||||
if (!addrConnect.GetSockAddr((struct sockaddr *)&sockaddr, &len)) { | if (!addrConnect.GetSockAddr((struct sockaddr *)&sockaddr, &len)) { | ||||
LogPrintf("Cannot connect to %s: unsupported network\n", | LogPrint(BCLog::NET, "Cannot connect to %s: unsupported network\n", | ||||
addrConnect.ToString()); | addrConnect.ToString()); | ||||
return false; | return false; | ||||
} | } | ||||
if (connect(hSocket, (struct sockaddr *)&sockaddr, len) == SOCKET_ERROR) { | if (connect(hSocket, (struct sockaddr *)&sockaddr, len) == SOCKET_ERROR) { | ||||
int nErr = WSAGetLastError(); | int nErr = WSAGetLastError(); | ||||
// WSAEINVAL is here because some legacy version of winsock uses it | // WSAEINVAL is here because some legacy version of winsock uses it | ||||
if (nErr == WSAEINPROGRESS || nErr == WSAEWOULDBLOCK || | if (nErr == WSAEINPROGRESS || nErr == WSAEWOULDBLOCK || | ||||
nErr == WSAEINVAL) { | nErr == WSAEINVAL) { | ||||
struct timeval timeout = MillisToTimeval(nTimeout); | struct timeval timeout = MillisToTimeval(nTimeout); | ||||
fd_set fdset; | fd_set fdset; | ||||
FD_ZERO(&fdset); | FD_ZERO(&fdset); | ||||
FD_SET(hSocket, &fdset); | FD_SET(hSocket, &fdset); | ||||
int nRet = select(hSocket + 1, nullptr, &fdset, nullptr, &timeout); | int nRet = select(hSocket + 1, nullptr, &fdset, nullptr, &timeout); | ||||
if (nRet == 0) { | if (nRet == 0) { | ||||
LogPrint(BCLog::NET, "connection to %s timeout\n", | LogPrint(BCLog::NET, "connection to %s timeout\n", | ||||
addrConnect.ToString()); | addrConnect.ToString()); | ||||
return false; | return false; | ||||
} | } | ||||
if (nRet == SOCKET_ERROR) { | if (nRet == SOCKET_ERROR) { | ||||
LogPrintf("select() for %s failed: %s\n", | LogPrint(BCLog::NET, "select() for %s failed: %s\n", | ||||
addrConnect.ToString(), | addrConnect.ToString(), | ||||
NetworkErrorString(WSAGetLastError())); | NetworkErrorString(WSAGetLastError())); | ||||
return false; | return false; | ||||
} | } | ||||
socklen_t nRetSize = sizeof(nRet); | socklen_t nRetSize = sizeof(nRet); | ||||
if (getsockopt(hSocket, SOL_SOCKET, SO_ERROR, | if (getsockopt(hSocket, SOL_SOCKET, SO_ERROR, | ||||
(sockopt_arg_type)&nRet, | (sockopt_arg_type)&nRet, | ||||
&nRetSize) == SOCKET_ERROR) { | &nRetSize) == SOCKET_ERROR) { | ||||
LogPrintf("getsockopt() for %s failed: %s\n", | LogPrint(BCLog::NET, "getsockopt() for %s failed: %s\n", | ||||
addrConnect.ToString(), | addrConnect.ToString(), | ||||
NetworkErrorString(WSAGetLastError())); | NetworkErrorString(WSAGetLastError())); | ||||
return false; | return false; | ||||
} | } | ||||
if (nRet != 0) { | if (nRet != 0) { | ||||
LogPrintf("connect() to %s failed after select(): %s\n", | LogPrint(BCLog::NET, | ||||
"connect() to %s failed after select(): %s\n", | |||||
addrConnect.ToString(), NetworkErrorString(nRet)); | addrConnect.ToString(), NetworkErrorString(nRet)); | ||||
return false; | return false; | ||||
} | } | ||||
} | } | ||||
#ifdef WIN32 | #ifdef WIN32 | ||||
else if (WSAGetLastError() != WSAEISCONN) | else if (WSAGetLastError() != WSAEISCONN) | ||||
#else | #else | ||||
else | else | ||||
#endif | #endif | ||||
{ | { | ||||
LogPrintf("connect() to %s failed: %s\n", addrConnect.ToString(), | LogPrint(BCLog::NET, "connect() to %s failed: %s\n", | ||||
addrConnect.ToString(), | |||||
NetworkErrorString(WSAGetLastError())); | NetworkErrorString(WSAGetLastError())); | ||||
return false; | return false; | ||||
} | } | ||||
} | } | ||||
return true; | return true; | ||||
} | } | ||||
bool SetProxy(enum Network net, const proxyType &addrProxy) { | bool SetProxy(enum Network net, const proxyType &addrProxy) { | ||||
assert(net >= 0 && net < NET_MAX); | assert(net >= 0 && net < NET_MAX); | ||||
▲ Show 20 Lines • Show All 177 Lines • Show Last 20 Lines |