1 // Copyright (c) 2009-2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2020 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
6 #include <netbase.h>
7
8 #include <sync.h>
9 #include <tinyformat.h>
10 #include <util/strencodings.h>
11 #include <util/string.h>
12 #include <util/system.h>
13
14 #include <atomic>
15
16 #ifndef WIN32
17 #include <fcntl.h>
18 #else
19 #include <codecvt>
20 #endif
21
22 #ifdef USE_POLL
23 #include <poll.h>
24 #endif
25
26 #if !defined(MSG_NOSIGNAL)
27 #define MSG_NOSIGNAL 0
28 #endif
29
30 // Settings
31 static RecursiveMutex cs_proxyInfos;
32 static proxyType proxyInfo[NET_MAX] GUARDED_BY(cs_proxyInfos);
33 static proxyType nameProxy GUARDED_BY(cs_proxyInfos);
34 int nConnectTimeout = DEFAULT_CONNECT_TIMEOUT;
35 bool fNameLookup = DEFAULT_NAME_LOOKUP;
36
37 // Need ample time for negotiation for very slow proxies such as Tor (milliseconds)
38 static const int SOCKS5_RECV_TIMEOUT = 20 * 1000;
39 static std::atomic<bool> interruptSocks5Recv(false);
40
ParseNetwork(const std::string & net_in)41 enum Network ParseNetwork(const std::string& net_in) {
42 std::string net = ToLower(net_in);
43 if (net == "ipv4") return NET_IPV4;
44 if (net == "ipv6") return NET_IPV6;
45 if (net == "onion") return NET_ONION;
46 if (net == "tor") {
47 LogPrintf("Warning: net name 'tor' is deprecated and will be removed in the future. You should use 'onion' instead.\n");
48 return NET_ONION;
49 }
50 return NET_UNROUTABLE;
51 }
52
GetNetworkName(enum Network net)53 std::string GetNetworkName(enum Network net) {
54 switch(net)
55 {
56 case NET_IPV4: return "ipv4";
57 case NET_IPV6: return "ipv6";
58 case NET_ONION: return "onion";
59 default: return "";
60 }
61 }
62
LookupIntern(const std::string & name,std::vector<CNetAddr> & vIP,unsigned int nMaxSolutions,bool fAllowLookup)63 bool static LookupIntern(const std::string& name, std::vector<CNetAddr>& vIP, unsigned int nMaxSolutions, bool fAllowLookup)
64 {
65 vIP.clear();
66
67 if (!ValidAsCString(name)) {
68 return false;
69 }
70
71 {
72 CNetAddr addr;
73 // From our perspective, onion addresses are not hostnames but rather
74 // direct encodings of CNetAddr much like IPv4 dotted-decimal notation
75 // or IPv6 colon-separated hextet notation. Since we can't use
76 // getaddrinfo to decode them and it wouldn't make sense to resolve
77 // them, we return a network address representing it instead. See
78 // CNetAddr::SetSpecial(const std::string&) for more details.
79 if (addr.SetSpecial(name)) {
80 vIP.push_back(addr);
81 return true;
82 }
83 }
84
85 struct addrinfo aiHint;
86 memset(&aiHint, 0, sizeof(struct addrinfo));
87
88 // We want a TCP port, which is a streaming socket type
89 aiHint.ai_socktype = SOCK_STREAM;
90 aiHint.ai_protocol = IPPROTO_TCP;
91 // We don't care which address family (IPv4 or IPv6) is returned
92 aiHint.ai_family = AF_UNSPEC;
93 // If we allow lookups of hostnames, use the AI_ADDRCONFIG flag to only
94 // return addresses whose family we have an address configured for.
95 //
96 // If we don't allow lookups, then use the AI_NUMERICHOST flag for
97 // getaddrinfo to only decode numerical network addresses and suppress
98 // hostname lookups.
99 aiHint.ai_flags = fAllowLookup ? AI_ADDRCONFIG : AI_NUMERICHOST;
100 struct addrinfo *aiRes = nullptr;
101 int nErr = getaddrinfo(name.c_str(), nullptr, &aiHint, &aiRes);
102 if (nErr)
103 return false;
104
105 // Traverse the linked list starting with aiTrav, add all non-internal
106 // IPv4,v6 addresses to vIP while respecting nMaxSolutions.
107 struct addrinfo *aiTrav = aiRes;
108 while (aiTrav != nullptr && (nMaxSolutions == 0 || vIP.size() < nMaxSolutions))
109 {
110 CNetAddr resolved;
111 if (aiTrav->ai_family == AF_INET)
112 {
113 assert(aiTrav->ai_addrlen >= sizeof(sockaddr_in));
114 resolved = CNetAddr(((struct sockaddr_in*)(aiTrav->ai_addr))->sin_addr);
115 }
116
117 if (aiTrav->ai_family == AF_INET6)
118 {
119 assert(aiTrav->ai_addrlen >= sizeof(sockaddr_in6));
120 struct sockaddr_in6* s6 = (struct sockaddr_in6*) aiTrav->ai_addr;
121 resolved = CNetAddr(s6->sin6_addr, s6->sin6_scope_id);
122 }
123 /* Never allow resolving to an internal address. Consider any such result invalid */
124 if (!resolved.IsInternal()) {
125 vIP.push_back(resolved);
126 }
127
128 aiTrav = aiTrav->ai_next;
129 }
130
131 freeaddrinfo(aiRes);
132
133 return (vIP.size() > 0);
134 }
135
136 /**
137 * Resolve a host string to its corresponding network addresses.
138 *
139 * @param name The string representing a host. Could be a name or a numerical
140 * IP address (IPv6 addresses in their bracketed form are
141 * allowed).
142 * @param[out] vIP The resulting network addresses to which the specified host
143 * string resolved.
144 *
145 * @returns Whether or not the specified host string successfully resolved to
146 * any resulting network addresses.
147 *
148 * @see Lookup(const char *, std::vector<CService>&, int, bool, unsigned int)
149 * for additional parameter descriptions.
150 */
LookupHost(const std::string & name,std::vector<CNetAddr> & vIP,unsigned int nMaxSolutions,bool fAllowLookup)151 bool LookupHost(const std::string& name, std::vector<CNetAddr>& vIP, unsigned int nMaxSolutions, bool fAllowLookup)
152 {
153 if (!ValidAsCString(name)) {
154 return false;
155 }
156 std::string strHost = name;
157 if (strHost.empty())
158 return false;
159 if (strHost.front() == '[' && strHost.back() == ']') {
160 strHost = strHost.substr(1, strHost.size() - 2);
161 }
162
163 return LookupIntern(strHost, vIP, nMaxSolutions, fAllowLookup);
164 }
165
166 /**
167 * Resolve a host string to its first corresponding network address.
168 *
169 * @see LookupHost(const std::string&, std::vector<CNetAddr>&, unsigned int, bool) for
170 * additional parameter descriptions.
171 */
LookupHost(const std::string & name,CNetAddr & addr,bool fAllowLookup)172 bool LookupHost(const std::string& name, CNetAddr& addr, bool fAllowLookup)
173 {
174 if (!ValidAsCString(name)) {
175 return false;
176 }
177 std::vector<CNetAddr> vIP;
178 LookupHost(name, vIP, 1, fAllowLookup);
179 if(vIP.empty())
180 return false;
181 addr = vIP.front();
182 return true;
183 }
184
185 /**
186 * Resolve a service string to its corresponding service.
187 *
188 * @param name The string representing a service. Could be a name or a
189 * numerical IP address (IPv6 addresses should be in their
190 * disambiguated bracketed form), optionally followed by a port
191 * number. (e.g. example.com:8333 or
192 * [2001:db8:85a3:8d3:1319:8a2e:370:7348]:420)
193 * @param[out] vAddr The resulting services to which the specified service string
194 * resolved.
195 * @param portDefault The default port for resulting services if not specified
196 * by the service string.
197 * @param fAllowLookup Whether or not hostname lookups are permitted. If yes,
198 * external queries may be performed.
199 * @param nMaxSolutions The maximum number of results we want, specifying 0
200 * means "as many solutions as we get."
201 *
202 * @returns Whether or not the service string successfully resolved to any
203 * resulting services.
204 */
Lookup(const std::string & name,std::vector<CService> & vAddr,int portDefault,bool fAllowLookup,unsigned int nMaxSolutions)205 bool Lookup(const std::string& name, std::vector<CService>& vAddr, int portDefault, bool fAllowLookup, unsigned int nMaxSolutions)
206 {
207 if (name.empty() || !ValidAsCString(name)) {
208 return false;
209 }
210 int port = portDefault;
211 std::string hostname;
212 SplitHostPort(name, port, hostname);
213
214 std::vector<CNetAddr> vIP;
215 bool fRet = LookupIntern(hostname, vIP, nMaxSolutions, fAllowLookup);
216 if (!fRet)
217 return false;
218 vAddr.resize(vIP.size());
219 for (unsigned int i = 0; i < vIP.size(); i++)
220 vAddr[i] = CService(vIP[i], port);
221 return true;
222 }
223
224 /**
225 * Resolve a service string to its first corresponding service.
226 *
227 * @see Lookup(const char *, std::vector<CService>&, int, bool, unsigned int)
228 * for additional parameter descriptions.
229 */
Lookup(const std::string & name,CService & addr,int portDefault,bool fAllowLookup)230 bool Lookup(const std::string& name, CService& addr, int portDefault, bool fAllowLookup)
231 {
232 if (!ValidAsCString(name)) {
233 return false;
234 }
235 std::vector<CService> vService;
236 bool fRet = Lookup(name, vService, portDefault, fAllowLookup, 1);
237 if (!fRet)
238 return false;
239 addr = vService[0];
240 return true;
241 }
242
243 /**
244 * Resolve a service string with a numeric IP to its first corresponding
245 * service.
246 *
247 * @returns The resulting CService if the resolution was successful, [::]:0
248 * otherwise.
249 *
250 * @see Lookup(const char *, CService&, int, bool) for additional parameter
251 * descriptions.
252 */
LookupNumeric(const std::string & name,int portDefault)253 CService LookupNumeric(const std::string& name, int portDefault)
254 {
255 if (!ValidAsCString(name)) {
256 return {};
257 }
258 CService addr;
259 // "1.2:345" will fail to resolve the ip, but will still set the port.
260 // If the ip fails to resolve, re-init the result.
261 if(!Lookup(name, addr, portDefault, false))
262 addr = CService();
263 return addr;
264 }
265
MillisToTimeval(int64_t nTimeout)266 struct timeval MillisToTimeval(int64_t nTimeout)
267 {
268 struct timeval timeout;
269 timeout.tv_sec = nTimeout / 1000;
270 timeout.tv_usec = (nTimeout % 1000) * 1000;
271 return timeout;
272 }
273
274 /** SOCKS version */
275 enum SOCKSVersion: uint8_t {
276 SOCKS4 = 0x04,
277 SOCKS5 = 0x05
278 };
279
280 /** Values defined for METHOD in RFC1928 */
281 enum SOCKS5Method: uint8_t {
282 NOAUTH = 0x00, //!< No authentication required
283 GSSAPI = 0x01, //!< GSSAPI
284 USER_PASS = 0x02, //!< Username/password
285 NO_ACCEPTABLE = 0xff, //!< No acceptable methods
286 };
287
288 /** Values defined for CMD in RFC1928 */
289 enum SOCKS5Command: uint8_t {
290 CONNECT = 0x01,
291 BIND = 0x02,
292 UDP_ASSOCIATE = 0x03
293 };
294
295 /** Values defined for REP in RFC1928 */
296 enum SOCKS5Reply: uint8_t {
297 SUCCEEDED = 0x00, //!< Succeeded
298 GENFAILURE = 0x01, //!< General failure
299 NOTALLOWED = 0x02, //!< Connection not allowed by ruleset
300 NETUNREACHABLE = 0x03, //!< Network unreachable
301 HOSTUNREACHABLE = 0x04, //!< Network unreachable
302 CONNREFUSED = 0x05, //!< Connection refused
303 TTLEXPIRED = 0x06, //!< TTL expired
304 CMDUNSUPPORTED = 0x07, //!< Command not supported
305 ATYPEUNSUPPORTED = 0x08, //!< Address type not supported
306 };
307
308 /** Values defined for ATYPE in RFC1928 */
309 enum SOCKS5Atyp: uint8_t {
310 IPV4 = 0x01,
311 DOMAINNAME = 0x03,
312 IPV6 = 0x04,
313 };
314
315 /** Status codes that can be returned by InterruptibleRecv */
316 enum class IntrRecvError {
317 OK,
318 Timeout,
319 Disconnected,
320 NetworkError,
321 Interrupted
322 };
323
324 /**
325 * Try to read a specified number of bytes from a socket. Please read the "see
326 * also" section for more detail.
327 *
328 * @param data The buffer where the read bytes should be stored.
329 * @param len The number of bytes to read into the specified buffer.
330 * @param timeout The total timeout in milliseconds for this read.
331 * @param hSocket The socket (has to be in non-blocking mode) from which to read
332 * bytes.
333 *
334 * @returns An IntrRecvError indicating the resulting status of this read.
335 * IntrRecvError::OK only if all of the specified number of bytes were
336 * read.
337 *
338 * @see This function can be interrupted by calling InterruptSocks5(bool).
339 * Sockets can be made non-blocking with SetSocketNonBlocking(const
340 * SOCKET&, bool).
341 */
InterruptibleRecv(uint8_t * data,size_t len,int timeout,const SOCKET & hSocket)342 static IntrRecvError InterruptibleRecv(uint8_t* data, size_t len, int timeout, const SOCKET& hSocket)
343 {
344 int64_t curTime = GetTimeMillis();
345 int64_t endTime = curTime + timeout;
346 // Maximum time to wait for I/O readiness. It will take up until this time
347 // (in millis) to break off in case of an interruption.
348 const int64_t maxWait = 1000;
349 while (len > 0 && curTime < endTime) {
350 ssize_t ret = recv(hSocket, (char*)data, len, 0); // Optimistically try the recv first
351 if (ret > 0) {
352 len -= ret;
353 data += ret;
354 } else if (ret == 0) { // Unexpected disconnection
355 return IntrRecvError::Disconnected;
356 } else { // Other error or blocking
357 int nErr = WSAGetLastError();
358 if (nErr == WSAEINPROGRESS || nErr == WSAEWOULDBLOCK || nErr == WSAEINVAL) {
359 if (!IsSelectableSocket(hSocket)) {
360 return IntrRecvError::NetworkError;
361 }
362 // Only wait at most maxWait milliseconds at a time, unless
363 // we're approaching the end of the specified total timeout
364 int timeout_ms = std::min(endTime - curTime, maxWait);
365 #ifdef USE_POLL
366 struct pollfd pollfd = {};
367 pollfd.fd = hSocket;
368 pollfd.events = POLLIN;
369 int nRet = poll(&pollfd, 1, timeout_ms);
370 #else
371 struct timeval tval = MillisToTimeval(timeout_ms);
372 fd_set fdset;
373 FD_ZERO(&fdset);
374 FD_SET(hSocket, &fdset);
375 int nRet = select(hSocket + 1, &fdset, nullptr, nullptr, &tval);
376 #endif
377 if (nRet == SOCKET_ERROR) {
378 return IntrRecvError::NetworkError;
379 }
380 } else {
381 return IntrRecvError::NetworkError;
382 }
383 }
384 if (interruptSocks5Recv)
385 return IntrRecvError::Interrupted;
386 curTime = GetTimeMillis();
387 }
388 return len == 0 ? IntrRecvError::OK : IntrRecvError::Timeout;
389 }
390
391 /** Credentials for proxy authentication */
392 struct ProxyCredentials
393 {
394 std::string username;
395 std::string password;
396 };
397
398 /** Convert SOCKS5 reply to an error message */
Socks5ErrorString(uint8_t err)399 static std::string Socks5ErrorString(uint8_t err)
400 {
401 switch(err) {
402 case SOCKS5Reply::GENFAILURE:
403 return "general failure";
404 case SOCKS5Reply::NOTALLOWED:
405 return "connection not allowed";
406 case SOCKS5Reply::NETUNREACHABLE:
407 return "network unreachable";
408 case SOCKS5Reply::HOSTUNREACHABLE:
409 return "host unreachable";
410 case SOCKS5Reply::CONNREFUSED:
411 return "connection refused";
412 case SOCKS5Reply::TTLEXPIRED:
413 return "TTL expired";
414 case SOCKS5Reply::CMDUNSUPPORTED:
415 return "protocol error";
416 case SOCKS5Reply::ATYPEUNSUPPORTED:
417 return "address type not supported";
418 default:
419 return "unknown";
420 }
421 }
422
423 /**
424 * Connect to a specified destination service through an already connected
425 * SOCKS5 proxy.
426 *
427 * @param strDest The destination fully-qualified domain name.
428 * @param port The destination port.
429 * @param auth The credentials with which to authenticate with the specified
430 * SOCKS5 proxy.
431 * @param hSocket The SOCKS5 proxy socket.
432 *
433 * @returns Whether or not the operation succeeded.
434 *
435 * @note The specified SOCKS5 proxy socket must already be connected to the
436 * SOCKS5 proxy.
437 *
438 * @see <a href="https://www.ietf.org/rfc/rfc1928.txt">RFC1928: SOCKS Protocol
439 * Version 5</a>
440 */
Socks5(const std::string & strDest,int port,const ProxyCredentials * auth,const SOCKET & hSocket)441 static bool Socks5(const std::string& strDest, int port, const ProxyCredentials *auth, const SOCKET& hSocket)
442 {
443 IntrRecvError recvr;
444 LogPrint(BCLog::NET, "SOCKS5 connecting %s\n", strDest);
445 if (strDest.size() > 255) {
446 return error("Hostname too long");
447 }
448 // Construct the version identifier/method selection message
449 std::vector<uint8_t> vSocks5Init;
450 vSocks5Init.push_back(SOCKSVersion::SOCKS5); // We want the SOCK5 protocol
451 if (auth) {
452 vSocks5Init.push_back(0x02); // 2 method identifiers follow...
453 vSocks5Init.push_back(SOCKS5Method::NOAUTH);
454 vSocks5Init.push_back(SOCKS5Method::USER_PASS);
455 } else {
456 vSocks5Init.push_back(0x01); // 1 method identifier follows...
457 vSocks5Init.push_back(SOCKS5Method::NOAUTH);
458 }
459 ssize_t ret = send(hSocket, (const char*)vSocks5Init.data(), vSocks5Init.size(), MSG_NOSIGNAL);
460 if (ret != (ssize_t)vSocks5Init.size()) {
461 return error("Error sending to proxy");
462 }
463 uint8_t pchRet1[2];
464 if ((recvr = InterruptibleRecv(pchRet1, 2, SOCKS5_RECV_TIMEOUT, hSocket)) != IntrRecvError::OK) {
465 LogPrintf("Socks5() connect to %s:%d failed: InterruptibleRecv() timeout or other failure\n", strDest, port);
466 return false;
467 }
468 if (pchRet1[0] != SOCKSVersion::SOCKS5) {
469 return error("Proxy failed to initialize");
470 }
471 if (pchRet1[1] == SOCKS5Method::USER_PASS && auth) {
472 // Perform username/password authentication (as described in RFC1929)
473 std::vector<uint8_t> vAuth;
474 vAuth.push_back(0x01); // Current (and only) version of user/pass subnegotiation
475 if (auth->username.size() > 255 || auth->password.size() > 255)
476 return error("Proxy username or password too long");
477 vAuth.push_back(auth->username.size());
478 vAuth.insert(vAuth.end(), auth->username.begin(), auth->username.end());
479 vAuth.push_back(auth->password.size());
480 vAuth.insert(vAuth.end(), auth->password.begin(), auth->password.end());
481 ret = send(hSocket, (const char*)vAuth.data(), vAuth.size(), MSG_NOSIGNAL);
482 if (ret != (ssize_t)vAuth.size()) {
483 return error("Error sending authentication to proxy");
484 }
485 LogPrint(BCLog::PROXY, "SOCKS5 sending proxy authentication %s:%s\n", auth->username, auth->password);
486 uint8_t pchRetA[2];
487 if ((recvr = InterruptibleRecv(pchRetA, 2, SOCKS5_RECV_TIMEOUT, hSocket)) != IntrRecvError::OK) {
488 return error("Error reading proxy authentication response");
489 }
490 if (pchRetA[0] != 0x01 || pchRetA[1] != 0x00) {
491 return error("Proxy authentication unsuccessful");
492 }
493 } else if (pchRet1[1] == SOCKS5Method::NOAUTH) {
494 // Perform no authentication
495 } else {
496 return error("Proxy requested wrong authentication method %02x", pchRet1[1]);
497 }
498 std::vector<uint8_t> vSocks5;
499 vSocks5.push_back(SOCKSVersion::SOCKS5); // VER protocol version
500 vSocks5.push_back(SOCKS5Command::CONNECT); // CMD CONNECT
501 vSocks5.push_back(0x00); // RSV Reserved must be 0
502 vSocks5.push_back(SOCKS5Atyp::DOMAINNAME); // ATYP DOMAINNAME
503 vSocks5.push_back(strDest.size()); // Length<=255 is checked at beginning of function
504 vSocks5.insert(vSocks5.end(), strDest.begin(), strDest.end());
505 vSocks5.push_back((port >> 8) & 0xFF);
506 vSocks5.push_back((port >> 0) & 0xFF);
507 ret = send(hSocket, (const char*)vSocks5.data(), vSocks5.size(), MSG_NOSIGNAL);
508 if (ret != (ssize_t)vSocks5.size()) {
509 return error("Error sending to proxy");
510 }
511 uint8_t pchRet2[4];
512 if ((recvr = InterruptibleRecv(pchRet2, 4, SOCKS5_RECV_TIMEOUT, hSocket)) != IntrRecvError::OK) {
513 if (recvr == IntrRecvError::Timeout) {
514 /* If a timeout happens here, this effectively means we timed out while connecting
515 * to the remote node. This is very common for Tor, so do not print an
516 * error message. */
517 return false;
518 } else {
519 return error("Error while reading proxy response");
520 }
521 }
522 if (pchRet2[0] != SOCKSVersion::SOCKS5) {
523 return error("Proxy failed to accept request");
524 }
525 if (pchRet2[1] != SOCKS5Reply::SUCCEEDED) {
526 // Failures to connect to a peer that are not proxy errors
527 LogPrintf("Socks5() connect to %s:%d failed: %s\n", strDest, port, Socks5ErrorString(pchRet2[1]));
528 return false;
529 }
530 if (pchRet2[2] != 0x00) { // Reserved field must be 0
531 return error("Error: malformed proxy response");
532 }
533 uint8_t pchRet3[256];
534 switch (pchRet2[3])
535 {
536 case SOCKS5Atyp::IPV4: recvr = InterruptibleRecv(pchRet3, 4, SOCKS5_RECV_TIMEOUT, hSocket); break;
537 case SOCKS5Atyp::IPV6: recvr = InterruptibleRecv(pchRet3, 16, SOCKS5_RECV_TIMEOUT, hSocket); break;
538 case SOCKS5Atyp::DOMAINNAME:
539 {
540 recvr = InterruptibleRecv(pchRet3, 1, SOCKS5_RECV_TIMEOUT, hSocket);
541 if (recvr != IntrRecvError::OK) {
542 return error("Error reading from proxy");
543 }
544 int nRecv = pchRet3[0];
545 recvr = InterruptibleRecv(pchRet3, nRecv, SOCKS5_RECV_TIMEOUT, hSocket);
546 break;
547 }
548 default: return error("Error: malformed proxy response");
549 }
550 if (recvr != IntrRecvError::OK) {
551 return error("Error reading from proxy");
552 }
553 if ((recvr = InterruptibleRecv(pchRet3, 2, SOCKS5_RECV_TIMEOUT, hSocket)) != IntrRecvError::OK) {
554 return error("Error reading from proxy");
555 }
556 LogPrint(BCLog::NET, "SOCKS5 connected %s\n", strDest);
557 return true;
558 }
559
560 /**
561 * Try to create a socket file descriptor with specific properties in the
562 * communications domain (address family) of the specified service.
563 *
564 * For details on the desired properties, see the inline comments in the source
565 * code.
566 */
CreateSocket(const CService & addrConnect)567 SOCKET CreateSocket(const CService &addrConnect)
568 {
569 // Create a sockaddr from the specified service.
570 struct sockaddr_storage sockaddr;
571 socklen_t len = sizeof(sockaddr);
572 if (!addrConnect.GetSockAddr((struct sockaddr*)&sockaddr, &len)) {
573 LogPrintf("Cannot create socket for %s: unsupported network\n", addrConnect.ToString());
574 return INVALID_SOCKET;
575 }
576
577 // Create a TCP socket in the address family of the specified service.
578 SOCKET hSocket = socket(((struct sockaddr*)&sockaddr)->sa_family, SOCK_STREAM, IPPROTO_TCP);
579 if (hSocket == INVALID_SOCKET)
580 return INVALID_SOCKET;
581
582 // Ensure that waiting for I/O on this socket won't result in undefined
583 // behavior.
584 if (!IsSelectableSocket(hSocket)) {
585 CloseSocket(hSocket);
586 LogPrintf("Cannot create connection: non-selectable socket created (fd >= FD_SETSIZE ?)\n");
587 return INVALID_SOCKET;
588 }
589
590 #ifdef SO_NOSIGPIPE
591 int set = 1;
592 // Set the no-sigpipe option on the socket for BSD systems, other UNIXes
593 // should use the MSG_NOSIGNAL flag for every send.
594 setsockopt(hSocket, SOL_SOCKET, SO_NOSIGPIPE, (void*)&set, sizeof(int));
595 #endif
596
597 // Set the no-delay option (disable Nagle's algorithm) on the TCP socket.
598 SetSocketNoDelay(hSocket);
599
600 // Set the non-blocking option on the socket.
601 if (!SetSocketNonBlocking(hSocket, true)) {
602 CloseSocket(hSocket);
603 LogPrintf("CreateSocket: Setting socket to non-blocking failed, error %s\n", NetworkErrorString(WSAGetLastError()));
604 }
605 return hSocket;
606 }
607
608 template<typename... Args>
LogConnectFailure(bool manual_connection,const char * fmt,const Args &...args)609 static void LogConnectFailure(bool manual_connection, const char* fmt, const Args&... args) {
610 std::string error_message = tfm::format(fmt, args...);
611 if (manual_connection) {
612 LogPrintf("%s\n", error_message);
613 } else {
614 LogPrint(BCLog::NET, "%s\n", error_message);
615 }
616 }
617
618 /**
619 * Try to connect to the specified service on the specified socket.
620 *
621 * @param addrConnect The service to which to connect.
622 * @param hSocket The socket on which to connect.
623 * @param nTimeout Wait this many milliseconds for the connection to be
624 * established.
625 * @param manual_connection Whether or not the connection was manually requested
626 * (e.g. through the addnode RPC)
627 *
628 * @returns Whether or not a connection was successfully made.
629 */
ConnectSocketDirectly(const CService & addrConnect,const SOCKET & hSocket,int nTimeout,bool manual_connection)630 bool ConnectSocketDirectly(const CService &addrConnect, const SOCKET& hSocket, int nTimeout, bool manual_connection)
631 {
632 // Create a sockaddr from the specified service.
633 struct sockaddr_storage sockaddr;
634 socklen_t len = sizeof(sockaddr);
635 if (hSocket == INVALID_SOCKET) {
636 LogPrintf("Cannot connect to %s: invalid socket\n", addrConnect.ToString());
637 return false;
638 }
639 if (!addrConnect.GetSockAddr((struct sockaddr*)&sockaddr, &len)) {
640 LogPrintf("Cannot connect to %s: unsupported network\n", addrConnect.ToString());
641 return false;
642 }
643
644 // Connect to the addrConnect service on the hSocket socket.
645 if (connect(hSocket, (struct sockaddr*)&sockaddr, len) == SOCKET_ERROR)
646 {
647 if (!IsSelectableSocket(hSocket)) {
648 LogPrintf("Cannot create connection: non-selectable socket created (fd >= FD_SETSIZE ?)\n");
649 return false;
650 }
651 int nErr = WSAGetLastError();
652 // WSAEINVAL is here because some legacy version of winsock uses it
653 if (nErr == WSAEINPROGRESS || nErr == WSAEWOULDBLOCK || nErr == WSAEINVAL)
654 {
655 // Connection didn't actually fail, but is being established
656 // asynchronously. Thus, use async I/O api (select/poll)
657 // synchronously to check for successful connection with a timeout.
658 #ifdef USE_POLL
659 struct pollfd pollfd = {};
660 pollfd.fd = hSocket;
661 pollfd.events = POLLIN | POLLOUT;
662 int nRet = poll(&pollfd, 1, nTimeout);
663 #else
664 struct timeval timeout = MillisToTimeval(nTimeout);
665 fd_set fdset;
666 FD_ZERO(&fdset);
667 FD_SET(hSocket, &fdset);
668 int nRet = select(hSocket + 1, nullptr, &fdset, nullptr, &timeout);
669 #endif
670 // Upon successful completion, both select and poll return the total
671 // number of file descriptors that have been selected. A value of 0
672 // indicates that the call timed out and no file descriptors have
673 // been selected.
674 if (nRet == 0)
675 {
676 LogPrint(BCLog::NET, "connection to %s timeout\n", addrConnect.ToString());
677 return false;
678 }
679 if (nRet == SOCKET_ERROR)
680 {
681 LogPrintf("select() for %s failed: %s\n", addrConnect.ToString(), NetworkErrorString(WSAGetLastError()));
682 return false;
683 }
684
685 // Even if the select/poll was successful, the connect might not
686 // have been successful. The reason for this failure is hidden away
687 // in the SO_ERROR for the socket in modern systems. We read it into
688 // nRet here.
689 socklen_t nRetSize = sizeof(nRet);
690 if (getsockopt(hSocket, SOL_SOCKET, SO_ERROR, (sockopt_arg_type)&nRet, &nRetSize) == SOCKET_ERROR)
691 {
692 LogPrintf("getsockopt() for %s failed: %s\n", addrConnect.ToString(), NetworkErrorString(WSAGetLastError()));
693 return false;
694 }
695 if (nRet != 0)
696 {
697 LogConnectFailure(manual_connection, "connect() to %s failed after select(): %s", addrConnect.ToString(), NetworkErrorString(nRet));
698 return false;
699 }
700 }
701 #ifdef WIN32
702 else if (WSAGetLastError() != WSAEISCONN)
703 #else
704 else
705 #endif
706 {
707 LogConnectFailure(manual_connection, "connect() to %s failed: %s", addrConnect.ToString(), NetworkErrorString(WSAGetLastError()));
708 return false;
709 }
710 }
711 return true;
712 }
713
SetProxy(enum Network net,const proxyType & addrProxy)714 bool SetProxy(enum Network net, const proxyType &addrProxy) {
715 assert(net >= 0 && net < NET_MAX);
716 if (!addrProxy.IsValid())
717 return false;
718 LOCK(cs_proxyInfos);
719 proxyInfo[net] = addrProxy;
720 return true;
721 }
722
GetProxy(enum Network net,proxyType & proxyInfoOut)723 bool GetProxy(enum Network net, proxyType &proxyInfoOut) {
724 assert(net >= 0 && net < NET_MAX);
725 LOCK(cs_proxyInfos);
726 if (!proxyInfo[net].IsValid())
727 return false;
728 proxyInfoOut = proxyInfo[net];
729 return true;
730 }
731
732 /**
733 * Set the name proxy to use for all connections to nodes specified by a
734 * hostname. After setting this proxy, connecting to a node specified by a
735 * hostname won't result in a local lookup of said hostname, rather, connect to
736 * the node by asking the name proxy for a proxy connection to the hostname,
737 * effectively delegating the hostname lookup to the specified proxy.
738 *
739 * This delegation increases privacy for those who set the name proxy as they no
740 * longer leak their external hostname queries to their DNS servers.
741 *
742 * @returns Whether or not the operation succeeded.
743 *
744 * @note SOCKS5's support for UDP-over-SOCKS5 has been considered, but no SOCK5
745 * server in common use (most notably Tor) actually implements UDP
746 * support, and a DNS resolver is beyond the scope of this project.
747 */
SetNameProxy(const proxyType & addrProxy)748 bool SetNameProxy(const proxyType &addrProxy) {
749 if (!addrProxy.IsValid())
750 return false;
751 LOCK(cs_proxyInfos);
752 nameProxy = addrProxy;
753 return true;
754 }
755
GetNameProxy(proxyType & nameProxyOut)756 bool GetNameProxy(proxyType &nameProxyOut) {
757 LOCK(cs_proxyInfos);
758 if(!nameProxy.IsValid())
759 return false;
760 nameProxyOut = nameProxy;
761 return true;
762 }
763
HaveNameProxy()764 bool HaveNameProxy() {
765 LOCK(cs_proxyInfos);
766 return nameProxy.IsValid();
767 }
768
IsProxy(const CNetAddr & addr)769 bool IsProxy(const CNetAddr &addr) {
770 LOCK(cs_proxyInfos);
771 for (int i = 0; i < NET_MAX; i++) {
772 if (addr == static_cast<CNetAddr>(proxyInfo[i].proxy))
773 return true;
774 }
775 return false;
776 }
777
778 /**
779 * Connect to a specified destination service through a SOCKS5 proxy by first
780 * connecting to the SOCKS5 proxy.
781 *
782 * @param proxy The SOCKS5 proxy.
783 * @param strDest The destination service to which to connect.
784 * @param port The destination port.
785 * @param hSocket The socket on which to connect to the SOCKS5 proxy.
786 * @param nTimeout Wait this many milliseconds for the connection to the SOCKS5
787 * proxy to be established.
788 * @param[out] outProxyConnectionFailed Whether or not the connection to the
789 * SOCKS5 proxy failed.
790 *
791 * @returns Whether or not the operation succeeded.
792 */
ConnectThroughProxy(const proxyType & proxy,const std::string & strDest,int port,const SOCKET & hSocket,int nTimeout,bool & outProxyConnectionFailed)793 bool ConnectThroughProxy(const proxyType &proxy, const std::string& strDest, int port, const SOCKET& hSocket, int nTimeout, bool& outProxyConnectionFailed)
794 {
795 // first connect to proxy server
796 if (!ConnectSocketDirectly(proxy.proxy, hSocket, nTimeout, true)) {
797 outProxyConnectionFailed = true;
798 return false;
799 }
800 // do socks negotiation
801 if (proxy.randomize_credentials) {
802 ProxyCredentials random_auth;
803 static std::atomic_int counter(0);
804 random_auth.username = random_auth.password = strprintf("%i", counter++);
805 if (!Socks5(strDest, (unsigned short)port, &random_auth, hSocket)) {
806 return false;
807 }
808 } else {
809 if (!Socks5(strDest, (unsigned short)port, 0, hSocket)) {
810 return false;
811 }
812 }
813 return true;
814 }
815
816 /**
817 * Parse and resolve a specified subnet string into the appropriate internal
818 * representation.
819 *
820 * @param strSubnet A string representation of a subnet of the form `network
821 * address [ "/", ( CIDR-style suffix | netmask ) ]`(e.g.
822 * `2001:db8::/32`, `192.0.2.0/255.255.255.0`, or `8.8.8.8`).
823 * @param ret The resulting internal representation of a subnet.
824 *
825 * @returns Whether the operation succeeded or not.
826 */
LookupSubNet(const std::string & strSubnet,CSubNet & ret)827 bool LookupSubNet(const std::string& strSubnet, CSubNet& ret)
828 {
829 if (!ValidAsCString(strSubnet)) {
830 return false;
831 }
832 size_t slash = strSubnet.find_last_of('/');
833 std::vector<CNetAddr> vIP;
834
835 std::string strAddress = strSubnet.substr(0, slash);
836 // TODO: Use LookupHost(const std::string&, CNetAddr&, bool) instead to just get
837 // one CNetAddr.
838 if (LookupHost(strAddress, vIP, 1, false))
839 {
840 CNetAddr network = vIP[0];
841 if (slash != strSubnet.npos)
842 {
843 std::string strNetmask = strSubnet.substr(slash + 1);
844 int32_t n;
845 if (ParseInt32(strNetmask, &n)) {
846 // If valid number, assume CIDR variable-length subnet masking
847 ret = CSubNet(network, n);
848 return ret.IsValid();
849 }
850 else // If not a valid number, try full netmask syntax
851 {
852 // Never allow lookup for netmask
853 if (LookupHost(strNetmask, vIP, 1, false)) {
854 ret = CSubNet(network, vIP[0]);
855 return ret.IsValid();
856 }
857 }
858 }
859 else
860 {
861 ret = CSubNet(network);
862 return ret.IsValid();
863 }
864 }
865 return false;
866 }
867
868 #ifdef WIN32
NetworkErrorString(int err)869 std::string NetworkErrorString(int err)
870 {
871 wchar_t buf[256];
872 buf[0] = 0;
873 if(FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_MAX_WIDTH_MASK,
874 nullptr, err, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
875 buf, ARRAYSIZE(buf), nullptr))
876 {
877 return strprintf("%s (%d)", std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>,wchar_t>().to_bytes(buf), err);
878 }
879 else
880 {
881 return strprintf("Unknown error (%d)", err);
882 }
883 }
884 #else
NetworkErrorString(int err)885 std::string NetworkErrorString(int err)
886 {
887 char buf[256];
888 buf[0] = 0;
889 /* Too bad there are two incompatible implementations of the
890 * thread-safe strerror. */
891 const char *s;
892 #ifdef STRERROR_R_CHAR_P /* GNU variant can return a pointer outside the passed buffer */
893 s = strerror_r(err, buf, sizeof(buf));
894 #else /* POSIX variant always returns message in buffer */
895 s = buf;
896 if (strerror_r(err, buf, sizeof(buf)))
897 buf[0] = 0;
898 #endif
899 return strprintf("%s (%d)", s, err);
900 }
901 #endif
902
CloseSocket(SOCKET & hSocket)903 bool CloseSocket(SOCKET& hSocket)
904 {
905 if (hSocket == INVALID_SOCKET)
906 return false;
907 #ifdef WIN32
908 int ret = closesocket(hSocket);
909 #else
910 int ret = close(hSocket);
911 #endif
912 if (ret) {
913 LogPrintf("Socket close failed: %d. Error: %s\n", hSocket, NetworkErrorString(WSAGetLastError()));
914 }
915 hSocket = INVALID_SOCKET;
916 return ret != SOCKET_ERROR;
917 }
918
SetSocketNonBlocking(const SOCKET & hSocket,bool fNonBlocking)919 bool SetSocketNonBlocking(const SOCKET& hSocket, bool fNonBlocking)
920 {
921 if (fNonBlocking) {
922 #ifdef WIN32
923 u_long nOne = 1;
924 if (ioctlsocket(hSocket, FIONBIO, &nOne) == SOCKET_ERROR) {
925 #else
926 int fFlags = fcntl(hSocket, F_GETFL, 0);
927 if (fcntl(hSocket, F_SETFL, fFlags | O_NONBLOCK) == SOCKET_ERROR) {
928 #endif
929 return false;
930 }
931 } else {
932 #ifdef WIN32
933 u_long nZero = 0;
934 if (ioctlsocket(hSocket, FIONBIO, &nZero) == SOCKET_ERROR) {
935 #else
936 int fFlags = fcntl(hSocket, F_GETFL, 0);
937 if (fcntl(hSocket, F_SETFL, fFlags & ~O_NONBLOCK) == SOCKET_ERROR) {
938 #endif
939 return false;
940 }
941 }
942
943 return true;
944 }
945
946 bool SetSocketNoDelay(const SOCKET& hSocket)
947 {
948 int set = 1;
949 int rc = setsockopt(hSocket, IPPROTO_TCP, TCP_NODELAY, (const char*)&set, sizeof(int));
950 return rc == 0;
951 }
952
953 void InterruptSocks5(bool interrupt)
954 {
955 interruptSocks5Recv = interrupt;
956 }
957