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