Inside Bitcoin
Opening the selected file…
Inside Bitcoin
Opening the selected file…
The code behind the network, with room to understand it.
Release published 2026-10-28 · Snapshot fetched 2026-11-01. Latest stable release at fetch time; development branches and Git history are excluded. Only the selected code window and visible folders load here.
751}753bool HaveNameProxy() {754LOCK(g_proxyinfo_mutex);755return nameProxy.IsValid();756}758bool IsProxy(const CNetAddr &addr) {759LOCK(g_proxyinfo_mutex);760for (int i = 0; i < NET_MAX; i++) {761if (addr == static_cast<CNetAddr>(proxyInfo[i].proxy))762return true;763}764return false;765}767/**768* Generate unique credentials for Tor stream isolation. Tor will create769* separate circuits for SOCKS5 proxy connections with different credentials, which770* makes it harder to correlate the connections.771*/772class TorStreamIsolationCredentialsGenerator773{774public:775TorStreamIsolationCredentialsGenerator():776m_prefix(GenerateUniquePrefix()) {777}779/** Return the next unique proxy credentials. */780ProxyCredentials Generate() {781ProxyCredentials auth;782auth.username = auth.password = strprintf("%s%i", m_prefix, m_counter);783++m_counter;784return auth;785}787/** Size of session prefix in bytes. */788static constexpr size_t PREFIX_BYTE_LENGTH = 8;789private:790const std::string m_prefix;791std::atomic<uint64_t> m_counter;793/** Generate a random prefix for each of the credentials returned by this generator.794* This makes sure that different launches of the application (either successively or in parallel)795* will not share the same circuits, as would be the case with a bare counter.796*/797static std::string GenerateUniquePrefix() {798std::array<uint8_t, PREFIX_BYTE_LENGTH> prefix_bytes;799GetRandBytes(prefix_bytes);800return HexStr(prefix_bytes) + "-";801}802};804std::unique_ptr<Sock> ConnectThroughProxy(const Proxy& proxy,805const std::string& dest,806uint16_t port,807bool& proxy_connection_failed)808{809// first connect to proxy server810auto sock = proxy.Connect();811if (!sock) {812proxy_connection_failed = true;813return {};814}816// do socks negotiation817if (proxy.m_tor_stream_isolation) {818static TorStreamIsolationCredentialsGenerator generator;819ProxyCredentials random_auth{generator.Generate()};820if (!Socks5(dest, port, &random_auth, *sock)) {821return {};822}823} else {824if (!Socks5(dest, port, nullptr, *sock)) {825return {};826}827}828return sock;829}831CSubNet LookupSubNet(const std::string& subnet_str)832{833CSubNet subnet;834assert(!subnet.IsValid());835if (ContainsNUL(subnet_str)) {836return subnet;837}839const size_t slash_pos{subnet_str.find_last_of('/')};840const std::string str_addr{subnet_str.substr(0, slash_pos)};841std::optional<CNetAddr> addr{LookupHost(str_addr, /*fAllowLookup=*/false)};843if (addr.has_value()) {844addr = static_cast<CNetAddr>(MaybeFlipIPv6toCJDNS(CService{addr.value(), /*port=*/0}));845if (slash_pos != subnet_str.npos) {846const std::string netmask_str{subnet_str.substr(slash_pos + 1)};847if (const auto netmask{ToIntegral<uint8_t>(netmask_str)}) {848// Valid number; assume CIDR variable-length subnet masking.849subnet = CSubNet{addr.value(), *netmask};850} else {851// Invalid number; try full netmask syntax. Never allow lookup for netmask.852const std::optional<CNetAddr> full_netmask{LookupHost(netmask_str, /*fAllowLookup=*/false)};853if (full_netmask.has_value()) {854subnet = CSubNet{addr.value(), full_netmask.value()};855}856}857} else {858// Single IP subnet (<ipv4>/32 or <ipv6>/128).859subnet = CSubNet{addr.value()};860}861}863return subnet;864}866bool IsBadPort(uint16_t port)867{868/* Don't forget to update doc/p2p-bad-ports.md if you change this list. */870switch (port) {871case 1: // tcpmux872case 7: // echo873case 9: // discard874case 11: // systat875case 13: // daytime876case 15: // netstat877case 17: // qotd878case 19: // chargen879case 20: // ftp data880case 21: // ftp access881case 22: // ssh882case 23: // telnet883case 25: // smtp884case 37: // time885case 42: // name886case 43: // nicname887case 53: // domain888case 69: // tftp889case 77: // priv-rjs890case 79: // finger891case 87: // ttylink892case 95: // supdup893case 101: // hostname894case 102: // iso-tsap895case 103: // gppitnp896case 104: // acr-nema897case 109: // pop2898case 110: // pop3899case 111: // sunrpc900case 113: // auth901case 115: // sftp902case 117: // uucp-path903case 119: // nntp904case 123: // NTP905case 135: // loc-srv /epmap906case 137: // netbios907case 139: // netbios908case 143: // imap2909case 161: // snmp910case 179: // BGP911case 389: // ldap912case 427: // SLP (Also used by Apple Filing Protocol)913case 465: // smtp+ssl914case 512: // print / exec915case 513: // login916case 514: // shell917case 515: // printer918case 526: // tempo919case 530: // courier920case 531: // chat921case 532: // netnews922case 540: // uucp923case 548: // AFP (Apple Filing Protocol)924case 554: // rtsp925case 556: // remotefs926case 563: // nntp+ssl927case 587: // smtp (rfc6409)928case 601: // syslog-conn (rfc3195)929case 636: // ldap+ssl930case 989: // ftps-data931case 990: // ftps932case 993: // ldap+ssl933case 995: // pop3+ssl934case 1719: // h323gatestat935case 1720: // h323hostcall936case 1723: // pptp937case 2049: // nfs938case 3306: // MySQL939case 3389: // RDP / Windows Remote Desktop940case 3659: // apple-sasl / PasswordServer941case 4045: // lockd942case 5060: // sip943case 5061: // sips944case 5432: // PostgreSQL945case 5900: // VNC946case 6000: // X11947case 6566: // sane-port948case 6665: // Alternate IRC949case 6666: // Alternate IRC950case 6667: // Standard IRC951case 6668: // Alternate IRC952case 6669: // Alternate IRC953case 6697: // IRC + TLS954case 10080: // Amanda955case 27017: // MongoDB956return true;957}958return false;959}961CService MaybeFlipIPv6toCJDNS(const CService& service)962{963CService ret{service};964if (ret.IsIPv6() && ret.HasCJDNSPrefix() && g_reachable_nets.Contains(NET_CJDNS)) {965ret.m_net = NET_CJDNS;966}967return ret;968}970CService GetBindAddress(const Sock& sock)971{972CService addr_bind;973sockaddr_storage storage;974socklen_t len = sizeof(storage);976auto sa = reinterpret_cast<sockaddr*>(&storage);978if (sock.GetSockName(sa, &len) == 0) {979addr_bind.SetSockAddr(sa, len);980} else {981LogWarning("getsockname failed\n");982}983return addr_bind;984}