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 ConnectSocketDirectly(const CService &addrConnect, SOCKET& hSocketRet, int nTimeout) { hSocketRet = INVALID_SOCKET; #ifdef USE_IPV6 struct sockaddr_storage sockaddr; #else struct sockaddr sockaddr; #endif socklen_t len = sizeof(sockaddr); if (!addrConnect.GetSockAddr((struct sockaddr*)&sockaddr, &len)) { printf("Cannot connect to %s: unsupported network\n", addrConnect.ToString().c_str()); return false; } SOCKET hSocket = socket(((struct sockaddr*)&sockaddr)->sa_family, SOCK_STREAM, IPPROTO_TCP); if (hSocket == INVALID_SOCKET) return false; #ifdef SO_NOSIGPIPE int set = 1; setsockopt(hSocket, SOL_SOCKET, SO_NOSIGPIPE, (void*)&set, sizeof(int)); #endif #ifdef WIN32 u_long fNonblock = 1; if (ioctlsocket(hSocket, FIONBIO, &fNonblock) == SOCKET_ERROR) #else int fFlags = fcntl(hSocket, F_GETFL, 0); if (fcntl(hSocket, F_SETFL, fFlags | O_NONBLOCK) == -1) #endif { closesocket(hSocket); return false; } if (connect(hSocket, (struct sockaddr*)&sockaddr, len) == SOCKET_ERROR) { // WSAEINVAL is here because some legacy version of winsock uses it if (WSAGetLastError() == WSAEINPROGRESS || WSAGetLastError() == WSAEWOULDBLOCK || WSAGetLastError() == WSAEINVAL) { struct timeval timeout; timeout.tv_sec = nTimeout / 1000; timeout.tv_usec = (nTimeout % 1000) * 1000; fd_set fdset; FD_ZERO(&fdset); FD_SET(hSocket, &fdset); int nRet = select(hSocket + 1, NULL, &fdset, NULL, &timeout); if (nRet == 0) { printf("connection timeout\n"); closesocket(hSocket); return false; } if (nRet == SOCKET_ERROR) { printf("select() for connection failed: %i\n",WSAGetLastError()); closesocket(hSocket); return false; } socklen_t nRetSize = sizeof(nRet); #ifdef WIN32 if (getsockopt(hSocket, SOL_SOCKET, SO_ERROR, (char*)(&nRet), &nRetSize) == SOCKET_ERROR) #else if (getsockopt(hSocket, SOL_SOCKET, SO_ERROR, &nRet, &nRetSize) == SOCKET_ERROR) #endif { printf("getsockopt() for connection failed: %i\n",WSAGetLastError()); closesocket(hSocket); return false; } if (nRet != 0) { printf("connect() failed after select(): %s\n",strerror(nRet)); closesocket(hSocket); return false; } } #ifdef WIN32 else if (WSAGetLastError() != WSAEISCONN) #else else #endif { printf("connect() failed: %i\n",WSAGetLastError()); closesocket(hSocket); return false; } } // this isn't even strictly necessary // CNode::ConnectNode immediately turns the socket back to non-blocking // but we'll turn it back to blocking just in case #ifdef WIN32 fNonblock = 0; if (ioctlsocket(hSocket, FIONBIO, &fNonblock) == SOCKET_ERROR) #else fFlags = fcntl(hSocket, F_GETFL, 0); if (fcntl(hSocket, F_SETFL, fFlags & !O_NONBLOCK) == SOCKET_ERROR) #endif { closesocket(hSocket); return false; } hSocketRet = hSocket; return true; }
bool static ConnectSocketDirectly(const CService &addrConnect, SOCKET& hSocketRet, int nTimeout) { hSocketRet = INVALID_SOCKET; struct sockaddr_storage sockaddr; socklen_t len = sizeof(sockaddr); if (!addrConnect.GetSockAddr((struct sockaddr*)&sockaddr, &len)) { LogPrintf("Cannot connect to %s: unsupported network\n", addrConnect.ToString()); return false; } SOCKET hSocket = socket(((struct sockaddr*)&sockaddr)->sa_family, SOCK_STREAM, IPPROTO_TCP); if (hSocket == INVALID_SOCKET) return false; #ifdef SO_NOSIGPIPE int set = 1; setsockopt(hSocket, SOL_SOCKET, SO_NOSIGPIPE, (void*)&set, sizeof(int)); #endif #ifdef WIN32 u_long fNonblock = 1; if (ioctlsocket(hSocket, FIONBIO, &fNonblock) == SOCKET_ERROR) #else int fFlags = fcntl(hSocket, F_GETFL, 0); if (fcntl(hSocket, F_SETFL, fFlags | O_NONBLOCK) == -1) #endif { closesocket(hSocket); return false; } if (connect(hSocket, (struct sockaddr*)&sockaddr, len) == SOCKET_ERROR) { int nErr = WSAGetLastError(); // WSAEINVAL is here because some legacy version of winsock uses it if (nErr == WSAEINPROGRESS || nErr == WSAEWOULDBLOCK || nErr == WSAEINVAL) { struct timeval timeout; timeout.tv_sec = nTimeout / 1000; timeout.tv_usec = (nTimeout % 1000) * 1000; fd_set fdset; FD_ZERO(&fdset); FD_SET(hSocket, &fdset); int nRet = select(hSocket + 1, NULL, &fdset, NULL, &timeout); if (nRet == 0) { LogPrint("net", "connection to %s timeout\n", addrConnect.ToString()); closesocket(hSocket); return false; } if (nRet == SOCKET_ERROR) { LogPrintf("select() for %s failed: %i\n", addrConnect.ToString(), WSAGetLastError()); closesocket(hSocket); return false; } socklen_t nRetSize = sizeof(nRet); #ifdef WIN32 if (getsockopt(hSocket, SOL_SOCKET, SO_ERROR, (char*)(&nRet), &nRetSize) == SOCKET_ERROR) #else if (getsockopt(hSocket, SOL_SOCKET, SO_ERROR, &nRet, &nRetSize) == SOCKET_ERROR) #endif { LogPrintf("getsockopt() for %s failed: %i\n", addrConnect.ToString(), WSAGetLastError()); closesocket(hSocket); return false; } if (nRet != 0) { LogPrintf("connect() to %s failed after select(): %s\n", addrConnect.ToString(), strerror(nRet)); closesocket(hSocket); return false; } } #ifdef WIN32 else if (WSAGetLastError() != WSAEISCONN) #else else #endif { LogPrintf("connect() to %s failed: %i\n", addrConnect.ToString(), WSAGetLastError()); closesocket(hSocket); return false; } }
bool static ConnectSocketDirectly(const CService& addrConnect, SOCKET& hSocketRet, int nTimeout) { hSocketRet = INVALID_SOCKET; struct sockaddr_storage sockaddr; socklen_t len = sizeof(sockaddr); if (!addrConnect.GetSockAddr((struct sockaddr*)&sockaddr, &len)) { LogPrintf("Cannot connect to %s: unsupported network\n", addrConnect.ToString()); return false; } SOCKET hSocket = socket(((struct sockaddr*)&sockaddr)->sa_family, SOCK_STREAM, IPPROTO_TCP); if (hSocket == INVALID_SOCKET) return false; #ifdef SO_NOSIGPIPE int set = 1; // Different way of disabling SIGPIPE on BSD setsockopt(hSocket, SOL_SOCKET, SO_NOSIGPIPE, (void*)&set, sizeof(int)); #endif // Set to non-blocking if (!SetSocketNonBlocking(hSocket, true)) return error("ConnectSocketDirectly: Setting socket to non-blocking failed, error %s\n", NetworkErrorString(WSAGetLastError())); if (connect(hSocket, (struct sockaddr*)&sockaddr, len) == SOCKET_ERROR) { int nErr = WSAGetLastError(); // WSAEINVAL is here because some legacy version of winsock uses it if (nErr == WSAEINPROGRESS || nErr == WSAEWOULDBLOCK || nErr == WSAEINVAL) { struct timeval timeout = MillisToTimeval(nTimeout); fd_set fdset; FD_ZERO(&fdset); FD_SET(hSocket, &fdset); int nRet = select(hSocket + 1, NULL, &fdset, NULL, &timeout); if (nRet == 0) { LogPrint("net", "connection to %s timeout\n", addrConnect.ToString()); CloseSocket(hSocket); return false; } if (nRet == SOCKET_ERROR) { LogPrintf("select() for %s failed: %s\n", addrConnect.ToString(), NetworkErrorString(WSAGetLastError())); CloseSocket(hSocket); return false; } socklen_t nRetSize = sizeof(nRet); #ifdef WIN32 if (getsockopt(hSocket, SOL_SOCKET, SO_ERROR, (char*)(&nRet), &nRetSize) == SOCKET_ERROR) #else if (getsockopt(hSocket, SOL_SOCKET, SO_ERROR, &nRet, &nRetSize) == SOCKET_ERROR) #endif { LogPrintf("getsockopt() for %s failed: %s\n", addrConnect.ToString(), NetworkErrorString(WSAGetLastError())); CloseSocket(hSocket); return false; } if (nRet != 0) { LogPrintf("connect() to %s failed after select(): %s\n", addrConnect.ToString(), NetworkErrorString(nRet)); CloseSocket(hSocket); return false; } } #ifdef WIN32 else if (WSAGetLastError() != WSAEISCONN) #else else #endif { LogPrintf("connect() to %s failed: %s\n", addrConnect.ToString(), NetworkErrorString(WSAGetLastError())); CloseSocket(hSocket); return false; } }
bool ConnectSocket(const CService &addrDest, SOCKET& hSocketRet, int nTimeout) { hSocketRet = INVALID_SOCKET; SOCKET hSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (hSocket == INVALID_SOCKET) return false; #ifdef SO_NOSIGPIPE int set = 1; setsockopt(hSocket, SOL_SOCKET, SO_NOSIGPIPE, (void*)&set, sizeof(int)); #endif bool fProxy = (fUseProxy && addrDest.IsRoutable()); struct sockaddr_in sockaddr; if (fProxy) addrProxy.GetSockAddr(&sockaddr); else addrDest.GetSockAddr(&sockaddr); #ifdef WIN32 u_long fNonblock = 1; if (ioctlsocket(hSocket, FIONBIO, &fNonblock) == SOCKET_ERROR) #else int fFlags = fcntl(hSocket, F_GETFL, 0); if (fcntl(hSocket, F_SETFL, fFlags | O_NONBLOCK) == -1) #endif { closesocket(hSocket); return false; } if (connect(hSocket, (struct sockaddr*)&sockaddr, sizeof(sockaddr)) == SOCKET_ERROR) { // WSAEINVAL is here because some legacy version of winsock uses it if (WSAGetLastError() == WSAEINPROGRESS || WSAGetLastError() == WSAEWOULDBLOCK || WSAGetLastError() == WSAEINVAL) { struct timeval timeout; timeout.tv_sec = nTimeout / 1000; timeout.tv_usec = (nTimeout % 1000) * 1000; fd_set fdset; FD_ZERO(&fdset); FD_SET(hSocket, &fdset); int nRet = select(hSocket + 1, NULL, &fdset, NULL, &timeout); if (nRet == 0) { printf("connection timeout\n"); closesocket(hSocket); return false; } if (nRet == SOCKET_ERROR) { printf("select() for connection failed: %i\n",WSAGetLastError()); closesocket(hSocket); return false; } socklen_t nRetSize = sizeof(nRet); #ifdef WIN32 if (getsockopt(hSocket, SOL_SOCKET, SO_ERROR, (char*)(&nRet), &nRetSize) == SOCKET_ERROR) #else if (getsockopt(hSocket, SOL_SOCKET, SO_ERROR, &nRet, &nRetSize) == SOCKET_ERROR) #endif { printf("getsockopt() for connection failed: %i\n",WSAGetLastError()); closesocket(hSocket); return false; } if (nRet != 0) { printf("connect() failed after select(): %s\n",strerror(nRet)); closesocket(hSocket); return false; } } #ifdef WIN32 else if (WSAGetLastError() != WSAEISCONN) #else else #endif { printf("connect() failed: %i\n",WSAGetLastError()); closesocket(hSocket); return false; } } // this isn't even strictly necessary // CNode::ConnectNode immediately turns the socket back to non-blocking // but we'll turn it back to blocking just in case #ifdef WIN32 fNonblock = 0; if (ioctlsocket(hSocket, FIONBIO, &fNonblock) == SOCKET_ERROR) #else fFlags = fcntl(hSocket, F_GETFL, 0); if (fcntl(hSocket, F_SETFL, fFlags & !O_NONBLOCK) == SOCKET_ERROR) #endif { closesocket(hSocket); return false; } if (fProxy) { printf("proxy connecting %s\n", addrDest.ToString().c_str()); char pszSocks4IP[] = "\4\1\0\0\0\0\0\0user"; struct sockaddr_in addr; addrDest.GetSockAddr(&addr); 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("proxy connected %s\n", addrDest.ToString().c_str()); } hSocketRet = hSocket; return true; }
bool static ConnectSocketDirectly(const CService &addrConnect, SOCKET& hSocketRet, int nTimeout) { hSocketRet = INVALID_SOCKET; struct sockaddr_storage sockaddr; socklen_t len = sizeof(sockaddr); if (!addrConnect.GetSockAddr((struct sockaddr*)&sockaddr, &len)) { printf("Cannot connect to %s: unsupported network\n", addrConnect.ToString().c_str()); return false; } SOCKET hSocket = socket(((struct sockaddr*)&sockaddr)->sa_family, SOCK_STREAM, IPPROTO_TCP); if (hSocket == INVALID_SOCKET) return false; #ifdef SO_NOSIGPIPE int set = 1; setsockopt(hSocket, SOL_SOCKET, SO_NOSIGPIPE, (void*)&set, sizeof(int)); #endif if (!SetSocketNonBlocking(hSocket, true)) return error("ConnectSocketDirectly: Setting socket to non-blocking failed, error %i\n", WSAGetLastError()); if (connect(hSocket, (struct sockaddr*)&sockaddr, len) == SOCKET_ERROR) { // WSAEINVAL is here because some legacy version of winsock uses it if (WSAGetLastError() == WSAEINPROGRESS || WSAGetLastError() == WSAEWOULDBLOCK || WSAGetLastError() == WSAEINVAL) { struct timeval timeout; timeout.tv_sec = nTimeout / 1000; timeout.tv_usec = (nTimeout % 1000) * 1000; fd_set fdset; FD_ZERO(&fdset); FD_SET(hSocket, &fdset); int nRet = select(hSocket + 1, NULL, &fdset, NULL, &timeout); if (nRet == 0) { printf("connection timeout\n"); CloseSocket(hSocket); return false; } if (nRet == SOCKET_ERROR) { printf("select() for connection failed: %i\n",WSAGetLastError()); CloseSocket(hSocket); return false; } socklen_t nRetSize = sizeof(nRet); #ifdef WIN32 if (getsockopt(hSocket, SOL_SOCKET, SO_ERROR, (char*)(&nRet), &nRetSize) == SOCKET_ERROR) #else if (getsockopt(hSocket, SOL_SOCKET, SO_ERROR, &nRet, &nRetSize) == SOCKET_ERROR) #endif { printf("getsockopt() for connection failed: %i\n",WSAGetLastError()); CloseSocket(hSocket); return false; } if (nRet != 0) { printf("connect() failed after select(): %s\n",strerror(nRet)); CloseSocket(hSocket); return false; } } #ifdef WIN32 else if (WSAGetLastError() != WSAEISCONN) #else else #endif { printf("connect() failed: %i\n",WSAGetLastError()); CloseSocket(hSocket); return false; } } hSocketRet = hSocket; return true; }