You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

netbase.cpp 24KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729
  1. // Copyright (c) 2009-2010 Satoshi Nakamoto
  2. // Copyright (c) 2009-2017 The Bitcoin Core developers
  3. // Distributed under the MIT software license, see the accompanying
  4. // file COPYING or http://www.opensource.org/licenses/mit-license.php.
  5. #include <netbase.h>
  6. #include <hash.h>
  7. #include <sync.h>
  8. #include <uint256.h>
  9. #include <random.h>
  10. #include <util.h>
  11. #include <utilstrencodings.h>
  12. #include <atomic>
  13. #ifndef WIN32
  14. #include <fcntl.h>
  15. #endif
  16. #include <boost/algorithm/string/case_conv.hpp> // for to_lower()
  17. #include <boost/algorithm/string/predicate.hpp> // for startswith() and endswith()
  18. #if !defined(HAVE_MSG_NOSIGNAL)
  19. #define MSG_NOSIGNAL 0
  20. #endif
  21. // Settings
  22. static proxyType proxyInfo[NET_MAX];
  23. static proxyType nameProxy;
  24. static CCriticalSection cs_proxyInfos;
  25. int nConnectTimeout = DEFAULT_CONNECT_TIMEOUT;
  26. bool fNameLookup = DEFAULT_NAME_LOOKUP;
  27. // Need ample time for negotiation for very slow proxies such as Tor (milliseconds)
  28. static const int SOCKS5_RECV_TIMEOUT = 20 * 1000;
  29. static std::atomic<bool> interruptSocks5Recv(false);
  30. enum Network ParseNetwork(std::string net) {
  31. boost::to_lower(net);
  32. if (net == "ipv4") return NET_IPV4;
  33. if (net == "ipv6") return NET_IPV6;
  34. if (net == "tor" || net == "onion") return NET_TOR;
  35. return NET_UNROUTABLE;
  36. }
  37. std::string GetNetworkName(enum Network net) {
  38. switch(net)
  39. {
  40. case NET_IPV4: return "ipv4";
  41. case NET_IPV6: return "ipv6";
  42. case NET_TOR: return "onion";
  43. default: return "";
  44. }
  45. }
  46. bool static LookupIntern(const char *pszName, std::vector<CNetAddr>& vIP, unsigned int nMaxSolutions, bool fAllowLookup)
  47. {
  48. vIP.clear();
  49. {
  50. CNetAddr addr;
  51. if (addr.SetSpecial(std::string(pszName))) {
  52. vIP.push_back(addr);
  53. return true;
  54. }
  55. }
  56. struct addrinfo aiHint;
  57. memset(&aiHint, 0, sizeof(struct addrinfo));
  58. aiHint.ai_socktype = SOCK_STREAM;
  59. aiHint.ai_protocol = IPPROTO_TCP;
  60. aiHint.ai_family = AF_UNSPEC;
  61. #ifdef WIN32
  62. aiHint.ai_flags = fAllowLookup ? 0 : AI_NUMERICHOST;
  63. #else
  64. aiHint.ai_flags = fAllowLookup ? AI_ADDRCONFIG : AI_NUMERICHOST;
  65. #endif
  66. struct addrinfo *aiRes = nullptr;
  67. int nErr = getaddrinfo(pszName, nullptr, &aiHint, &aiRes);
  68. if (nErr)
  69. return false;
  70. struct addrinfo *aiTrav = aiRes;
  71. while (aiTrav != nullptr && (nMaxSolutions == 0 || vIP.size() < nMaxSolutions))
  72. {
  73. CNetAddr resolved;
  74. if (aiTrav->ai_family == AF_INET)
  75. {
  76. assert(aiTrav->ai_addrlen >= sizeof(sockaddr_in));
  77. resolved = CNetAddr(((struct sockaddr_in*)(aiTrav->ai_addr))->sin_addr);
  78. }
  79. if (aiTrav->ai_family == AF_INET6)
  80. {
  81. assert(aiTrav->ai_addrlen >= sizeof(sockaddr_in6));
  82. struct sockaddr_in6* s6 = (struct sockaddr_in6*) aiTrav->ai_addr;
  83. resolved = CNetAddr(s6->sin6_addr, s6->sin6_scope_id);
  84. }
  85. /* Never allow resolving to an internal address. Consider any such result invalid */
  86. if (!resolved.IsInternal()) {
  87. vIP.push_back(resolved);
  88. }
  89. aiTrav = aiTrav->ai_next;
  90. }
  91. freeaddrinfo(aiRes);
  92. return (vIP.size() > 0);
  93. }
  94. bool LookupHost(const char *pszName, std::vector<CNetAddr>& vIP, unsigned int nMaxSolutions, bool fAllowLookup)
  95. {
  96. std::string strHost(pszName);
  97. if (strHost.empty())
  98. return false;
  99. if (boost::algorithm::starts_with(strHost, "[") && boost::algorithm::ends_with(strHost, "]"))
  100. {
  101. strHost = strHost.substr(1, strHost.size() - 2);
  102. }
  103. return LookupIntern(strHost.c_str(), vIP, nMaxSolutions, fAllowLookup);
  104. }
  105. bool LookupHost(const char *pszName, CNetAddr& addr, bool fAllowLookup)
  106. {
  107. std::vector<CNetAddr> vIP;
  108. LookupHost(pszName, vIP, 1, fAllowLookup);
  109. if(vIP.empty())
  110. return false;
  111. addr = vIP.front();
  112. return true;
  113. }
  114. bool Lookup(const char *pszName, std::vector<CService>& vAddr, int portDefault, bool fAllowLookup, unsigned int nMaxSolutions)
  115. {
  116. if (pszName[0] == 0)
  117. return false;
  118. int port = portDefault;
  119. std::string hostname = "";
  120. SplitHostPort(std::string(pszName), port, hostname);
  121. std::vector<CNetAddr> vIP;
  122. bool fRet = LookupIntern(hostname.c_str(), vIP, nMaxSolutions, fAllowLookup);
  123. if (!fRet)
  124. return false;
  125. vAddr.resize(vIP.size());
  126. for (unsigned int i = 0; i < vIP.size(); i++)
  127. vAddr[i] = CService(vIP[i], port);
  128. return true;
  129. }
  130. bool Lookup(const char *pszName, CService& addr, int portDefault, bool fAllowLookup)
  131. {
  132. std::vector<CService> vService;
  133. bool fRet = Lookup(pszName, vService, portDefault, fAllowLookup, 1);
  134. if (!fRet)
  135. return false;
  136. addr = vService[0];
  137. return true;
  138. }
  139. CService LookupNumeric(const char *pszName, int portDefault)
  140. {
  141. CService addr;
  142. // "1.2:345" will fail to resolve the ip, but will still set the port.
  143. // If the ip fails to resolve, re-init the result.
  144. if(!Lookup(pszName, addr, portDefault, false))
  145. addr = CService();
  146. return addr;
  147. }
  148. struct timeval MillisToTimeval(int64_t nTimeout)
  149. {
  150. struct timeval timeout;
  151. timeout.tv_sec = nTimeout / 1000;
  152. timeout.tv_usec = (nTimeout % 1000) * 1000;
  153. return timeout;
  154. }
  155. /** SOCKS version */
  156. enum SOCKSVersion: uint8_t {
  157. SOCKS4 = 0x04,
  158. SOCKS5 = 0x05
  159. };
  160. /** Values defined for METHOD in RFC1928 */
  161. enum SOCKS5Method: uint8_t {
  162. NOAUTH = 0x00, //! No authentication required
  163. GSSAPI = 0x01, //! GSSAPI
  164. USER_PASS = 0x02, //! Username/password
  165. NO_ACCEPTABLE = 0xff, //! No acceptable methods
  166. };
  167. /** Values defined for CMD in RFC1928 */
  168. enum SOCKS5Command: uint8_t {
  169. CONNECT = 0x01,
  170. BIND = 0x02,
  171. UDP_ASSOCIATE = 0x03
  172. };
  173. /** Values defined for REP in RFC1928 */
  174. enum SOCKS5Reply: uint8_t {
  175. SUCCEEDED = 0x00, //! Succeeded
  176. GENFAILURE = 0x01, //! General failure
  177. NOTALLOWED = 0x02, //! Connection not allowed by ruleset
  178. NETUNREACHABLE = 0x03, //! Network unreachable
  179. HOSTUNREACHABLE = 0x04, //! Network unreachable
  180. CONNREFUSED = 0x05, //! Connection refused
  181. TTLEXPIRED = 0x06, //! TTL expired
  182. CMDUNSUPPORTED = 0x07, //! Command not supported
  183. ATYPEUNSUPPORTED = 0x08, //! Address type not supported
  184. };
  185. /** Values defined for ATYPE in RFC1928 */
  186. enum SOCKS5Atyp: uint8_t {
  187. IPV4 = 0x01,
  188. DOMAINNAME = 0x03,
  189. IPV6 = 0x04,
  190. };
  191. /** Status codes that can be returned by InterruptibleRecv */
  192. enum class IntrRecvError {
  193. OK,
  194. Timeout,
  195. Disconnected,
  196. NetworkError,
  197. Interrupted
  198. };
  199. /**
  200. * Read bytes from socket. This will either read the full number of bytes requested
  201. * or return False on error or timeout.
  202. * This function can be interrupted by calling InterruptSocks5()
  203. *
  204. * @param data Buffer to receive into
  205. * @param len Length of data to receive
  206. * @param timeout Timeout in milliseconds for receive operation
  207. *
  208. * @note This function requires that hSocket is in non-blocking mode.
  209. */
  210. static IntrRecvError InterruptibleRecv(uint8_t* data, size_t len, int timeout, const SOCKET& hSocket)
  211. {
  212. int64_t curTime = GetTimeMillis();
  213. int64_t endTime = curTime + timeout;
  214. // Maximum time to wait in one select call. It will take up until this time (in millis)
  215. // to break off in case of an interruption.
  216. const int64_t maxWait = 1000;
  217. while (len > 0 && curTime < endTime) {
  218. ssize_t ret = recv(hSocket, (char*)data, len, 0); // Optimistically try the recv first
  219. if (ret > 0) {
  220. len -= ret;
  221. data += ret;
  222. } else if (ret == 0) { // Unexpected disconnection
  223. return IntrRecvError::Disconnected;
  224. } else { // Other error or blocking
  225. int nErr = WSAGetLastError();
  226. if (nErr == WSAEINPROGRESS || nErr == WSAEWOULDBLOCK || nErr == WSAEINVAL) {
  227. if (!IsSelectableSocket(hSocket)) {
  228. return IntrRecvError::NetworkError;
  229. }
  230. struct timeval tval = MillisToTimeval(std::min(endTime - curTime, maxWait));
  231. fd_set fdset;
  232. FD_ZERO(&fdset);
  233. FD_SET(hSocket, &fdset);
  234. int nRet = select(hSocket + 1, &fdset, nullptr, nullptr, &tval);
  235. if (nRet == SOCKET_ERROR) {
  236. return IntrRecvError::NetworkError;
  237. }
  238. } else {
  239. return IntrRecvError::NetworkError;
  240. }
  241. }
  242. if (interruptSocks5Recv)
  243. return IntrRecvError::Interrupted;
  244. curTime = GetTimeMillis();
  245. }
  246. return len == 0 ? IntrRecvError::OK : IntrRecvError::Timeout;
  247. }
  248. /** Credentials for proxy authentication */
  249. struct ProxyCredentials
  250. {
  251. std::string username;
  252. std::string password;
  253. };
  254. /** Convert SOCKS5 reply to an error message */
  255. std::string Socks5ErrorString(uint8_t err)
  256. {
  257. switch(err) {
  258. case SOCKS5Reply::GENFAILURE:
  259. return "general failure";
  260. case SOCKS5Reply::NOTALLOWED:
  261. return "connection not allowed";
  262. case SOCKS5Reply::NETUNREACHABLE:
  263. return "network unreachable";
  264. case SOCKS5Reply::HOSTUNREACHABLE:
  265. return "host unreachable";
  266. case SOCKS5Reply::CONNREFUSED:
  267. return "connection refused";
  268. case SOCKS5Reply::TTLEXPIRED:
  269. return "TTL expired";
  270. case SOCKS5Reply::CMDUNSUPPORTED:
  271. return "protocol error";
  272. case SOCKS5Reply::ATYPEUNSUPPORTED:
  273. return "address type not supported";
  274. default:
  275. return "unknown";
  276. }
  277. }
  278. /** Connect using SOCKS5 (as described in RFC1928) */
  279. static bool Socks5(const std::string& strDest, int port, const ProxyCredentials *auth, const SOCKET& hSocket)
  280. {
  281. IntrRecvError recvr;
  282. LogPrint(BCLog::NET, "SOCKS5 connecting %s\n", strDest);
  283. if (strDest.size() > 255) {
  284. return error("Hostname too long");
  285. }
  286. // Accepted authentication methods
  287. std::vector<uint8_t> vSocks5Init;
  288. vSocks5Init.push_back(SOCKSVersion::SOCKS5);
  289. if (auth) {
  290. vSocks5Init.push_back(0x02); // Number of methods
  291. vSocks5Init.push_back(SOCKS5Method::NOAUTH);
  292. vSocks5Init.push_back(SOCKS5Method::USER_PASS);
  293. } else {
  294. vSocks5Init.push_back(0x01); // Number of methods
  295. vSocks5Init.push_back(SOCKS5Method::NOAUTH);
  296. }
  297. ssize_t ret = send(hSocket, (const char*)vSocks5Init.data(), vSocks5Init.size(), MSG_NOSIGNAL);
  298. if (ret != (ssize_t)vSocks5Init.size()) {
  299. return error("Error sending to proxy");
  300. }
  301. uint8_t pchRet1[2];
  302. if ((recvr = InterruptibleRecv(pchRet1, 2, SOCKS5_RECV_TIMEOUT, hSocket)) != IntrRecvError::OK) {
  303. LogPrintf("Socks5() connect to %s:%d failed: InterruptibleRecv() timeout or other failure\n", strDest, port);
  304. return false;
  305. }
  306. if (pchRet1[0] != SOCKSVersion::SOCKS5) {
  307. return error("Proxy failed to initialize");
  308. }
  309. if (pchRet1[1] == SOCKS5Method::USER_PASS && auth) {
  310. // Perform username/password authentication (as described in RFC1929)
  311. std::vector<uint8_t> vAuth;
  312. vAuth.push_back(0x01); // Current (and only) version of user/pass subnegotiation
  313. if (auth->username.size() > 255 || auth->password.size() > 255)
  314. return error("Proxy username or password too long");
  315. vAuth.push_back(auth->username.size());
  316. vAuth.insert(vAuth.end(), auth->username.begin(), auth->username.end());
  317. vAuth.push_back(auth->password.size());
  318. vAuth.insert(vAuth.end(), auth->password.begin(), auth->password.end());
  319. ret = send(hSocket, (const char*)vAuth.data(), vAuth.size(), MSG_NOSIGNAL);
  320. if (ret != (ssize_t)vAuth.size()) {
  321. return error("Error sending authentication to proxy");
  322. }
  323. LogPrint(BCLog::PROXY, "SOCKS5 sending proxy authentication %s:%s\n", auth->username, auth->password);
  324. uint8_t pchRetA[2];
  325. if ((recvr = InterruptibleRecv(pchRetA, 2, SOCKS5_RECV_TIMEOUT, hSocket)) != IntrRecvError::OK) {
  326. return error("Error reading proxy authentication response");
  327. }
  328. if (pchRetA[0] != 0x01 || pchRetA[1] != 0x00) {
  329. return error("Proxy authentication unsuccessful");
  330. }
  331. } else if (pchRet1[1] == SOCKS5Method::NOAUTH) {
  332. // Perform no authentication
  333. } else {
  334. return error("Proxy requested wrong authentication method %02x", pchRet1[1]);
  335. }
  336. std::vector<uint8_t> vSocks5;
  337. vSocks5.push_back(SOCKSVersion::SOCKS5); // VER protocol version
  338. vSocks5.push_back(SOCKS5Command::CONNECT); // CMD CONNECT
  339. vSocks5.push_back(0x00); // RSV Reserved must be 0
  340. vSocks5.push_back(SOCKS5Atyp::DOMAINNAME); // ATYP DOMAINNAME
  341. vSocks5.push_back(strDest.size()); // Length<=255 is checked at beginning of function
  342. vSocks5.insert(vSocks5.end(), strDest.begin(), strDest.end());
  343. vSocks5.push_back((port >> 8) & 0xFF);
  344. vSocks5.push_back((port >> 0) & 0xFF);
  345. ret = send(hSocket, (const char*)vSocks5.data(), vSocks5.size(), MSG_NOSIGNAL);
  346. if (ret != (ssize_t)vSocks5.size()) {
  347. return error("Error sending to proxy");
  348. }
  349. uint8_t pchRet2[4];
  350. if ((recvr = InterruptibleRecv(pchRet2, 4, SOCKS5_RECV_TIMEOUT, hSocket)) != IntrRecvError::OK) {
  351. if (recvr == IntrRecvError::Timeout) {
  352. /* If a timeout happens here, this effectively means we timed out while connecting
  353. * to the remote node. This is very common for Tor, so do not print an
  354. * error message. */
  355. return false;
  356. } else {
  357. return error("Error while reading proxy response");
  358. }
  359. }
  360. if (pchRet2[0] != SOCKSVersion::SOCKS5) {
  361. return error("Proxy failed to accept request");
  362. }
  363. if (pchRet2[1] != SOCKS5Reply::SUCCEEDED) {
  364. // Failures to connect to a peer that are not proxy errors
  365. LogPrintf("Socks5() connect to %s:%d failed: %s\n", strDest, port, Socks5ErrorString(pchRet2[1]));
  366. return false;
  367. }
  368. if (pchRet2[2] != 0x00) { // Reserved field must be 0
  369. return error("Error: malformed proxy response");
  370. }
  371. uint8_t pchRet3[256];
  372. switch (pchRet2[3])
  373. {
  374. case SOCKS5Atyp::IPV4: recvr = InterruptibleRecv(pchRet3, 4, SOCKS5_RECV_TIMEOUT, hSocket); break;
  375. case SOCKS5Atyp::IPV6: recvr = InterruptibleRecv(pchRet3, 16, SOCKS5_RECV_TIMEOUT, hSocket); break;
  376. case SOCKS5Atyp::DOMAINNAME:
  377. {
  378. recvr = InterruptibleRecv(pchRet3, 1, SOCKS5_RECV_TIMEOUT, hSocket);
  379. if (recvr != IntrRecvError::OK) {
  380. return error("Error reading from proxy");
  381. }
  382. int nRecv = pchRet3[0];
  383. recvr = InterruptibleRecv(pchRet3, nRecv, SOCKS5_RECV_TIMEOUT, hSocket);
  384. break;
  385. }
  386. default: return error("Error: malformed proxy response");
  387. }
  388. if (recvr != IntrRecvError::OK) {
  389. return error("Error reading from proxy");
  390. }
  391. if ((recvr = InterruptibleRecv(pchRet3, 2, SOCKS5_RECV_TIMEOUT, hSocket)) != IntrRecvError::OK) {
  392. return error("Error reading from proxy");
  393. }
  394. LogPrint(BCLog::NET, "SOCKS5 connected %s\n", strDest);
  395. return true;
  396. }
  397. SOCKET CreateSocket(const CService &addrConnect)
  398. {
  399. struct sockaddr_storage sockaddr;
  400. socklen_t len = sizeof(sockaddr);
  401. if (!addrConnect.GetSockAddr((struct sockaddr*)&sockaddr, &len)) {
  402. LogPrintf("Cannot create socket for %s: unsupported network\n", addrConnect.ToString());
  403. return INVALID_SOCKET;
  404. }
  405. SOCKET hSocket = socket(((struct sockaddr*)&sockaddr)->sa_family, SOCK_STREAM, IPPROTO_TCP);
  406. if (hSocket == INVALID_SOCKET)
  407. return INVALID_SOCKET;
  408. if (!IsSelectableSocket(hSocket)) {
  409. CloseSocket(hSocket);
  410. LogPrintf("Cannot create connection: non-selectable socket created (fd >= FD_SETSIZE ?)\n");
  411. return INVALID_SOCKET;
  412. }
  413. #ifdef SO_NOSIGPIPE
  414. int set = 1;
  415. // Different way of disabling SIGPIPE on BSD
  416. setsockopt(hSocket, SOL_SOCKET, SO_NOSIGPIPE, (void*)&set, sizeof(int));
  417. #endif
  418. //Disable Nagle's algorithm
  419. SetSocketNoDelay(hSocket);
  420. // Set to non-blocking
  421. if (!SetSocketNonBlocking(hSocket, true)) {
  422. CloseSocket(hSocket);
  423. LogPrintf("ConnectSocketDirectly: Setting socket to non-blocking failed, error %s\n", NetworkErrorString(WSAGetLastError()));
  424. }
  425. return hSocket;
  426. }
  427. bool ConnectSocketDirectly(const CService &addrConnect, const SOCKET& hSocket, int nTimeout)
  428. {
  429. struct sockaddr_storage sockaddr;
  430. socklen_t len = sizeof(sockaddr);
  431. if (hSocket == INVALID_SOCKET) {
  432. LogPrintf("Cannot connect to %s: invalid socket\n", addrConnect.ToString());
  433. return false;
  434. }
  435. if (!addrConnect.GetSockAddr((struct sockaddr*)&sockaddr, &len)) {
  436. LogPrintf("Cannot connect to %s: unsupported network\n", addrConnect.ToString());
  437. return false;
  438. }
  439. if (connect(hSocket, (struct sockaddr*)&sockaddr, len) == SOCKET_ERROR)
  440. {
  441. int nErr = WSAGetLastError();
  442. // WSAEINVAL is here because some legacy version of winsock uses it
  443. if (nErr == WSAEINPROGRESS || nErr == WSAEWOULDBLOCK || nErr == WSAEINVAL)
  444. {
  445. struct timeval timeout = MillisToTimeval(nTimeout);
  446. fd_set fdset;
  447. FD_ZERO(&fdset);
  448. FD_SET(hSocket, &fdset);
  449. int nRet = select(hSocket + 1, nullptr, &fdset, nullptr, &timeout);
  450. if (nRet == 0)
  451. {
  452. LogPrint(BCLog::NET, "connection to %s timeout\n", addrConnect.ToString());
  453. return false;
  454. }
  455. if (nRet == SOCKET_ERROR)
  456. {
  457. LogPrintf("select() for %s failed: %s\n", addrConnect.ToString(), NetworkErrorString(WSAGetLastError()));
  458. return false;
  459. }
  460. socklen_t nRetSize = sizeof(nRet);
  461. #ifdef WIN32
  462. if (getsockopt(hSocket, SOL_SOCKET, SO_ERROR, (char*)(&nRet), &nRetSize) == SOCKET_ERROR)
  463. #else
  464. if (getsockopt(hSocket, SOL_SOCKET, SO_ERROR, &nRet, &nRetSize) == SOCKET_ERROR)
  465. #endif
  466. {
  467. LogPrintf("getsockopt() for %s failed: %s\n", addrConnect.ToString(), NetworkErrorString(WSAGetLastError()));
  468. return false;
  469. }
  470. if (nRet != 0)
  471. {
  472. LogPrintf("connect() to %s failed after select(): %s\n", addrConnect.ToString(), NetworkErrorString(nRet));
  473. return false;
  474. }
  475. }
  476. #ifdef WIN32
  477. else if (WSAGetLastError() != WSAEISCONN)
  478. #else
  479. else
  480. #endif
  481. {
  482. LogPrintf("connect() to %s failed: %s\n", addrConnect.ToString(), NetworkErrorString(WSAGetLastError()));
  483. return false;
  484. }
  485. }
  486. return true;
  487. }
  488. bool SetProxy(enum Network net, const proxyType &addrProxy) {
  489. assert(net >= 0 && net < NET_MAX);
  490. if (!addrProxy.IsValid())
  491. return false;
  492. LOCK(cs_proxyInfos);
  493. proxyInfo[net] = addrProxy;
  494. return true;
  495. }
  496. bool GetProxy(enum Network net, proxyType &proxyInfoOut) {
  497. assert(net >= 0 && net < NET_MAX);
  498. LOCK(cs_proxyInfos);
  499. if (!proxyInfo[net].IsValid())
  500. return false;
  501. proxyInfoOut = proxyInfo[net];
  502. return true;
  503. }
  504. bool SetNameProxy(const proxyType &addrProxy) {
  505. if (!addrProxy.IsValid())
  506. return false;
  507. LOCK(cs_proxyInfos);
  508. nameProxy = addrProxy;
  509. return true;
  510. }
  511. bool GetNameProxy(proxyType &nameProxyOut) {
  512. LOCK(cs_proxyInfos);
  513. if(!nameProxy.IsValid())
  514. return false;
  515. nameProxyOut = nameProxy;
  516. return true;
  517. }
  518. bool HaveNameProxy() {
  519. LOCK(cs_proxyInfos);
  520. return nameProxy.IsValid();
  521. }
  522. bool IsProxy(const CNetAddr &addr) {
  523. LOCK(cs_proxyInfos);
  524. for (int i = 0; i < NET_MAX; i++) {
  525. if (addr == (CNetAddr)proxyInfo[i].proxy)
  526. return true;
  527. }
  528. return false;
  529. }
  530. bool ConnectThroughProxy(const proxyType &proxy, const std::string& strDest, int port, const SOCKET& hSocket, int nTimeout, bool *outProxyConnectionFailed)
  531. {
  532. // first connect to proxy server
  533. if (!ConnectSocketDirectly(proxy.proxy, hSocket, nTimeout)) {
  534. if (outProxyConnectionFailed)
  535. *outProxyConnectionFailed = true;
  536. return false;
  537. }
  538. // do socks negotiation
  539. if (proxy.randomize_credentials) {
  540. ProxyCredentials random_auth;
  541. static std::atomic_int counter(0);
  542. random_auth.username = random_auth.password = strprintf("%i", counter++);
  543. if (!Socks5(strDest, (unsigned short)port, &random_auth, hSocket)) {
  544. return false;
  545. }
  546. } else {
  547. if (!Socks5(strDest, (unsigned short)port, 0, hSocket)) {
  548. return false;
  549. }
  550. }
  551. return true;
  552. }
  553. bool LookupSubNet(const char* pszName, CSubNet& ret)
  554. {
  555. std::string strSubnet(pszName);
  556. size_t slash = strSubnet.find_last_of('/');
  557. std::vector<CNetAddr> vIP;
  558. std::string strAddress = strSubnet.substr(0, slash);
  559. if (LookupHost(strAddress.c_str(), vIP, 1, false))
  560. {
  561. CNetAddr network = vIP[0];
  562. if (slash != strSubnet.npos)
  563. {
  564. std::string strNetmask = strSubnet.substr(slash + 1);
  565. int32_t n;
  566. // IPv4 addresses start at offset 12, and first 12 bytes must match, so just offset n
  567. if (ParseInt32(strNetmask, &n)) { // If valid number, assume /24 syntax
  568. ret = CSubNet(network, n);
  569. return ret.IsValid();
  570. }
  571. else // If not a valid number, try full netmask syntax
  572. {
  573. // Never allow lookup for netmask
  574. if (LookupHost(strNetmask.c_str(), vIP, 1, false)) {
  575. ret = CSubNet(network, vIP[0]);
  576. return ret.IsValid();
  577. }
  578. }
  579. }
  580. else
  581. {
  582. ret = CSubNet(network);
  583. return ret.IsValid();
  584. }
  585. }
  586. return false;
  587. }
  588. #ifdef WIN32
  589. std::string NetworkErrorString(int err)
  590. {
  591. char buf[256];
  592. buf[0] = 0;
  593. if(FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_MAX_WIDTH_MASK,
  594. nullptr, err, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
  595. buf, sizeof(buf), nullptr))
  596. {
  597. return strprintf("%s (%d)", buf, err);
  598. }
  599. else
  600. {
  601. return strprintf("Unknown error (%d)", err);
  602. }
  603. }
  604. #else
  605. std::string NetworkErrorString(int err)
  606. {
  607. char buf[256];
  608. buf[0] = 0;
  609. /* Too bad there are two incompatible implementations of the
  610. * thread-safe strerror. */
  611. const char *s;
  612. #ifdef STRERROR_R_CHAR_P /* GNU variant can return a pointer outside the passed buffer */
  613. s = strerror_r(err, buf, sizeof(buf));
  614. #else /* POSIX variant always returns message in buffer */
  615. s = buf;
  616. if (strerror_r(err, buf, sizeof(buf)))
  617. buf[0] = 0;
  618. #endif
  619. return strprintf("%s (%d)", s, err);
  620. }
  621. #endif
  622. bool CloseSocket(SOCKET& hSocket)
  623. {
  624. if (hSocket == INVALID_SOCKET)
  625. return false;
  626. #ifdef WIN32
  627. int ret = closesocket(hSocket);
  628. #else
  629. int ret = close(hSocket);
  630. #endif
  631. if (ret) {
  632. LogPrintf("Socket close failed: %d. Error: %s\n", hSocket, NetworkErrorString(WSAGetLastError()));
  633. }
  634. hSocket = INVALID_SOCKET;
  635. return ret != SOCKET_ERROR;
  636. }
  637. bool SetSocketNonBlocking(const SOCKET& hSocket, bool fNonBlocking)
  638. {
  639. if (fNonBlocking) {
  640. #ifdef WIN32
  641. u_long nOne = 1;
  642. if (ioctlsocket(hSocket, FIONBIO, &nOne) == SOCKET_ERROR) {
  643. #else
  644. int fFlags = fcntl(hSocket, F_GETFL, 0);
  645. if (fcntl(hSocket, F_SETFL, fFlags | O_NONBLOCK) == SOCKET_ERROR) {
  646. #endif
  647. return false;
  648. }
  649. } else {
  650. #ifdef WIN32
  651. u_long nZero = 0;
  652. if (ioctlsocket(hSocket, FIONBIO, &nZero) == SOCKET_ERROR) {
  653. #else
  654. int fFlags = fcntl(hSocket, F_GETFL, 0);
  655. if (fcntl(hSocket, F_SETFL, fFlags & ~O_NONBLOCK) == SOCKET_ERROR) {
  656. #endif
  657. return false;
  658. }
  659. }
  660. return true;
  661. }
  662. bool SetSocketNoDelay(const SOCKET& hSocket)
  663. {
  664. int set = 1;
  665. int rc = setsockopt(hSocket, IPPROTO_TCP, TCP_NODELAY, (const char*)&set, sizeof(int));
  666. return rc == 0;
  667. }
  668. void InterruptSocks5(bool interrupt)
  669. {
  670. interruptSocks5Recv = interrupt;
  671. }