Bitcoin ABC 0.30.5
P2P Digital Currency
netbase.cpp
Go to the documentation of this file.
1// Copyright (c) 2009-2010 Satoshi Nakamoto
2// Copyright (c) 2009-2016 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 <compat.h>
9#include <logging.h>
10#include <sync.h>
11#include <tinyformat.h>
12#include <util/sock.h>
13#include <util/strencodings.h>
14#include <util/string.h>
15#include <util/time.h>
16
17#include <atomic>
18#include <chrono>
19#include <cstdint>
20#include <functional>
21#include <memory>
22
23#ifndef WIN32
24#include <fcntl.h>
25#else
26#include <codecvt>
27#endif
28
29#ifdef USE_POLL
30#include <poll.h>
31#endif
32
33// Settings
36static proxyType nameProxy GUARDED_BY(g_proxyinfo_mutex);
39
40// Need ample time for negotiation for very slow proxies such as Tor
41// (milliseconds)
42
43int g_socks5_recv_timeout = 20 * 1000;
44static std::atomic<bool> interruptSocks5Recv(false);
45
46std::vector<CNetAddr> WrappedGetAddrInfo(const std::string &name,
47 bool allow_lookup) {
48 addrinfo ai_hint{};
49 // We want a TCP port, which is a streaming socket type
50 ai_hint.ai_socktype = SOCK_STREAM;
51 ai_hint.ai_protocol = IPPROTO_TCP;
52 // We don't care which address family (IPv4 or IPv6) is returned
53 ai_hint.ai_family = AF_UNSPEC;
54 // If we allow lookups of hostnames, use the AI_ADDRCONFIG flag to only
55 // return addresses whose family we have an address configured for.
56 //
57 // If we don't allow lookups, then use the AI_NUMERICHOST flag for
58 // getaddrinfo to only decode numerical network addresses and suppress
59 // hostname lookups.
60 ai_hint.ai_flags = allow_lookup ? AI_ADDRCONFIG : AI_NUMERICHOST;
61
62 addrinfo *ai_res{nullptr};
63 const int n_err{getaddrinfo(name.c_str(), nullptr, &ai_hint, &ai_res)};
64 if (n_err != 0) {
65 return {};
66 }
67
68 // Traverse the linked list starting with ai_trav.
69 addrinfo *ai_trav{ai_res};
70 std::vector<CNetAddr> resolved_addresses;
71 while (ai_trav != nullptr) {
72 if (ai_trav->ai_family == AF_INET) {
73 assert(ai_trav->ai_addrlen >= sizeof(sockaddr_in));
74 resolved_addresses.emplace_back(
75 reinterpret_cast<sockaddr_in *>(ai_trav->ai_addr)->sin_addr);
76 }
77 if (ai_trav->ai_family == AF_INET6) {
78 assert(ai_trav->ai_addrlen >= sizeof(sockaddr_in6));
79 const sockaddr_in6 *s6{
80 reinterpret_cast<sockaddr_in6 *>(ai_trav->ai_addr)};
81 resolved_addresses.emplace_back(s6->sin6_addr, s6->sin6_scope_id);
82 }
83 ai_trav = ai_trav->ai_next;
84 }
85 freeaddrinfo(ai_res);
86
87 return resolved_addresses;
88}
89
91
92enum Network ParseNetwork(const std::string &net_in) {
93 std::string net = ToLower(net_in);
94 if (net == "ipv4") {
95 return NET_IPV4;
96 }
97 if (net == "ipv6") {
98 return NET_IPV6;
99 }
100 if (net == "onion") {
101 return NET_ONION;
102 }
103 if (net == "tor") {
104 LogPrintf("Warning: net name 'tor' is deprecated and will be removed "
105 "in the future. You should use 'onion' instead.\n");
106 return NET_ONION;
107 }
108 if (net == "i2p") {
109 return NET_I2P;
110 }
111 return NET_UNROUTABLE;
112}
113
114std::string GetNetworkName(enum Network net) {
115 switch (net) {
116 case NET_UNROUTABLE:
117 return "not_publicly_routable";
118 case NET_IPV4:
119 return "ipv4";
120 case NET_IPV6:
121 return "ipv6";
122 case NET_ONION:
123 return "onion";
124 case NET_I2P:
125 return "i2p";
126 case NET_CJDNS:
127 return "cjdns";
128 case NET_INTERNAL:
129 return "internal";
130 case NET_MAX:
131 assert(false);
132 } // no default case, so the compiler can warn about missing cases
133
134 assert(false);
135}
136
137std::vector<std::string> GetNetworkNames(bool append_unroutable) {
138 std::vector<std::string> names;
139 for (int n = 0; n < NET_MAX; ++n) {
140 const enum Network network { static_cast<Network>(n) };
141 if (network == NET_UNROUTABLE || network == NET_CJDNS ||
142 network == NET_INTERNAL) {
143 continue;
144 }
145 names.emplace_back(GetNetworkName(network));
146 }
147 if (append_unroutable) {
148 names.emplace_back(GetNetworkName(NET_UNROUTABLE));
149 }
150 return names;
151}
152
153static bool LookupIntern(const std::string &name, std::vector<CNetAddr> &vIP,
154 unsigned int nMaxSolutions, bool fAllowLookup,
155 DNSLookupFn dns_lookup_function) {
156 vIP.clear();
157
158 if (!ContainsNoNUL(name)) {
159 return false;
160 }
161
162 {
163 CNetAddr addr;
164 // From our perspective, onion addresses are not hostnames but rather
165 // direct encodings of CNetAddr much like IPv4 dotted-decimal notation
166 // or IPv6 colon-separated hextet notation. Since we can't use
167 // getaddrinfo to decode them and it wouldn't make sense to resolve
168 // them, we return a network address representing it instead. See
169 // CNetAddr::SetSpecial(const std::string&) for more details.
170 if (addr.SetSpecial(name)) {
171 vIP.push_back(addr);
172 return true;
173 }
174 }
175
176 for (const CNetAddr &resolved : dns_lookup_function(name, fAllowLookup)) {
177 if (nMaxSolutions > 0 && vIP.size() >= nMaxSolutions) {
178 break;
179 }
180
181 // Never allow resolving to an internal address. Consider any such
182 // result invalid.
183 if (!resolved.IsInternal()) {
184 vIP.push_back(resolved);
185 }
186 }
187
188 return (vIP.size() > 0);
189}
190
191bool LookupHost(const std::string &name, std::vector<CNetAddr> &vIP,
192 unsigned int nMaxSolutions, bool fAllowLookup,
193 DNSLookupFn dns_lookup_function) {
194 if (!ContainsNoNUL(name)) {
195 return false;
196 }
197 std::string strHost = name;
198 if (strHost.empty()) {
199 return false;
200 }
201 if (strHost.front() == '[' && strHost.back() == ']') {
202 strHost = strHost.substr(1, strHost.size() - 2);
203 }
204
205 return LookupIntern(strHost, vIP, nMaxSolutions, fAllowLookup,
206 dns_lookup_function);
207}
208
209bool LookupHost(const std::string &name, CNetAddr &addr, bool fAllowLookup,
210 DNSLookupFn dns_lookup_function) {
211 if (!ContainsNoNUL(name)) {
212 return false;
213 }
214 std::vector<CNetAddr> vIP;
215 LookupHost(name, vIP, 1, fAllowLookup, dns_lookup_function);
216 if (vIP.empty()) {
217 return false;
218 }
219 addr = vIP.front();
220 return true;
221}
222
223bool Lookup(const std::string &name, std::vector<CService> &vAddr,
224 uint16_t portDefault, bool fAllowLookup, unsigned int nMaxSolutions,
225 DNSLookupFn dns_lookup_function) {
226 if (name.empty() || !ContainsNoNUL(name)) {
227 return false;
228 }
229 uint16_t port{portDefault};
230 std::string hostname;
231 SplitHostPort(name, port, hostname);
232
233 std::vector<CNetAddr> vIP;
234 bool fRet = LookupIntern(hostname, vIP, nMaxSolutions, fAllowLookup,
235 dns_lookup_function);
236 if (!fRet) {
237 return false;
238 }
239 vAddr.resize(vIP.size());
240 for (unsigned int i = 0; i < vIP.size(); i++) {
241 vAddr[i] = CService(vIP[i], port);
242 }
243 return true;
244}
245
246bool Lookup(const std::string &name, CService &addr, uint16_t portDefault,
247 bool fAllowLookup, DNSLookupFn dns_lookup_function) {
248 if (!ContainsNoNUL(name)) {
249 return false;
250 }
251 std::vector<CService> vService;
252 bool fRet = Lookup(name, vService, portDefault, fAllowLookup, 1,
253 dns_lookup_function);
254 if (!fRet) {
255 return false;
256 }
257 addr = vService[0];
258 return true;
259}
260
261CService LookupNumeric(const std::string &name, uint16_t portDefault,
262 DNSLookupFn dns_lookup_function) {
263 if (!ContainsNoNUL(name)) {
264 return {};
265 }
266 CService addr;
267 // "1.2:345" will fail to resolve the ip, but will still set the port.
268 // If the ip fails to resolve, re-init the result.
269 if (!Lookup(name, addr, portDefault, false, dns_lookup_function)) {
270 addr = CService();
271 }
272 return addr;
273}
274
276enum SOCKSVersion : uint8_t { SOCKS4 = 0x04, SOCKS5 = 0x05 };
277
279enum SOCKS5Method : uint8_t {
280 NOAUTH = 0x00,
281 GSSAPI = 0x01,
282 USER_PASS = 0x02,
284};
285
287enum SOCKS5Command : uint8_t {
288 CONNECT = 0x01,
289 BIND = 0x02,
290 UDP_ASSOCIATE = 0x03
292
294enum SOCKS5Reply : uint8_t {
295 SUCCEEDED = 0x00,
296 GENFAILURE = 0x01,
297 NOTALLOWED = 0x02,
300 CONNREFUSED = 0x05,
301 TTLEXPIRED = 0x06,
304};
305
307enum SOCKS5Atyp : uint8_t {
308 IPV4 = 0x01,
310 IPV6 = 0x04,
311};
312
314enum class IntrRecvError {
315 OK,
316 Timeout,
320};
321
340static IntrRecvError InterruptibleRecv(uint8_t *data, size_t len, int timeout,
341 const Sock &sock) {
342 int64_t curTime = GetTimeMillis();
343 int64_t endTime = curTime + timeout;
344 while (len > 0 && curTime < endTime) {
345 // Optimistically try the recv first
346 ssize_t ret = sock.Recv(data, len, 0);
347 if (ret > 0) {
348 len -= ret;
349 data += ret;
350 } else if (ret == 0) {
351 // Unexpected disconnection
353 } else {
354 // Other error or blocking
355 int nErr = WSAGetLastError();
356 if (nErr == WSAEINPROGRESS || nErr == WSAEWOULDBLOCK ||
357 nErr == WSAEINVAL) {
358 // Only wait at most MAX_WAIT_FOR_IO at a time, unless
359 // we're approaching the end of the specified total timeout
360 const auto remaining =
361 std::chrono::milliseconds{endTime - curTime};
362 const auto timeout_ = std::min(
363 remaining, std::chrono::milliseconds{MAX_WAIT_FOR_IO});
364 if (!sock.Wait(timeout_, Sock::RECV)) {
366 }
367 } else {
369 }
370 }
373 }
374 curTime = GetTimeMillis();
375 }
376 return len == 0 ? IntrRecvError::OK : IntrRecvError::Timeout;
377}
378
380static std::string Socks5ErrorString(uint8_t err) {
381 switch (err) {
383 return "general failure";
385 return "connection not allowed";
387 return "network unreachable";
389 return "host unreachable";
391 return "connection refused";
393 return "TTL expired";
395 return "protocol error";
397 return "address type not supported";
398 default:
399 return "unknown";
400 }
401}
402
421bool Socks5(const std::string &strDest, uint16_t port,
422 const ProxyCredentials *auth, const Sock &sock) {
423 IntrRecvError recvr;
424 LogPrint(BCLog::NET, "SOCKS5 connecting %s\n", strDest);
425 if (strDest.size() > 255) {
426 return error("Hostname too long");
427 }
428 // Construct the version identifier/method selection message
429 std::vector<uint8_t> vSocks5Init;
430 // We want the SOCK5 protocol
431 vSocks5Init.push_back(SOCKSVersion::SOCKS5);
432 if (auth) {
433 // 2 method identifiers follow...
434 vSocks5Init.push_back(0x02);
435 vSocks5Init.push_back(SOCKS5Method::NOAUTH);
436 vSocks5Init.push_back(SOCKS5Method::USER_PASS);
437 } else {
438 // 1 method identifier follows...
439 vSocks5Init.push_back(0x01);
440 vSocks5Init.push_back(SOCKS5Method::NOAUTH);
441 }
442 ssize_t ret =
443 sock.Send(vSocks5Init.data(), vSocks5Init.size(), MSG_NOSIGNAL);
444 if (ret != (ssize_t)vSocks5Init.size()) {
445 return error("Error sending to proxy");
446 }
447 uint8_t pchRet1[2];
448 if ((recvr = InterruptibleRecv(pchRet1, 2, g_socks5_recv_timeout, sock)) !=
450 LogPrintf("Socks5() connect to %s:%d failed: InterruptibleRecv() "
451 "timeout or other failure\n",
452 strDest, port);
453 return false;
454 }
455 if (pchRet1[0] != SOCKSVersion::SOCKS5) {
456 return error("Proxy failed to initialize");
457 }
458 if (pchRet1[1] == SOCKS5Method::USER_PASS && auth) {
459 // Perform username/password authentication (as described in RFC1929)
460 std::vector<uint8_t> vAuth;
461 // Current (and only) version of user/pass subnegotiation
462 vAuth.push_back(0x01);
463 if (auth->username.size() > 255 || auth->password.size() > 255) {
464 return error("Proxy username or password too long");
465 }
466 vAuth.push_back(auth->username.size());
467 vAuth.insert(vAuth.end(), auth->username.begin(), auth->username.end());
468 vAuth.push_back(auth->password.size());
469 vAuth.insert(vAuth.end(), auth->password.begin(), auth->password.end());
470 ret = sock.Send(vAuth.data(), vAuth.size(), MSG_NOSIGNAL);
471 if (ret != (ssize_t)vAuth.size()) {
472 return error("Error sending authentication to proxy");
473 }
474 LogPrint(BCLog::PROXY, "SOCKS5 sending proxy authentication %s:%s\n",
475 auth->username, auth->password);
476 uint8_t pchRetA[2];
477 if ((recvr = InterruptibleRecv(pchRetA, 2, g_socks5_recv_timeout,
478 sock)) != IntrRecvError::OK) {
479 return error("Error reading proxy authentication response");
480 }
481 if (pchRetA[0] != 0x01 || pchRetA[1] != 0x00) {
482 return error("Proxy authentication unsuccessful");
483 }
484 } else if (pchRet1[1] == SOCKS5Method::NOAUTH) {
485 // Perform no authentication
486 } else {
487 return error("Proxy requested wrong authentication method %02x",
488 pchRet1[1]);
489 }
490 std::vector<uint8_t> vSocks5;
491 // VER protocol version
492 vSocks5.push_back(SOCKSVersion::SOCKS5);
493 // CMD CONNECT
494 vSocks5.push_back(SOCKS5Command::CONNECT);
495 // RSV Reserved must be 0
496 vSocks5.push_back(0x00);
497 // ATYP DOMAINNAME
498 vSocks5.push_back(SOCKS5Atyp::DOMAINNAME);
499 // Length<=255 is checked at beginning of function
500 vSocks5.push_back(strDest.size());
501 vSocks5.insert(vSocks5.end(), strDest.begin(), strDest.end());
502 vSocks5.push_back((port >> 8) & 0xFF);
503 vSocks5.push_back((port >> 0) & 0xFF);
504 ret = sock.Send(vSocks5.data(), vSocks5.size(), MSG_NOSIGNAL);
505 if (ret != (ssize_t)vSocks5.size()) {
506 return error("Error sending to proxy");
507 }
508 uint8_t pchRet2[4];
509 if ((recvr = InterruptibleRecv(pchRet2, 4, g_socks5_recv_timeout, sock)) !=
511 if (recvr == IntrRecvError::Timeout) {
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,
528 Socks5ErrorString(pchRet2[1]));
529 return false;
530 }
531 // Reserved field must be 0
532 if (pchRet2[2] != 0x00) {
533 return error("Error: malformed proxy response");
534 }
535 uint8_t pchRet3[256];
536 switch (pchRet2[3]) {
537 case SOCKS5Atyp::IPV4:
538 recvr = InterruptibleRecv(pchRet3, 4, g_socks5_recv_timeout, sock);
539 break;
540 case SOCKS5Atyp::IPV6:
541 recvr = InterruptibleRecv(pchRet3, 16, g_socks5_recv_timeout, sock);
542 break;
544 recvr = InterruptibleRecv(pchRet3, 1, g_socks5_recv_timeout, sock);
545 if (recvr != IntrRecvError::OK) {
546 return error("Error reading from proxy");
547 }
548 int nRecv = pchRet3[0];
549 recvr =
550 InterruptibleRecv(pchRet3, nRecv, g_socks5_recv_timeout, sock);
551 break;
552 }
553 default:
554 return error("Error: malformed proxy response");
555 }
556 if (recvr != IntrRecvError::OK) {
557 return error("Error reading from proxy");
558 }
559 if ((recvr = InterruptibleRecv(pchRet3, 2, g_socks5_recv_timeout, sock)) !=
561 return error("Error reading from proxy");
562 }
563 LogPrint(BCLog::NET, "SOCKS5 connected %s\n", strDest);
564 return true;
565}
566
567std::unique_ptr<Sock> CreateSockTCP(const CService &address_family) {
568 // Create a sockaddr from the specified service.
569 struct sockaddr_storage sockaddr;
570 socklen_t len = sizeof(sockaddr);
571 if (!address_family.GetSockAddr((struct sockaddr *)&sockaddr, &len)) {
572 LogPrintf("Cannot create socket for %s: unsupported network\n",
573 address_family.ToString());
574 return nullptr;
575 }
576
577 // Create a TCP socket in the address family of the specified service.
578 SOCKET hSocket = socket(((struct sockaddr *)&sockaddr)->sa_family,
579 SOCK_STREAM, IPPROTO_TCP);
580 if (hSocket == INVALID_SOCKET) {
581 return nullptr;
582 }
583
584 // Ensure that waiting for I/O on this socket won't result in undefined
585 // behavior.
586 if (!IsSelectableSocket(hSocket)) {
587 CloseSocket(hSocket);
588 LogPrintf("Cannot create connection: non-selectable socket created (fd "
589 ">= FD_SETSIZE ?)\n");
590 return nullptr;
591 }
592
593#ifdef SO_NOSIGPIPE
594 int set = 1;
595 // Set the no-sigpipe option on the socket for BSD systems, other UNIXes
596 // should use the MSG_NOSIGNAL flag for every send.
597 setsockopt(hSocket, SOL_SOCKET, SO_NOSIGPIPE, (sockopt_arg_type)&set,
598 sizeof(int));
599#endif
600
601 // Set the no-delay option (disable Nagle's algorithm) on the TCP socket.
602 SetSocketNoDelay(hSocket);
603
604 // Set the non-blocking option on the socket.
605 if (!SetSocketNonBlocking(hSocket, true)) {
606 CloseSocket(hSocket);
607 LogPrintf("CreateSocket: Setting socket to non-blocking "
608 "failed, error %s\n",
610 return nullptr;
611 }
612 return std::make_unique<Sock>(hSocket);
613}
614
615std::function<std::unique_ptr<Sock>(const CService &)> CreateSock =
617
618template <typename... Args>
619static void LogConnectFailure(bool manual_connection, const char *fmt,
620 const Args &...args) {
621 std::string error_message = tfm::format(fmt, args...);
622 if (manual_connection) {
623 LogPrintf("%s\n", error_message);
624 } else {
625 LogPrint(BCLog::NET, "%s\n", error_message);
626 }
627}
628
629bool ConnectSocketDirectly(const CService &addrConnect, const Sock &sock,
630 int nTimeout, bool manual_connection) {
631 // Create a sockaddr from the specified service.
632 struct sockaddr_storage sockaddr;
633 socklen_t len = sizeof(sockaddr);
634 if (sock.Get() == INVALID_SOCKET) {
635 LogPrintf("Cannot connect to %s: invalid socket\n",
636 addrConnect.ToString());
637 return false;
638 }
639 if (!addrConnect.GetSockAddr((struct sockaddr *)&sockaddr, &len)) {
640 LogPrintf("Cannot connect to %s: unsupported network\n",
641 addrConnect.ToString());
642 return false;
643 }
644
645 // Connect to the addrConnect service on the hSocket socket.
646 if (sock.Connect(reinterpret_cast<struct sockaddr *>(&sockaddr), len) ==
647 SOCKET_ERROR) {
648 int nErr = WSAGetLastError();
649 // WSAEINVAL is here because some legacy version of winsock uses it
650 if (nErr == WSAEINPROGRESS || nErr == WSAEWOULDBLOCK ||
651 nErr == WSAEINVAL) {
652 // Connection didn't actually fail, but is being established
653 // asynchronously. Thus, use async I/O api (select/poll)
654 // synchronously to check for successful connection with a timeout.
655 const Sock::Event requested = Sock::RECV | Sock::SEND;
656 Sock::Event occurred;
657 if (!sock.Wait(std::chrono::milliseconds{nTimeout}, requested,
658 &occurred)) {
659 LogPrintf("wait for connect to %s failed: %s\n",
660 addrConnect.ToString(),
662 return false;
663 } else if (occurred == 0) {
664 LogPrint(BCLog::NET, "connection attempt to %s timed out\n",
665 addrConnect.ToString());
666 return false;
667 }
668
669 // Even if the wait was successful, the connect might not
670 // have been successful. The reason for this failure is hidden away
671 // in the SO_ERROR for the socket in modern systems. We read it into
672 // sockerr here.
673 int sockerr;
674 socklen_t sockerr_len = sizeof(sockerr);
675 if (sock.GetSockOpt(SOL_SOCKET, SO_ERROR,
676 (sockopt_arg_type)&sockerr,
677 &sockerr_len) == SOCKET_ERROR) {
678 LogPrintf("getsockopt() for %s failed: %s\n",
679 addrConnect.ToString(),
681 return false;
682 }
683 if (sockerr != 0) {
685 manual_connection, "connect() to %s failed after wait: %s",
686 addrConnect.ToString(), NetworkErrorString(sockerr));
687 return false;
688 }
689 }
690#ifdef WIN32
691 else if (WSAGetLastError() != WSAEISCONN)
692#else
693 else
694#endif
695 {
696 LogConnectFailure(manual_connection, "connect() to %s failed: %s",
697 addrConnect.ToString(),
699 return false;
700 }
701 }
702 return true;
703}
704
705bool SetProxy(enum Network net, const proxyType &addrProxy) {
706 assert(net >= 0 && net < NET_MAX);
707 if (!addrProxy.IsValid()) {
708 return false;
709 }
711 proxyInfo[net] = addrProxy;
712 return true;
713}
714
715bool GetProxy(enum Network net, proxyType &proxyInfoOut) {
716 assert(net >= 0 && net < NET_MAX);
718 if (!proxyInfo[net].IsValid()) {
719 return false;
720 }
721 proxyInfoOut = proxyInfo[net];
722 return true;
723}
724
725bool SetNameProxy(const proxyType &addrProxy) {
726 if (!addrProxy.IsValid()) {
727 return false;
728 }
730 nameProxy = addrProxy;
731 return true;
732}
733
734bool GetNameProxy(proxyType &nameProxyOut) {
736 if (!nameProxy.IsValid()) {
737 return false;
738 }
739 nameProxyOut = nameProxy;
740 return true;
741}
742
745 return nameProxy.IsValid();
746}
747
748bool IsProxy(const CNetAddr &addr) {
750 for (int i = 0; i < NET_MAX; i++) {
751 if (addr == static_cast<CNetAddr>(proxyInfo[i].proxy)) {
752 return true;
753 }
754 }
755 return false;
756}
757
758bool ConnectThroughProxy(const proxyType &proxy, const std::string &strDest,
759 uint16_t port, const Sock &sock, int nTimeout,
760 bool &outProxyConnectionFailed) {
761 // first connect to proxy server
762 if (!ConnectSocketDirectly(proxy.proxy, sock, nTimeout, true)) {
763 outProxyConnectionFailed = true;
764 return false;
765 }
766 // do socks negotiation
767 if (proxy.randomize_credentials) {
768 ProxyCredentials random_auth;
769 static std::atomic_int counter(0);
770 random_auth.username = random_auth.password =
771 strprintf("%i", counter++);
772 if (!Socks5(strDest, port, &random_auth, sock)) {
773 return false;
774 }
775 } else if (!Socks5(strDest, port, 0, sock)) {
776 return false;
777 }
778 return true;
779}
780
781bool LookupSubNet(const std::string &strSubnet, CSubNet &ret,
782 DNSLookupFn dns_lookup_function) {
783 if (!ContainsNoNUL(strSubnet)) {
784 return false;
785 }
786 size_t slash = strSubnet.find_last_of('/');
787 std::vector<CNetAddr> vIP;
788
789 std::string strAddress = strSubnet.substr(0, slash);
790 // TODO: Use LookupHost(const std::string&, CNetAddr&, bool) instead to just
791 if (LookupHost(strAddress, vIP, 1, false, dns_lookup_function)) {
792 CNetAddr network = vIP[0];
793 if (slash != strSubnet.npos) {
794 std::string strNetmask = strSubnet.substr(slash + 1);
795 uint8_t n;
796 if (ParseUInt8(strNetmask, &n)) {
797 // If valid number, assume CIDR variable-length subnet masking
798 ret = CSubNet(network, n);
799 return ret.IsValid();
800 } else {
801 // If not a valid number, try full netmask syntax
802 // Never allow lookup for netmask
803 if (LookupHost(strNetmask, vIP, 1, false,
804 dns_lookup_function)) {
805 ret = CSubNet(network, vIP[0]);
806 return ret.IsValid();
807 }
808 }
809 } else {
810 ret = CSubNet(network);
811 return ret.IsValid();
812 }
813 }
814 return false;
815}
816
817bool SetSocketNonBlocking(const SOCKET &hSocket, bool fNonBlocking) {
818 if (fNonBlocking) {
819#ifdef WIN32
820 u_long nOne = 1;
821 if (ioctlsocket(hSocket, FIONBIO, &nOne) == SOCKET_ERROR) {
822#else
823 int fFlags = fcntl(hSocket, F_GETFL, 0);
824 if (fcntl(hSocket, F_SETFL, fFlags | O_NONBLOCK) == SOCKET_ERROR) {
825#endif
826 return false;
827 }
828 } else {
829#ifdef WIN32
830 u_long nZero = 0;
831 if (ioctlsocket(hSocket, FIONBIO, &nZero) == SOCKET_ERROR) {
832#else
833 int fFlags = fcntl(hSocket, F_GETFL, 0);
834 if (fcntl(hSocket, F_SETFL, fFlags & ~O_NONBLOCK) == SOCKET_ERROR) {
835#endif
836 return false;
837 }
838 }
839
840 return true;
841}
842
843bool SetSocketNoDelay(const SOCKET &hSocket) {
844 int set = 1;
845 int rc = setsockopt(hSocket, IPPROTO_TCP, TCP_NODELAY,
846 (sockopt_arg_type)&set, sizeof(int));
847 return rc == 0;
848}
849
850void InterruptSocks5(bool interrupt) {
851 interruptSocks5Recv = interrupt;
852}
853
854bool IsBadPort(uint16_t port) {
855 // Don't forget to update doc/p2p-bad-ports.md if you change this list.
856
857 switch (port) {
858 case 1: // tcpmux
859 case 7: // echo
860 case 9: // discard
861 case 11: // systat
862 case 13: // daytime
863 case 15: // netstat
864 case 17: // qotd
865 case 19: // chargen
866 case 20: // ftp data
867 case 21: // ftp access
868 case 22: // ssh
869 case 23: // telnet
870 case 25: // smtp
871 case 37: // time
872 case 42: // name
873 case 43: // nicname
874 case 53: // domain
875 case 69: // tftp
876 case 77: // priv-rjs
877 case 79: // finger
878 case 87: // ttylink
879 case 95: // supdup
880 case 101: // hostname
881 case 102: // iso-tsap
882 case 103: // gppitnp
883 case 104: // acr-nema
884 case 109: // pop2
885 case 110: // pop3
886 case 111: // sunrpc
887 case 113: // auth
888 case 115: // sftp
889 case 117: // uucp-path
890 case 119: // nntp
891 case 123: // NTP
892 case 135: // loc-srv /epmap
893 case 137: // netbios
894 case 139: // netbios
895 case 143: // imap2
896 case 161: // snmp
897 case 179: // BGP
898 case 389: // ldap
899 case 427: // SLP (Also used by Apple Filing Protocol)
900 case 465: // smtp+ssl
901 case 512: // print / exec
902 case 513: // login
903 case 514: // shell
904 case 515: // printer
905 case 526: // tempo
906 case 530: // courier
907 case 531: // chat
908 case 532: // netnews
909 case 540: // uucp
910 case 548: // AFP (Apple Filing Protocol)
911 case 554: // rtsp
912 case 556: // remotefs
913 case 563: // nntp+ssl
914 case 587: // smtp (rfc6409)
915 case 601: // syslog-conn (rfc3195)
916 case 636: // ldap+ssl
917 case 989: // ftps-data
918 case 990: // ftps
919 case 993: // ldap+ssl
920 case 995: // pop3+ssl
921 case 1719: // h323gatestat
922 case 1720: // h323hostcall
923 case 1723: // pptp
924 case 2049: // nfs
925 case 3659: // apple-sasl / PasswordServer
926 case 4045: // lockd
927 case 5060: // sip
928 case 5061: // sips
929 case 6000: // X11
930 case 6566: // sane-port
931 case 6665: // Alternate IRC
932 case 6666: // Alternate IRC
933 case 6667: // Standard IRC
934 case 6668: // Alternate IRC
935 case 6669: // Alternate IRC
936 case 6697: // IRC + TLS
937 case 10080: // Amanda
938 return true;
939 }
940 return false;
941}
Network address.
Definition: netaddress.h:121
bool SetSpecial(const std::string &addr)
Parse a Tor or I2P address and set this object to it.
Definition: netaddress.cpp:227
A combination of a network address (CNetAddr) and a (TCP) port.
Definition: netaddress.h:545
std::string ToString() const
bool GetSockAddr(struct sockaddr *paddr, socklen_t *addrlen) const
Obtain the IPv4/6 socket address this represents.
bool IsValid() const
Different type to mark Mutex at global scope.
Definition: sync.h:144
RAII helper class that manages a socket.
Definition: sock.h:28
virtual ssize_t Send(const void *data, size_t len, int flags) const
send(2) wrapper.
Definition: sock.cpp:65
static constexpr Event SEND
If passed to Wait(), then it will wait for readiness to send to the socket.
Definition: sock.h:141
virtual bool Wait(std::chrono::milliseconds timeout, Event requested, Event *occurred=nullptr) const
Wait for readiness for input (recv) or output (send).
Definition: sock.cpp:108
uint8_t Event
Definition: sock.h:129
static constexpr Event RECV
If passed to Wait(), then it will wait for readiness to read from the socket.
Definition: sock.h:135
virtual SOCKET Get() const
Get the value of the contained socket.
Definition: sock.cpp:51
virtual int GetSockOpt(int level, int opt_name, void *opt_val, socklen_t *opt_len) const
getsockopt(2) wrapper.
Definition: sock.cpp:102
virtual int Connect(const sockaddr *addr, socklen_t addr_len) const
connect(2) wrapper.
Definition: sock.cpp:73
virtual ssize_t Recv(void *buf, size_t len, int flags) const
recv(2) wrapper.
Definition: sock.cpp:69
bool IsValid() const
Definition: netbase.h:58
CService proxy
Definition: netbase.h:60
bool randomize_credentials
Definition: netbase.h:61
#define INVALID_SOCKET
Definition: compat.h:52
#define WSAEWOULDBLOCK
Definition: compat.h:45
#define WSAEINVAL
Definition: compat.h:43
#define SOCKET_ERROR
Definition: compat.h:53
#define WSAGetLastError()
Definition: compat.h:42
static bool IsSelectableSocket(const SOCKET &s)
Definition: compat.h:102
#define MSG_NOSIGNAL
Definition: compat.h:113
unsigned int SOCKET
Definition: compat.h:40
void * sockopt_arg_type
Definition: compat.h:87
#define WSAEINPROGRESS
Definition: compat.h:49
bool error(const char *fmt, const Args &...args)
Definition: logging.h:226
#define LogPrint(category,...)
Definition: logging.h:211
#define LogPrintf(...)
Definition: logging.h:207
@ PROXY
Definition: logging.h:55
@ NET
Definition: logging.h:40
void format(std::ostream &out, const char *fmt, const Args &...args)
Format list of arguments to the stream according to given format string.
Definition: tinyformat.h:1112
Network
A network type.
Definition: netaddress.h:44
@ NET_I2P
I2P.
Definition: netaddress.h:59
@ NET_CJDNS
CJDNS.
Definition: netaddress.h:62
@ NET_MAX
Dummy value to indicate the number of NET_* constants.
Definition: netaddress.h:69
@ NET_ONION
TOR (v2 or v3)
Definition: netaddress.h:56
@ NET_IPV6
IPv6.
Definition: netaddress.h:53
@ NET_IPV4
IPv4.
Definition: netaddress.h:50
@ NET_UNROUTABLE
Addresses from these networks are not publicly routable on the global Internet.
Definition: netaddress.h:47
@ NET_INTERNAL
A set of addresses that represent the hash of a string or FQDN.
Definition: netaddress.h:66
IntrRecvError
Status codes that can be returned by InterruptibleRecv.
Definition: netbase.cpp:314
SOCKS5Atyp
Values defined for ATYPE in RFC1928.
Definition: netbase.cpp:307
@ DOMAINNAME
Definition: netbase.cpp:309
@ IPV4
Definition: netbase.cpp:308
@ IPV6
Definition: netbase.cpp:310
SOCKS5Command
Values defined for CMD in RFC1928.
Definition: netbase.cpp:287
@ UDP_ASSOCIATE
Definition: netbase.cpp:290
@ CONNECT
Definition: netbase.cpp:288
@ BIND
Definition: netbase.cpp:289
bool GetNameProxy(proxyType &nameProxyOut)
Definition: netbase.cpp:734
std::string GetNetworkName(enum Network net)
Definition: netbase.cpp:114
static void LogConnectFailure(bool manual_connection, const char *fmt, const Args &...args)
Definition: netbase.cpp:619
SOCKSVersion
SOCKS version.
Definition: netbase.cpp:276
@ SOCKS4
Definition: netbase.cpp:276
@ SOCKS5
Definition: netbase.cpp:276
int g_socks5_recv_timeout
Definition: netbase.cpp:43
bool HaveNameProxy()
Definition: netbase.cpp:743
bool GetProxy(enum Network net, proxyType &proxyInfoOut)
Definition: netbase.cpp:715
bool LookupSubNet(const std::string &strSubnet, CSubNet &ret, DNSLookupFn dns_lookup_function)
Parse and resolve a specified subnet string into the appropriate internal representation.
Definition: netbase.cpp:781
static bool LookupIntern(const std::string &name, std::vector< CNetAddr > &vIP, unsigned int nMaxSolutions, bool fAllowLookup, DNSLookupFn dns_lookup_function)
Definition: netbase.cpp:153
bool SetSocketNoDelay(const SOCKET &hSocket)
Set the TCP_NODELAY flag on a socket.
Definition: netbase.cpp:843
bool ConnectThroughProxy(const proxyType &proxy, const std::string &strDest, uint16_t port, const Sock &sock, int nTimeout, bool &outProxyConnectionFailed)
Connect to a specified destination service through a SOCKS5 proxy by first connecting to the SOCKS5 p...
Definition: netbase.cpp:758
static IntrRecvError InterruptibleRecv(uint8_t *data, size_t len, int timeout, const Sock &sock)
Try to read a specified number of bytes from a socket.
Definition: netbase.cpp:340
enum Network ParseNetwork(const std::string &net_in)
Definition: netbase.cpp:92
SOCKS5Method
Values defined for METHOD in RFC1928.
Definition: netbase.cpp:279
@ GSSAPI
GSSAPI.
Definition: netbase.cpp:281
@ NOAUTH
No authentication required.
Definition: netbase.cpp:280
@ USER_PASS
Username/password.
Definition: netbase.cpp:282
@ NO_ACCEPTABLE
No acceptable methods.
Definition: netbase.cpp:283
bool Socks5(const std::string &strDest, uint16_t port, const ProxyCredentials *auth, const Sock &sock)
Connect to a specified destination service through an already connected SOCKS5 proxy.
Definition: netbase.cpp:421
static std::string Socks5ErrorString(uint8_t err)
Convert SOCKS5 reply to an error message.
Definition: netbase.cpp:380
void InterruptSocks5(bool interrupt)
Definition: netbase.cpp:850
std::unique_ptr< Sock > CreateSockTCP(const CService &address_family)
Create a TCP socket in the given address family.
Definition: netbase.cpp:567
std::function< std::unique_ptr< Sock >(const CService &)> CreateSock
Socket factory.
Definition: netbase.cpp:615
bool ConnectSocketDirectly(const CService &addrConnect, const Sock &sock, int nTimeout, bool manual_connection)
Try to connect to the specified service on the specified socket.
Definition: netbase.cpp:629
SOCKS5Reply
Values defined for REP in RFC1928.
Definition: netbase.cpp:294
@ TTLEXPIRED
TTL expired.
Definition: netbase.cpp:301
@ CMDUNSUPPORTED
Command not supported.
Definition: netbase.cpp:302
@ NETUNREACHABLE
Network unreachable.
Definition: netbase.cpp:298
@ GENFAILURE
General failure.
Definition: netbase.cpp:296
@ CONNREFUSED
Connection refused.
Definition: netbase.cpp:300
@ SUCCEEDED
Succeeded.
Definition: netbase.cpp:295
@ ATYPEUNSUPPORTED
Address type not supported.
Definition: netbase.cpp:303
@ NOTALLOWED
Connection not allowed by ruleset.
Definition: netbase.cpp:297
@ HOSTUNREACHABLE
Network unreachable.
Definition: netbase.cpp:299
static GlobalMutex g_proxyinfo_mutex
Definition: netbase.cpp:34
bool Lookup(const std::string &name, std::vector< CService > &vAddr, uint16_t portDefault, bool fAllowLookup, unsigned int nMaxSolutions, DNSLookupFn dns_lookup_function)
Resolve a service string to its corresponding service.
Definition: netbase.cpp:223
bool fNameLookup
Definition: netbase.cpp:38
static std::atomic< bool > interruptSocks5Recv(false)
static proxyType proxyInfo[NET_MAX] GUARDED_BY(g_proxyinfo_mutex)
int nConnectTimeout
Definition: netbase.cpp:37
bool SetNameProxy(const proxyType &addrProxy)
Set the name proxy to use for all connections to nodes specified by a hostname.
Definition: netbase.cpp:725
bool SetSocketNonBlocking(const SOCKET &hSocket, bool fNonBlocking)
Disable or enable blocking-mode for a socket.
Definition: netbase.cpp:817
CService LookupNumeric(const std::string &name, uint16_t portDefault, DNSLookupFn dns_lookup_function)
Resolve a service string with a numeric IP to its first corresponding service.
Definition: netbase.cpp:261
bool IsProxy(const CNetAddr &addr)
Definition: netbase.cpp:748
bool IsBadPort(uint16_t port)
Determine if a port is "bad" from the perspective of attempting to connect to a node on that port.
Definition: netbase.cpp:854
std::vector< CNetAddr > WrappedGetAddrInfo(const std::string &name, bool allow_lookup)
Wrapper for getaddrinfo(3).
Definition: netbase.cpp:46
DNSLookupFn g_dns_lookup
Definition: netbase.cpp:90
bool LookupHost(const std::string &name, std::vector< CNetAddr > &vIP, unsigned int nMaxSolutions, bool fAllowLookup, DNSLookupFn dns_lookup_function)
Resolve a host string to its corresponding network addresses.
Definition: netbase.cpp:191
bool SetProxy(enum Network net, const proxyType &addrProxy)
Definition: netbase.cpp:705
std::vector< std::string > GetNetworkNames(bool append_unroutable)
Return a vector of publicly routable Network names; optionally append NET_UNROUTABLE.
Definition: netbase.cpp:137
static const int DEFAULT_NAME_LOOKUP
-dns default
Definition: netbase.h:30
std::function< std::vector< CNetAddr >(const std::string &, bool)> DNSLookupFn
Definition: netbase.h:109
static const int DEFAULT_CONNECT_TIMEOUT
-timeout default
Definition: netbase.h:28
const char * name
Definition: rest.cpp:47
std::string NetworkErrorString(int err)
Return readable error string for a network error code.
Definition: sock.cpp:398
bool CloseSocket(SOCKET &hSocket)
Close socket and set hSocket to INVALID_SOCKET.
Definition: sock.cpp:405
static constexpr auto MAX_WAIT_FOR_IO
Maximum time to wait for I/O readiness.
Definition: sock.h:21
bool ContainsNoNUL(std::string_view str) noexcept
Check if a string does not contain any embedded NUL (\0) characters.
Definition: string.h:90
Credentials for proxy authentication.
Definition: netbase.h:65
std::string username
Definition: netbase.h:66
std::string password
Definition: netbase.h:67
#define LOCK(cs)
Definition: sync.h:306
int64_t GetTimeMillis()
Returns the system time (not mockable)
Definition: time.cpp:101
#define strprintf
Format arguments and return the string or write to given std::ostream (see tinyformat::format doc for...
Definition: tinyformat.h:1202
bool ParseUInt8(std::string_view str, uint8_t *out)
Convert decimal string to unsigned 8-bit integer with strict parse error feedback.
void SplitHostPort(std::string_view in, uint16_t &portOut, std::string &hostOut)
std::string ToLower(std::string_view str)
Returns the lowercase equivalent of the given string.
assert(!tx.IsCoinBase())