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 25KB

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