mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-06-19 13:22:02 +02:00
net: use Sock in InterruptibleRecv() and Socks5()
Use the `Sock` class instead of `SOCKET` for `InterruptibleRecv()` and `Socks5()`. This way the `Socks5()` function can be tested by giving it a mocked instance of a socket. Co-authored-by: practicalswift <practicalswift@users.noreply.github.com>
This commit is contained in:
parent
ba9d73268f
commit
04ae846904
@ -440,7 +440,7 @@ CNode* CConnman::ConnectNode(CAddress addrConnect, const char *pszDest, bool fCo
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
connected = ConnectThroughProxy(proxy, addrConnect.ToStringIP(), addrConnect.GetPort(),
|
connected = ConnectThroughProxy(proxy, addrConnect.ToStringIP(), addrConnect.GetPort(),
|
||||||
sock->Get(), nConnectTimeout, proxyConnectionFailed);
|
*sock, nConnectTimeout, proxyConnectionFailed);
|
||||||
} else {
|
} else {
|
||||||
// no proxy needed (none set for target network)
|
// no proxy needed (none set for target network)
|
||||||
sock = CreateSock(addrConnect);
|
sock = CreateSock(addrConnect);
|
||||||
@ -464,7 +464,7 @@ CNode* CConnman::ConnectNode(CAddress addrConnect, const char *pszDest, bool fCo
|
|||||||
int port = default_port;
|
int port = default_port;
|
||||||
SplitHostPort(std::string(pszDest), port, host);
|
SplitHostPort(std::string(pszDest), port, host);
|
||||||
bool proxyConnectionFailed;
|
bool proxyConnectionFailed;
|
||||||
connected = ConnectThroughProxy(proxy, host, port, sock->Get(), nConnectTimeout,
|
connected = ConnectThroughProxy(proxy, host, port, *sock, nConnectTimeout,
|
||||||
proxyConnectionFailed);
|
proxyConnectionFailed);
|
||||||
}
|
}
|
||||||
if (!connected) {
|
if (!connected) {
|
||||||
|
@ -343,7 +343,7 @@ enum class IntrRecvError {
|
|||||||
* Sockets can be made non-blocking with SetSocketNonBlocking(const
|
* Sockets can be made non-blocking with SetSocketNonBlocking(const
|
||||||
* SOCKET&, bool).
|
* SOCKET&, bool).
|
||||||
*/
|
*/
|
||||||
static IntrRecvError InterruptibleRecv(uint8_t* data, size_t len, int timeout, const SOCKET& hSocket)
|
static IntrRecvError InterruptibleRecv(uint8_t* data, size_t len, int timeout, const Sock& hSocket)
|
||||||
{
|
{
|
||||||
int64_t curTime = GetTimeMillis();
|
int64_t curTime = GetTimeMillis();
|
||||||
int64_t endTime = curTime + timeout;
|
int64_t endTime = curTime + timeout;
|
||||||
@ -351,7 +351,7 @@ static IntrRecvError InterruptibleRecv(uint8_t* data, size_t len, int timeout, c
|
|||||||
// (in millis) to break off in case of an interruption.
|
// (in millis) to break off in case of an interruption.
|
||||||
const int64_t maxWait = 1000;
|
const int64_t maxWait = 1000;
|
||||||
while (len > 0 && curTime < endTime) {
|
while (len > 0 && curTime < endTime) {
|
||||||
ssize_t ret = recv(hSocket, (char*)data, len, 0); // Optimistically try the recv first
|
ssize_t ret = hSocket.Recv(data, len, 0); // Optimistically try the recv first
|
||||||
if (ret > 0) {
|
if (ret > 0) {
|
||||||
len -= ret;
|
len -= ret;
|
||||||
data += ret;
|
data += ret;
|
||||||
@ -360,25 +360,10 @@ static IntrRecvError InterruptibleRecv(uint8_t* data, size_t len, int timeout, c
|
|||||||
} else { // Other error or blocking
|
} else { // Other error or blocking
|
||||||
int nErr = WSAGetLastError();
|
int nErr = WSAGetLastError();
|
||||||
if (nErr == WSAEINPROGRESS || nErr == WSAEWOULDBLOCK || nErr == WSAEINVAL) {
|
if (nErr == WSAEINPROGRESS || nErr == WSAEWOULDBLOCK || nErr == WSAEINVAL) {
|
||||||
if (!IsSelectableSocket(hSocket)) {
|
|
||||||
return IntrRecvError::NetworkError;
|
|
||||||
}
|
|
||||||
// Only wait at most maxWait milliseconds at a time, unless
|
// Only wait at most maxWait milliseconds at a time, unless
|
||||||
// we're approaching the end of the specified total timeout
|
// we're approaching the end of the specified total timeout
|
||||||
int timeout_ms = std::min(endTime - curTime, maxWait);
|
int timeout_ms = std::min(endTime - curTime, maxWait);
|
||||||
#ifdef USE_POLL
|
if (!hSocket.Wait(std::chrono::milliseconds{timeout_ms}, Sock::RECV)) {
|
||||||
struct pollfd pollfd = {};
|
|
||||||
pollfd.fd = hSocket;
|
|
||||||
pollfd.events = POLLIN;
|
|
||||||
int nRet = poll(&pollfd, 1, timeout_ms);
|
|
||||||
#else
|
|
||||||
struct timeval tval = MillisToTimeval(timeout_ms);
|
|
||||||
fd_set fdset;
|
|
||||||
FD_ZERO(&fdset);
|
|
||||||
FD_SET(hSocket, &fdset);
|
|
||||||
int nRet = select(hSocket + 1, &fdset, nullptr, nullptr, &tval);
|
|
||||||
#endif
|
|
||||||
if (nRet == SOCKET_ERROR) {
|
|
||||||
return IntrRecvError::NetworkError;
|
return IntrRecvError::NetworkError;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -442,7 +427,7 @@ static std::string Socks5ErrorString(uint8_t err)
|
|||||||
* @see <a href="https://www.ietf.org/rfc/rfc1928.txt">RFC1928: SOCKS Protocol
|
* @see <a href="https://www.ietf.org/rfc/rfc1928.txt">RFC1928: SOCKS Protocol
|
||||||
* Version 5</a>
|
* Version 5</a>
|
||||||
*/
|
*/
|
||||||
static bool Socks5(const std::string& strDest, int port, const ProxyCredentials *auth, const SOCKET& hSocket)
|
static bool Socks5(const std::string& strDest, int port, const ProxyCredentials* auth, const Sock& hSocket)
|
||||||
{
|
{
|
||||||
IntrRecvError recvr;
|
IntrRecvError recvr;
|
||||||
LogPrint(BCLog::NET, "SOCKS5 connecting %s\n", strDest);
|
LogPrint(BCLog::NET, "SOCKS5 connecting %s\n", strDest);
|
||||||
@ -460,7 +445,7 @@ static bool Socks5(const std::string& strDest, int port, const ProxyCredentials
|
|||||||
vSocks5Init.push_back(0x01); // 1 method identifier follows...
|
vSocks5Init.push_back(0x01); // 1 method identifier follows...
|
||||||
vSocks5Init.push_back(SOCKS5Method::NOAUTH);
|
vSocks5Init.push_back(SOCKS5Method::NOAUTH);
|
||||||
}
|
}
|
||||||
ssize_t ret = send(hSocket, (const char*)vSocks5Init.data(), vSocks5Init.size(), MSG_NOSIGNAL);
|
ssize_t ret = hSocket.Send(vSocks5Init.data(), 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");
|
||||||
}
|
}
|
||||||
@ -482,7 +467,7 @@ static bool Socks5(const std::string& strDest, int port, const ProxyCredentials
|
|||||||
vAuth.insert(vAuth.end(), auth->username.begin(), auth->username.end());
|
vAuth.insert(vAuth.end(), auth->username.begin(), auth->username.end());
|
||||||
vAuth.push_back(auth->password.size());
|
vAuth.push_back(auth->password.size());
|
||||||
vAuth.insert(vAuth.end(), auth->password.begin(), auth->password.end());
|
vAuth.insert(vAuth.end(), auth->password.begin(), auth->password.end());
|
||||||
ret = send(hSocket, (const char*)vAuth.data(), vAuth.size(), MSG_NOSIGNAL);
|
ret = hSocket.Send(vAuth.data(), vAuth.size(), MSG_NOSIGNAL);
|
||||||
if (ret != (ssize_t)vAuth.size()) {
|
if (ret != (ssize_t)vAuth.size()) {
|
||||||
return error("Error sending authentication to proxy");
|
return error("Error sending authentication to proxy");
|
||||||
}
|
}
|
||||||
@ -508,7 +493,7 @@ static bool Socks5(const std::string& strDest, int port, const ProxyCredentials
|
|||||||
vSocks5.insert(vSocks5.end(), strDest.begin(), strDest.end());
|
vSocks5.insert(vSocks5.end(), strDest.begin(), strDest.end());
|
||||||
vSocks5.push_back((port >> 8) & 0xFF);
|
vSocks5.push_back((port >> 8) & 0xFF);
|
||||||
vSocks5.push_back((port >> 0) & 0xFF);
|
vSocks5.push_back((port >> 0) & 0xFF);
|
||||||
ret = send(hSocket, (const char*)vSocks5.data(), vSocks5.size(), MSG_NOSIGNAL);
|
ret = hSocket.Send(vSocks5.data(), vSocks5.size(), MSG_NOSIGNAL);
|
||||||
if (ret != (ssize_t)vSocks5.size()) {
|
if (ret != (ssize_t)vSocks5.size()) {
|
||||||
return error("Error sending to proxy");
|
return error("Error sending to proxy");
|
||||||
}
|
}
|
||||||
@ -787,10 +772,10 @@ bool IsProxy(const CNetAddr &addr) {
|
|||||||
*
|
*
|
||||||
* @returns Whether or not the operation succeeded.
|
* @returns Whether or not the operation succeeded.
|
||||||
*/
|
*/
|
||||||
bool ConnectThroughProxy(const proxyType &proxy, const std::string& strDest, int port, const SOCKET& hSocket, int nTimeout, bool& outProxyConnectionFailed)
|
bool ConnectThroughProxy(const proxyType& proxy, const std::string& strDest, int port, const Sock& hSocket, int nTimeout, bool& outProxyConnectionFailed)
|
||||||
{
|
{
|
||||||
// first connect to proxy server
|
// first connect to proxy server
|
||||||
if (!ConnectSocketDirectly(proxy.proxy, hSocket, nTimeout, true)) {
|
if (!ConnectSocketDirectly(proxy.proxy, hSocket.Get(), nTimeout, true)) {
|
||||||
outProxyConnectionFailed = true;
|
outProxyConnectionFailed = true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -68,7 +68,7 @@ std::unique_ptr<Sock> CreateSockTCP(const CService& address_family);
|
|||||||
extern std::function<std::unique_ptr<Sock>(const CService&)> CreateSock;
|
extern std::function<std::unique_ptr<Sock>(const CService&)> CreateSock;
|
||||||
|
|
||||||
bool ConnectSocketDirectly(const CService &addrConnect, const SOCKET& hSocketRet, int nTimeout, bool manual_connection);
|
bool ConnectSocketDirectly(const CService &addrConnect, const SOCKET& hSocketRet, int nTimeout, bool manual_connection);
|
||||||
bool ConnectThroughProxy(const proxyType &proxy, const std::string& strDest, int port, const SOCKET& hSocketRet, int nTimeout, bool& outProxyConnectionFailed);
|
bool ConnectThroughProxy(const proxyType& proxy, const std::string& strDest, int port, const Sock& hSocketRet, int nTimeout, bool& outProxyConnectionFailed);
|
||||||
/** Disable or enable blocking-mode for a socket */
|
/** Disable or enable blocking-mode for a socket */
|
||||||
bool SetSocketNonBlocking(const SOCKET& hSocket, bool fNonBlocking);
|
bool SetSocketNonBlocking(const SOCKET& hSocket, bool fNonBlocking);
|
||||||
/** Set the TCP_NODELAY flag on a socket */
|
/** Set the TCP_NODELAY flag on a socket */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user