/ src / netbase.cpp
netbase.cpp
  1  // Copyright (c) 2009-2010 Satoshi Nakamoto
  2  // Copyright (c) 2009-2022 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 <limits>
 26  #include <memory>
 27  
 28  #if HAVE_SOCKADDR_UN
 29  #include <sys/un.h>
 30  #endif
 31  
 32  // Settings
 33  static GlobalMutex g_proxyinfo_mutex;
 34  static Proxy proxyInfo[NET_MAX] GUARDED_BY(g_proxyinfo_mutex);
 35  static Proxy nameProxy GUARDED_BY(g_proxyinfo_mutex);
 36  int nConnectTimeout = DEFAULT_CONNECT_TIMEOUT;
 37  bool fNameLookup = DEFAULT_NAME_LOOKUP;
 38  
 39  // Need ample time for negotiation for very slow proxies such as Tor
 40  std::chrono::milliseconds g_socks5_recv_timeout = 20s;
 41  CThreadInterrupt g_socks5_interrupt;
 42  
 43  ReachableNets g_reachable_nets;
 44  
 45  std::vector<CNetAddr> WrappedGetAddrInfo(const std::string& name, bool allow_lookup)
 46  {
 47      addrinfo ai_hint{};
 48      // We want a TCP port, which is a streaming socket type
 49      ai_hint.ai_socktype = SOCK_STREAM;
 50      ai_hint.ai_protocol = IPPROTO_TCP;
 51      // We don't care which address family (IPv4 or IPv6) is returned
 52      ai_hint.ai_family = AF_UNSPEC;
 53      // If we allow lookups of hostnames, use the AI_ADDRCONFIG flag to only
 54      // return addresses whose family we have an address configured for.
 55      //
 56      // If we don't allow lookups, then use the AI_NUMERICHOST flag for
 57      // getaddrinfo to only decode numerical network addresses and suppress
 58      // hostname lookups.
 59      ai_hint.ai_flags = allow_lookup ? AI_ADDRCONFIG : AI_NUMERICHOST;
 60  
 61      addrinfo* ai_res{nullptr};
 62      const int n_err{getaddrinfo(name.c_str(), nullptr, &ai_hint, &ai_res)};
 63      if (n_err != 0) {
 64          return {};
 65      }
 66  
 67      // Traverse the linked list starting with ai_trav.
 68      addrinfo* ai_trav{ai_res};
 69      std::vector<CNetAddr> resolved_addresses;
 70      while (ai_trav != nullptr) {
 71          if (ai_trav->ai_family == AF_INET) {
 72              assert(ai_trav->ai_addrlen >= sizeof(sockaddr_in));
 73              resolved_addresses.emplace_back(reinterpret_cast<sockaddr_in*>(ai_trav->ai_addr)->sin_addr);
 74          }
 75          if (ai_trav->ai_family == AF_INET6) {
 76              assert(ai_trav->ai_addrlen >= sizeof(sockaddr_in6));
 77              const sockaddr_in6* s6{reinterpret_cast<sockaddr_in6*>(ai_trav->ai_addr)};
 78              resolved_addresses.emplace_back(s6->sin6_addr, s6->sin6_scope_id);
 79          }
 80          ai_trav = ai_trav->ai_next;
 81      }
 82      freeaddrinfo(ai_res);
 83  
 84      return resolved_addresses;
 85  }
 86  
 87  DNSLookupFn g_dns_lookup{WrappedGetAddrInfo};
 88  
 89  enum Network ParseNetwork(const std::string& net_in) {
 90      std::string net = ToLower(net_in);
 91      if (net == "ipv4") return NET_IPV4;
 92      if (net == "ipv6") return NET_IPV6;
 93      if (net == "onion") return NET_ONION;
 94      if (net == "tor") {
 95          LogPrintf("Warning: net name 'tor' is deprecated and will be removed in the future. You should use 'onion' instead.\n");
 96          return NET_ONION;
 97      }
 98      if (net == "i2p") {
 99          return NET_I2P;
100      }
101      if (net == "cjdns") {
102          return NET_CJDNS;
103      }
104      return NET_UNROUTABLE;
105  }
106  
107  std::string GetNetworkName(enum Network net)
108  {
109      switch (net) {
110      case NET_UNROUTABLE: return "not_publicly_routable";
111      case NET_IPV4: return "ipv4";
112      case NET_IPV6: return "ipv6";
113      case NET_ONION: return "onion";
114      case NET_I2P: return "i2p";
115      case NET_CJDNS: return "cjdns";
116      case NET_INTERNAL: return "internal";
117      case NET_MAX: assert(false);
118      } // no default case, so the compiler can warn about missing cases
119  
120      assert(false);
121  }
122  
123  std::vector<std::string> GetNetworkNames(bool append_unroutable)
124  {
125      std::vector<std::string> names;
126      for (int n = 0; n < NET_MAX; ++n) {
127          const enum Network network{static_cast<Network>(n)};
128          if (network == NET_UNROUTABLE || network == NET_INTERNAL) continue;
129          names.emplace_back(GetNetworkName(network));
130      }
131      if (append_unroutable) {
132          names.emplace_back(GetNetworkName(NET_UNROUTABLE));
133      }
134      return names;
135  }
136  
137  static std::vector<CNetAddr> LookupIntern(const std::string& name, unsigned int nMaxSolutions, bool fAllowLookup, DNSLookupFn dns_lookup_function)
138  {
139      if (!ContainsNoNUL(name)) return {};
140      {
141          CNetAddr addr;
142          // From our perspective, onion addresses are not hostnames but rather
143          // direct encodings of CNetAddr much like IPv4 dotted-decimal notation
144          // or IPv6 colon-separated hextet notation. Since we can't use
145          // getaddrinfo to decode them and it wouldn't make sense to resolve
146          // them, we return a network address representing it instead. See
147          // CNetAddr::SetSpecial(const std::string&) for more details.
148          if (addr.SetSpecial(name)) return {addr};
149      }
150  
151      std::vector<CNetAddr> addresses;
152  
153      for (const CNetAddr& resolved : dns_lookup_function(name, fAllowLookup)) {
154          if (nMaxSolutions > 0 && addresses.size() >= nMaxSolutions) {
155              break;
156          }
157          /* Never allow resolving to an internal address. Consider any such result invalid */
158          if (!resolved.IsInternal()) {
159              addresses.push_back(resolved);
160          }
161      }
162  
163      return addresses;
164  }
165  
166  std::vector<CNetAddr> LookupHost(const std::string& name, unsigned int nMaxSolutions, bool fAllowLookup, DNSLookupFn dns_lookup_function)
167  {
168      if (!ContainsNoNUL(name)) return {};
169      std::string strHost = name;
170      if (strHost.empty()) return {};
171      if (strHost.front() == '[' && strHost.back() == ']') {
172          strHost = strHost.substr(1, strHost.size() - 2);
173      }
174  
175      return LookupIntern(strHost, nMaxSolutions, fAllowLookup, dns_lookup_function);
176  }
177  
178  std::optional<CNetAddr> LookupHost(const std::string& name, bool fAllowLookup, DNSLookupFn dns_lookup_function)
179  {
180      const std::vector<CNetAddr> addresses{LookupHost(name, 1, fAllowLookup, dns_lookup_function)};
181      return addresses.empty() ? std::nullopt : std::make_optional(addresses.front());
182  }
183  
184  std::vector<CService> Lookup(const std::string& name, uint16_t portDefault, bool fAllowLookup, unsigned int nMaxSolutions, DNSLookupFn dns_lookup_function)
185  {
186      if (name.empty() || !ContainsNoNUL(name)) {
187          return {};
188      }
189      uint16_t port{portDefault};
190      std::string hostname;
191      SplitHostPort(name, port, hostname);
192  
193      const std::vector<CNetAddr> addresses{LookupIntern(hostname, nMaxSolutions, fAllowLookup, dns_lookup_function)};
194      if (addresses.empty()) return {};
195      std::vector<CService> services;
196      services.reserve(addresses.size());
197      for (const auto& addr : addresses)
198          services.emplace_back(addr, port);
199      return services;
200  }
201  
202  std::optional<CService> Lookup(const std::string& name, uint16_t portDefault, bool fAllowLookup, DNSLookupFn dns_lookup_function)
203  {
204      const std::vector<CService> services{Lookup(name, portDefault, fAllowLookup, 1, dns_lookup_function)};
205  
206      return services.empty() ? std::nullopt : std::make_optional(services.front());
207  }
208  
209  CService LookupNumeric(const std::string& name, uint16_t portDefault, DNSLookupFn dns_lookup_function)
210  {
211      if (!ContainsNoNUL(name)) {
212          return {};
213      }
214      // "1.2:345" will fail to resolve the ip, but will still set the port.
215      // If the ip fails to resolve, re-init the result.
216      return Lookup(name, portDefault, /*fAllowLookup=*/false, dns_lookup_function).value_or(CService{});
217  }
218  
219  bool IsUnixSocketPath(const std::string& name)
220  {
221  #if HAVE_SOCKADDR_UN
222      if (name.find(ADDR_PREFIX_UNIX) != 0) return false;
223  
224      // Split off "unix:" prefix
225      std::string str{name.substr(ADDR_PREFIX_UNIX.length())};
226  
227      // Path size limit is platform-dependent
228      // see https://manpages.ubuntu.com/manpages/xenial/en/man7/unix.7.html
229      if (str.size() + 1 > sizeof(((sockaddr_un*)nullptr)->sun_path)) return false;
230  
231      return true;
232  #else
233      return false;
234  #endif
235  }
236  
237  /** SOCKS version */
238  enum SOCKSVersion: uint8_t {
239      SOCKS4 = 0x04,
240      SOCKS5 = 0x05
241  };
242  
243  /** Values defined for METHOD in RFC1928 */
244  enum SOCKS5Method: uint8_t {
245      NOAUTH = 0x00,        //!< No authentication required
246      GSSAPI = 0x01,        //!< GSSAPI
247      USER_PASS = 0x02,     //!< Username/password
248      NO_ACCEPTABLE = 0xff, //!< No acceptable methods
249  };
250  
251  /** Values defined for CMD in RFC1928 */
252  enum SOCKS5Command: uint8_t {
253      CONNECT = 0x01,
254      BIND = 0x02,
255      UDP_ASSOCIATE = 0x03
256  };
257  
258  /** Values defined for REP in RFC1928 */
259  enum SOCKS5Reply: uint8_t {
260      SUCCEEDED = 0x00,        //!< Succeeded
261      GENFAILURE = 0x01,       //!< General failure
262      NOTALLOWED = 0x02,       //!< Connection not allowed by ruleset
263      NETUNREACHABLE = 0x03,   //!< Network unreachable
264      HOSTUNREACHABLE = 0x04,  //!< Network unreachable
265      CONNREFUSED = 0x05,      //!< Connection refused
266      TTLEXPIRED = 0x06,       //!< TTL expired
267      CMDUNSUPPORTED = 0x07,   //!< Command not supported
268      ATYPEUNSUPPORTED = 0x08, //!< Address type not supported
269  };
270  
271  /** Values defined for ATYPE in RFC1928 */
272  enum SOCKS5Atyp: uint8_t {
273      IPV4 = 0x01,
274      DOMAINNAME = 0x03,
275      IPV6 = 0x04,
276  };
277  
278  /** Status codes that can be returned by InterruptibleRecv */
279  enum class IntrRecvError {
280      OK,
281      Timeout,
282      Disconnected,
283      NetworkError,
284      Interrupted
285  };
286  
287  /**
288   * Try to read a specified number of bytes from a socket. Please read the "see
289   * also" section for more detail.
290   *
291   * @param data The buffer where the read bytes should be stored.
292   * @param len The number of bytes to read into the specified buffer.
293   * @param timeout The total timeout for this read.
294   * @param sock The socket (has to be in non-blocking mode) from which to read bytes.
295   *
296   * @returns An IntrRecvError indicating the resulting status of this read.
297   *          IntrRecvError::OK only if all of the specified number of bytes were
298   *          read.
299   *
300   * @see This function can be interrupted by calling g_socks5_interrupt().
301   *      Sockets can be made non-blocking with Sock::SetNonBlocking().
302   */
303  static IntrRecvError InterruptibleRecv(uint8_t* data, size_t len, std::chrono::milliseconds timeout, const Sock& sock)
304  {
305      auto curTime{Now<SteadyMilliseconds>()};
306      const auto endTime{curTime + timeout};
307      while (len > 0 && curTime < endTime) {
308          ssize_t ret = sock.Recv(data, len, 0); // Optimistically try the recv first
309          if (ret > 0) {
310              len -= ret;
311              data += ret;
312          } else if (ret == 0) { // Unexpected disconnection
313              return IntrRecvError::Disconnected;
314          } else { // Other error or blocking
315              int nErr = WSAGetLastError();
316              if (nErr == WSAEINPROGRESS || nErr == WSAEWOULDBLOCK || nErr == WSAEINVAL) {
317                  // Only wait at most MAX_WAIT_FOR_IO at a time, unless
318                  // we're approaching the end of the specified total timeout
319                  const auto remaining = std::chrono::milliseconds{endTime - curTime};
320                  const auto timeout = std::min(remaining, std::chrono::milliseconds{MAX_WAIT_FOR_IO});
321                  if (!sock.Wait(timeout, Sock::RECV)) {
322                      return IntrRecvError::NetworkError;
323                  }
324              } else {
325                  return IntrRecvError::NetworkError;
326              }
327          }
328          if (g_socks5_interrupt) {
329              return IntrRecvError::Interrupted;
330          }
331          curTime = Now<SteadyMilliseconds>();
332      }
333      return len == 0 ? IntrRecvError::OK : IntrRecvError::Timeout;
334  }
335  
336  /** Convert SOCKS5 reply to an error message */
337  static std::string Socks5ErrorString(uint8_t err)
338  {
339      switch(err) {
340          case SOCKS5Reply::GENFAILURE:
341              return "general failure";
342          case SOCKS5Reply::NOTALLOWED:
343              return "connection not allowed";
344          case SOCKS5Reply::NETUNREACHABLE:
345              return "network unreachable";
346          case SOCKS5Reply::HOSTUNREACHABLE:
347              return "host unreachable";
348          case SOCKS5Reply::CONNREFUSED:
349              return "connection refused";
350          case SOCKS5Reply::TTLEXPIRED:
351              return "TTL expired";
352          case SOCKS5Reply::CMDUNSUPPORTED:
353              return "protocol error";
354          case SOCKS5Reply::ATYPEUNSUPPORTED:
355              return "address type not supported";
356          default:
357              return "unknown";
358      }
359  }
360  
361  bool Socks5(const std::string& strDest, uint16_t port, const ProxyCredentials* auth, const Sock& sock)
362  {
363      try {
364          IntrRecvError recvr;
365          LogPrint(BCLog::NET, "SOCKS5 connecting %s\n", strDest);
366          if (strDest.size() > 255) {
367              LogError("Hostname too long\n");
368              return false;
369          }
370          // Construct the version identifier/method selection message
371          std::vector<uint8_t> vSocks5Init;
372          vSocks5Init.push_back(SOCKSVersion::SOCKS5); // We want the SOCK5 protocol
373          if (auth) {
374              vSocks5Init.push_back(0x02); // 2 method identifiers follow...
375              vSocks5Init.push_back(SOCKS5Method::NOAUTH);
376              vSocks5Init.push_back(SOCKS5Method::USER_PASS);
377          } else {
378              vSocks5Init.push_back(0x01); // 1 method identifier follows...
379              vSocks5Init.push_back(SOCKS5Method::NOAUTH);
380          }
381          sock.SendComplete(vSocks5Init, g_socks5_recv_timeout, g_socks5_interrupt);
382          uint8_t pchRet1[2];
383          if (InterruptibleRecv(pchRet1, 2, g_socks5_recv_timeout, sock) != IntrRecvError::OK) {
384              LogPrintf("Socks5() connect to %s:%d failed: InterruptibleRecv() timeout or other failure\n", strDest, port);
385              return false;
386          }
387          if (pchRet1[0] != SOCKSVersion::SOCKS5) {
388              LogError("Proxy failed to initialize\n");
389              return false;
390          }
391          if (pchRet1[1] == SOCKS5Method::USER_PASS && auth) {
392              // Perform username/password authentication (as described in RFC1929)
393              std::vector<uint8_t> vAuth;
394              vAuth.push_back(0x01); // Current (and only) version of user/pass subnegotiation
395              if (auth->username.size() > 255 || auth->password.size() > 255) {
396                  LogError("Proxy username or password too long\n");
397                  return false;
398              }
399              vAuth.push_back(auth->username.size());
400              vAuth.insert(vAuth.end(), auth->username.begin(), auth->username.end());
401              vAuth.push_back(auth->password.size());
402              vAuth.insert(vAuth.end(), auth->password.begin(), auth->password.end());
403              sock.SendComplete(vAuth, g_socks5_recv_timeout, g_socks5_interrupt);
404              LogPrint(BCLog::PROXY, "SOCKS5 sending proxy authentication %s:%s\n", auth->username, auth->password);
405              uint8_t pchRetA[2];
406              if (InterruptibleRecv(pchRetA, 2, g_socks5_recv_timeout, sock) != IntrRecvError::OK) {
407                  LogError("Error reading proxy authentication response\n");
408                  return false;
409              }
410              if (pchRetA[0] != 0x01 || pchRetA[1] != 0x00) {
411                  LogError("Proxy authentication unsuccessful\n");
412                  return false;
413              }
414          } else if (pchRet1[1] == SOCKS5Method::NOAUTH) {
415              // Perform no authentication
416          } else {
417              LogError("Proxy requested wrong authentication method %02x\n", pchRet1[1]);
418              return false;
419          }
420          std::vector<uint8_t> vSocks5;
421          vSocks5.push_back(SOCKSVersion::SOCKS5);   // VER protocol version
422          vSocks5.push_back(SOCKS5Command::CONNECT); // CMD CONNECT
423          vSocks5.push_back(0x00);                   // RSV Reserved must be 0
424          vSocks5.push_back(SOCKS5Atyp::DOMAINNAME); // ATYP DOMAINNAME
425          vSocks5.push_back(strDest.size());         // Length<=255 is checked at beginning of function
426          vSocks5.insert(vSocks5.end(), strDest.begin(), strDest.end());
427          vSocks5.push_back((port >> 8) & 0xFF);
428          vSocks5.push_back((port >> 0) & 0xFF);
429          sock.SendComplete(vSocks5, g_socks5_recv_timeout, g_socks5_interrupt);
430          uint8_t pchRet2[4];
431          if ((recvr = InterruptibleRecv(pchRet2, 4, g_socks5_recv_timeout, sock)) != IntrRecvError::OK) {
432              if (recvr == IntrRecvError::Timeout) {
433                  /* If a timeout happens here, this effectively means we timed out while connecting
434                   * to the remote node. This is very common for Tor, so do not print an
435                   * error message. */
436                  return false;
437              } else {
438                  LogError("Error while reading proxy response\n");
439                  return false;
440              }
441          }
442          if (pchRet2[0] != SOCKSVersion::SOCKS5) {
443              LogError("Proxy failed to accept request\n");
444              return false;
445          }
446          if (pchRet2[1] != SOCKS5Reply::SUCCEEDED) {
447              // Failures to connect to a peer that are not proxy errors
448              LogPrintf("Socks5() connect to %s:%d failed: %s\n", strDest, port, Socks5ErrorString(pchRet2[1]));
449              return false;
450          }
451          if (pchRet2[2] != 0x00) { // Reserved field must be 0
452              LogError("Error: malformed proxy response\n");
453              return false;
454          }
455          uint8_t pchRet3[256];
456          switch (pchRet2[3]) {
457          case SOCKS5Atyp::IPV4: recvr = InterruptibleRecv(pchRet3, 4, g_socks5_recv_timeout, sock); break;
458          case SOCKS5Atyp::IPV6: recvr = InterruptibleRecv(pchRet3, 16, g_socks5_recv_timeout, sock); break;
459          case SOCKS5Atyp::DOMAINNAME: {
460              recvr = InterruptibleRecv(pchRet3, 1, g_socks5_recv_timeout, sock);
461              if (recvr != IntrRecvError::OK) {
462                  LogError("Error reading from proxy\n");
463                  return false;
464              }
465              int nRecv = pchRet3[0];
466              recvr = InterruptibleRecv(pchRet3, nRecv, g_socks5_recv_timeout, sock);
467              break;
468          }
469          default: {
470              LogError("Error: malformed proxy response\n");
471              return false;
472          }
473          }
474          if (recvr != IntrRecvError::OK) {
475              LogError("Error reading from proxy\n");
476              return false;
477          }
478          if (InterruptibleRecv(pchRet3, 2, g_socks5_recv_timeout, sock) != IntrRecvError::OK) {
479              LogError("Error reading from proxy\n");
480              return false;
481          }
482          LogPrint(BCLog::NET, "SOCKS5 connected %s\n", strDest);
483          return true;
484      } catch (const std::runtime_error& e) {
485          LogError("Error during SOCKS5 proxy handshake: %s\n", e.what());
486          return false;
487      }
488  }
489  
490  std::unique_ptr<Sock> CreateSockOS(sa_family_t address_family)
491  {
492      // Not IPv4, IPv6 or UNIX
493      if (address_family == AF_UNSPEC) return nullptr;
494  
495      int protocol{IPPROTO_TCP};
496  #if HAVE_SOCKADDR_UN
497      if (address_family == AF_UNIX) protocol = 0;
498  #endif
499  
500      // Create a socket in the specified address family.
501      SOCKET hSocket = socket(address_family, SOCK_STREAM, protocol);
502      if (hSocket == INVALID_SOCKET) {
503          return nullptr;
504      }
505  
506      auto sock = std::make_unique<Sock>(hSocket);
507  
508      // Ensure that waiting for I/O on this socket won't result in undefined
509      // behavior.
510      if (!sock->IsSelectable()) {
511          LogPrintf("Cannot create connection: non-selectable socket created (fd >= FD_SETSIZE ?)\n");
512          return nullptr;
513      }
514  
515  #ifdef SO_NOSIGPIPE
516      int set = 1;
517      // Set the no-sigpipe option on the socket for BSD systems, other UNIXes
518      // should use the MSG_NOSIGNAL flag for every send.
519      if (sock->SetSockOpt(SOL_SOCKET, SO_NOSIGPIPE, (void*)&set, sizeof(int)) == SOCKET_ERROR) {
520          LogPrintf("Error setting SO_NOSIGPIPE on socket: %s, continuing anyway\n",
521                    NetworkErrorString(WSAGetLastError()));
522      }
523  #endif
524  
525      // Set the non-blocking option on the socket.
526      if (!sock->SetNonBlocking()) {
527          LogPrintf("Error setting socket to non-blocking: %s\n", NetworkErrorString(WSAGetLastError()));
528          return nullptr;
529      }
530  
531  #if HAVE_SOCKADDR_UN
532      if (address_family == AF_UNIX) return sock;
533  #endif
534  
535      // Set the no-delay option (disable Nagle's algorithm) on the TCP socket.
536      const int on{1};
537      if (sock->SetSockOpt(IPPROTO_TCP, TCP_NODELAY, &on, sizeof(on)) == SOCKET_ERROR) {
538          LogPrint(BCLog::NET, "Unable to set TCP_NODELAY on a newly created socket, continuing anyway\n");
539      }
540      return sock;
541  }
542  
543  std::function<std::unique_ptr<Sock>(const sa_family_t&)> CreateSock = CreateSockOS;
544  
545  template<typename... Args>
546  static void LogConnectFailure(bool manual_connection, const char* fmt, const Args&... args) {
547      std::string error_message = tfm::format(fmt, args...);
548      if (manual_connection) {
549          LogPrintf("%s\n", error_message);
550      } else {
551          LogPrint(BCLog::NET, "%s\n", error_message);
552      }
553  }
554  
555  static bool ConnectToSocket(const Sock& sock, struct sockaddr* sockaddr, socklen_t len, const std::string& dest_str, bool manual_connection)
556  {
557      // Connect to `sockaddr` using `sock`.
558      if (sock.Connect(sockaddr, len) == SOCKET_ERROR) {
559          int nErr = WSAGetLastError();
560          // WSAEINVAL is here because some legacy version of winsock uses it
561          if (nErr == WSAEINPROGRESS || nErr == WSAEWOULDBLOCK || nErr == WSAEINVAL)
562          {
563              // Connection didn't actually fail, but is being established
564              // asynchronously. Thus, use async I/O api (select/poll)
565              // synchronously to check for successful connection with a timeout.
566              const Sock::Event requested = Sock::RECV | Sock::SEND;
567              Sock::Event occurred;
568              if (!sock.Wait(std::chrono::milliseconds{nConnectTimeout}, requested, &occurred)) {
569                  LogPrintf("wait for connect to %s failed: %s\n",
570                            dest_str,
571                            NetworkErrorString(WSAGetLastError()));
572                  return false;
573              } else if (occurred == 0) {
574                  LogPrint(BCLog::NET, "connection attempt to %s timed out\n", dest_str);
575                  return false;
576              }
577  
578              // Even if the wait was successful, the connect might not
579              // have been successful. The reason for this failure is hidden away
580              // in the SO_ERROR for the socket in modern systems. We read it into
581              // sockerr here.
582              int sockerr;
583              socklen_t sockerr_len = sizeof(sockerr);
584              if (sock.GetSockOpt(SOL_SOCKET, SO_ERROR, (sockopt_arg_type)&sockerr, &sockerr_len) ==
585                  SOCKET_ERROR) {
586                  LogPrintf("getsockopt() for %s failed: %s\n", dest_str, NetworkErrorString(WSAGetLastError()));
587                  return false;
588              }
589              if (sockerr != 0) {
590                  LogConnectFailure(manual_connection,
591                                    "connect() to %s failed after wait: %s",
592                                    dest_str,
593                                    NetworkErrorString(sockerr));
594                  return false;
595              }
596          }
597  #ifdef WIN32
598          else if (WSAGetLastError() != WSAEISCONN)
599  #else
600          else
601  #endif
602          {
603              LogConnectFailure(manual_connection, "connect() to %s failed: %s", dest_str, NetworkErrorString(WSAGetLastError()));
604              return false;
605          }
606      }
607      return true;
608  }
609  
610  std::unique_ptr<Sock> ConnectDirectly(const CService& dest, bool manual_connection)
611  {
612      auto sock = CreateSock(dest.GetSAFamily());
613      if (!sock) {
614          LogPrintLevel(BCLog::NET, BCLog::Level::Error, "Cannot create a socket for connecting to %s\n", dest.ToStringAddrPort());
615          return {};
616      }
617  
618      // Create a sockaddr from the specified service.
619      struct sockaddr_storage sockaddr;
620      socklen_t len = sizeof(sockaddr);
621      if (!dest.GetSockAddr((struct sockaddr*)&sockaddr, &len)) {
622          LogPrintf("Cannot get sockaddr for %s: unsupported network\n", dest.ToStringAddrPort());
623          return {};
624      }
625  
626      if (!ConnectToSocket(*sock, (struct sockaddr*)&sockaddr, len, dest.ToStringAddrPort(), manual_connection)) {
627          return {};
628      }
629  
630      return sock;
631  }
632  
633  std::unique_ptr<Sock> Proxy::Connect() const
634  {
635      if (!IsValid()) {
636          LogPrintf("Cannot connect to invalid Proxy\n");
637          return {};
638      }
639  
640      if (!m_is_unix_socket) return ConnectDirectly(proxy, /*manual_connection=*/true);
641  
642  #if HAVE_SOCKADDR_UN
643      auto sock = CreateSock(AF_UNIX);
644      if (!sock) {
645          LogPrintLevel(BCLog::NET, BCLog::Level::Error, "Cannot create a socket for connecting to %s\n", m_unix_socket_path);
646          return {};
647      }
648  
649      const std::string path{m_unix_socket_path.substr(ADDR_PREFIX_UNIX.length())};
650  
651      struct sockaddr_un addrun;
652      memset(&addrun, 0, sizeof(addrun));
653      addrun.sun_family = AF_UNIX;
654      // leave the last char in addrun.sun_path[] to be always '\0'
655      memcpy(addrun.sun_path, path.c_str(), std::min(sizeof(addrun.sun_path) - 1, path.length()));
656      socklen_t len = sizeof(addrun);
657  
658      if(!ConnectToSocket(*sock, (struct sockaddr*)&addrun, len, path, /*manual_connection=*/true)) {
659          LogPrintf("Cannot connect to socket for %s\n", path);
660          return {};
661      }
662  
663      return sock;
664  #else
665      return {};
666  #endif
667  }
668  
669  bool SetProxy(enum Network net, const Proxy &addrProxy) {
670      assert(net >= 0 && net < NET_MAX);
671      if (!addrProxy.IsValid())
672          return false;
673      LOCK(g_proxyinfo_mutex);
674      proxyInfo[net] = addrProxy;
675      return true;
676  }
677  
678  bool GetProxy(enum Network net, Proxy &proxyInfoOut) {
679      assert(net >= 0 && net < NET_MAX);
680      LOCK(g_proxyinfo_mutex);
681      if (!proxyInfo[net].IsValid())
682          return false;
683      proxyInfoOut = proxyInfo[net];
684      return true;
685  }
686  
687  bool SetNameProxy(const Proxy &addrProxy) {
688      if (!addrProxy.IsValid())
689          return false;
690      LOCK(g_proxyinfo_mutex);
691      nameProxy = addrProxy;
692      return true;
693  }
694  
695  bool GetNameProxy(Proxy &nameProxyOut) {
696      LOCK(g_proxyinfo_mutex);
697      if(!nameProxy.IsValid())
698          return false;
699      nameProxyOut = nameProxy;
700      return true;
701  }
702  
703  bool HaveNameProxy() {
704      LOCK(g_proxyinfo_mutex);
705      return nameProxy.IsValid();
706  }
707  
708  bool IsProxy(const CNetAddr &addr) {
709      LOCK(g_proxyinfo_mutex);
710      for (int i = 0; i < NET_MAX; i++) {
711          if (addr == static_cast<CNetAddr>(proxyInfo[i].proxy))
712              return true;
713      }
714      return false;
715  }
716  
717  std::unique_ptr<Sock> ConnectThroughProxy(const Proxy& proxy,
718                                            const std::string& dest,
719                                            uint16_t port,
720                                            bool& proxy_connection_failed)
721  {
722      // first connect to proxy server
723      auto sock = proxy.Connect();
724      if (!sock) {
725          proxy_connection_failed = true;
726          return {};
727      }
728  
729      // do socks negotiation
730      if (proxy.m_randomize_credentials) {
731          ProxyCredentials random_auth;
732          static std::atomic_int counter(0);
733          random_auth.username = random_auth.password = strprintf("%i", counter++);
734          if (!Socks5(dest, port, &random_auth, *sock)) {
735              return {};
736          }
737      } else {
738          if (!Socks5(dest, port, nullptr, *sock)) {
739              return {};
740          }
741      }
742      return sock;
743  }
744  
745  CSubNet LookupSubNet(const std::string& subnet_str)
746  {
747      CSubNet subnet;
748      assert(!subnet.IsValid());
749      if (!ContainsNoNUL(subnet_str)) {
750          return subnet;
751      }
752  
753      const size_t slash_pos{subnet_str.find_last_of('/')};
754      const std::string str_addr{subnet_str.substr(0, slash_pos)};
755      std::optional<CNetAddr> addr{LookupHost(str_addr, /*fAllowLookup=*/false)};
756  
757      if (addr.has_value()) {
758          addr = static_cast<CNetAddr>(MaybeFlipIPv6toCJDNS(CService{addr.value(), /*port=*/0}));
759          if (slash_pos != subnet_str.npos) {
760              const std::string netmask_str{subnet_str.substr(slash_pos + 1)};
761              uint8_t netmask;
762              if (ParseUInt8(netmask_str, &netmask)) {
763                  // Valid number; assume CIDR variable-length subnet masking.
764                  subnet = CSubNet{addr.value(), netmask};
765              } else {
766                  // Invalid number; try full netmask syntax. Never allow lookup for netmask.
767                  const std::optional<CNetAddr> full_netmask{LookupHost(netmask_str, /*fAllowLookup=*/false)};
768                  if (full_netmask.has_value()) {
769                      subnet = CSubNet{addr.value(), full_netmask.value()};
770                  }
771              }
772          } else {
773              // Single IP subnet (<ipv4>/32 or <ipv6>/128).
774              subnet = CSubNet{addr.value()};
775          }
776      }
777  
778      return subnet;
779  }
780  
781  bool IsBadPort(uint16_t port)
782  {
783      /* Don't forget to update doc/p2p-bad-ports.md if you change this list. */
784  
785      switch (port) {
786      case 1:     // tcpmux
787      case 7:     // echo
788      case 9:     // discard
789      case 11:    // systat
790      case 13:    // daytime
791      case 15:    // netstat
792      case 17:    // qotd
793      case 19:    // chargen
794      case 20:    // ftp data
795      case 21:    // ftp access
796      case 22:    // ssh
797      case 23:    // telnet
798      case 25:    // smtp
799      case 37:    // time
800      case 42:    // name
801      case 43:    // nicname
802      case 53:    // domain
803      case 69:    // tftp
804      case 77:    // priv-rjs
805      case 79:    // finger
806      case 87:    // ttylink
807      case 95:    // supdup
808      case 101:   // hostname
809      case 102:   // iso-tsap
810      case 103:   // gppitnp
811      case 104:   // acr-nema
812      case 109:   // pop2
813      case 110:   // pop3
814      case 111:   // sunrpc
815      case 113:   // auth
816      case 115:   // sftp
817      case 117:   // uucp-path
818      case 119:   // nntp
819      case 123:   // NTP
820      case 135:   // loc-srv /epmap
821      case 137:   // netbios
822      case 139:   // netbios
823      case 143:   // imap2
824      case 161:   // snmp
825      case 179:   // BGP
826      case 389:   // ldap
827      case 427:   // SLP (Also used by Apple Filing Protocol)
828      case 465:   // smtp+ssl
829      case 512:   // print / exec
830      case 513:   // login
831      case 514:   // shell
832      case 515:   // printer
833      case 526:   // tempo
834      case 530:   // courier
835      case 531:   // chat
836      case 532:   // netnews
837      case 540:   // uucp
838      case 548:   // AFP (Apple Filing Protocol)
839      case 554:   // rtsp
840      case 556:   // remotefs
841      case 563:   // nntp+ssl
842      case 587:   // smtp (rfc6409)
843      case 601:   // syslog-conn (rfc3195)
844      case 636:   // ldap+ssl
845      case 989:   // ftps-data
846      case 990:   // ftps
847      case 993:   // ldap+ssl
848      case 995:   // pop3+ssl
849      case 1719:  // h323gatestat
850      case 1720:  // h323hostcall
851      case 1723:  // pptp
852      case 2049:  // nfs
853      case 3659:  // apple-sasl / PasswordServer
854      case 4045:  // lockd
855      case 5060:  // sip
856      case 5061:  // sips
857      case 6000:  // X11
858      case 6566:  // sane-port
859      case 6665:  // Alternate IRC
860      case 6666:  // Alternate IRC
861      case 6667:  // Standard IRC
862      case 6668:  // Alternate IRC
863      case 6669:  // Alternate IRC
864      case 6697:  // IRC + TLS
865      case 10080: // Amanda
866          return true;
867      }
868      return false;
869  }
870  
871  CService MaybeFlipIPv6toCJDNS(const CService& service)
872  {
873      CService ret{service};
874      if (ret.IsIPv6() && ret.HasCJDNSPrefix() && g_reachable_nets.Contains(NET_CJDNS)) {
875          ret.m_net = NET_CJDNS;
876      }
877      return ret;
878  }