1 // Copyright (c) 2009-2019 The Bitcoin Core developers
2 // Distributed under the MIT software license, see the accompanying
3 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
4 
5 #ifndef BITCOIN_NETBASE_H
6 #define BITCOIN_NETBASE_H
7 
8 #if defined(HAVE_CONFIG_H)
9 #include <config/bitcoin-config.h>
10 #endif
11 
12 #include <compat.h>
13 #include <netaddress.h>
14 #include <serialize.h>
15 #include <util/sock.h>
16 
17 #include <functional>
18 #include <memory>
19 #include <stdint.h>
20 #include <string>
21 #include <type_traits>
22 #include <vector>
23 
24 extern int nConnectTimeout;
25 extern bool fNameLookup;
26 
27 //! -timeout default
28 static const int DEFAULT_CONNECT_TIMEOUT = 5000;
29 //! -dns default
30 static const int DEFAULT_NAME_LOOKUP = true;
31 
32 enum class ConnectionDirection {
33     None = 0,
34     In = (1U << 0),
35     Out = (1U << 1),
36     Both = (In | Out),
37 };
38 static inline ConnectionDirection& operator|=(ConnectionDirection& a, ConnectionDirection b) {
39     using underlying = typename std::underlying_type<ConnectionDirection>::type;
40     a = ConnectionDirection(underlying(a) | underlying(b));
41     return a;
42 }
43 static inline bool operator&(ConnectionDirection a, ConnectionDirection b) {
44     using underlying = typename std::underlying_type<ConnectionDirection>::type;
45     return (underlying(a) & underlying(b));
46 }
47 
48 class proxyType
49 {
50 public:
proxyType()51     proxyType(): randomize_credentials(false) {}
proxy(_proxy)52     explicit proxyType(const CService &_proxy, bool _randomize_credentials=false): proxy(_proxy), randomize_credentials(_randomize_credentials) {}
53 
IsValid()54     bool IsValid() const { return proxy.IsValid(); }
55 
56     CService proxy;
57     bool randomize_credentials;
58 };
59 
60 /** Credentials for proxy authentication */
61 struct ProxyCredentials
62 {
63     std::string username;
64     std::string password;
65 };
66 
67 /**
68  * Wrapper for getaddrinfo(3). Do not use directly: call Lookup/LookupHost/LookupNumeric/LookupSubNet.
69  */
70 std::vector<CNetAddr> WrappedGetAddrInfo(const std::string& name, bool allow_lookup);
71 
72 enum Network ParseNetwork(const std::string& net);
73 std::string GetNetworkName(enum Network net);
74 /** Return a vector of publicly routable Network names; optionally append NET_UNROUTABLE. */
75 std::vector<std::string> GetNetworkNames(bool append_unroutable = false);
76 bool SetProxy(enum Network net, const proxyType &addrProxy);
77 bool GetProxy(enum Network net, proxyType &proxyInfoOut);
78 bool IsProxy(const CNetAddr &addr);
79 /**
80  * Set the name proxy to use for all connections to nodes specified by a
81  * hostname. After setting this proxy, connecting to a node specified by a
82  * hostname won't result in a local lookup of said hostname, rather, connect to
83  * the node by asking the name proxy for a proxy connection to the hostname,
84  * effectively delegating the hostname lookup to the specified proxy.
85  *
86  * This delegation increases privacy for those who set the name proxy as they no
87  * longer leak their external hostname queries to their DNS servers.
88  *
89  * @returns Whether or not the operation succeeded.
90  *
91  * @note SOCKS5's support for UDP-over-SOCKS5 has been considered, but no SOCK5
92  *       server in common use (most notably Tor) actually implements UDP
93  *       support, and a DNS resolver is beyond the scope of this project.
94  */
95 bool SetNameProxy(const proxyType &addrProxy);
96 bool HaveNameProxy();
97 bool GetNameProxy(proxyType &nameProxyOut);
98 
99 using DNSLookupFn = std::function<std::vector<CNetAddr>(const std::string&, bool)>;
100 extern DNSLookupFn g_dns_lookup;
101 
102 /**
103  * Resolve a host string to its corresponding network addresses.
104  *
105  * @param name    The string representing a host. Could be a name or a numerical
106  *                IP address (IPv6 addresses in their bracketed form are
107  *                allowed).
108  * @param[out] vIP The resulting network addresses to which the specified host
109  *                 string resolved.
110  *
111  * @returns Whether or not the specified host string successfully resolved to
112  *          any resulting network addresses.
113  *
114  * @see Lookup(const std::string&, std::vector<CService>&, uint16_t, bool, unsigned int, DNSLookupFn)
115  *      for additional parameter descriptions.
116  */
117 bool LookupHost(const std::string& name, std::vector<CNetAddr>& vIP, unsigned int nMaxSolutions, bool fAllowLookup, DNSLookupFn dns_lookup_function = g_dns_lookup);
118 
119 /**
120  * Resolve a host string to its first corresponding network address.
121  *
122  * @see LookupHost(const std::string&, std::vector<CNetAddr>&, uint16_t, bool, DNSLookupFn)
123  *      for additional parameter descriptions.
124  */
125 bool LookupHost(const std::string& name, CNetAddr& addr, bool fAllowLookup, DNSLookupFn dns_lookup_function = g_dns_lookup);
126 
127 /**
128  * Resolve a service string to its corresponding service.
129  *
130  * @param name    The string representing a service. Could be a name or a
131  *                numerical IP address (IPv6 addresses should be in their
132  *                disambiguated bracketed form), optionally followed by a uint16_t port
133  *                number. (e.g. example.com:8333 or
134  *                [2001:db8:85a3:8d3:1319:8a2e:370:7348]:420)
135  * @param[out] vAddr The resulting services to which the specified service string
136  *                   resolved.
137  * @param portDefault The default port for resulting services if not specified
138  *                    by the service string.
139  * @param fAllowLookup Whether or not hostname lookups are permitted. If yes,
140  *                     external queries may be performed.
141  * @param nMaxSolutions The maximum number of results we want, specifying 0
142  *                      means "as many solutions as we get."
143  *
144  * @returns Whether or not the service string successfully resolved to any
145  *          resulting services.
146  */
147 bool Lookup(const std::string& name, std::vector<CService>& vAddr, uint16_t portDefault, bool fAllowLookup, unsigned int nMaxSolutions, DNSLookupFn dns_lookup_function = g_dns_lookup);
148 
149 /**
150  * Resolve a service string to its first corresponding service.
151  *
152  * @see Lookup(const std::string&, std::vector<CService>&, uint16_t, bool, unsigned int, DNSLookupFn)
153  *      for additional parameter descriptions.
154  */
155 bool Lookup(const std::string& name, CService& addr, uint16_t portDefault, bool fAllowLookup, DNSLookupFn dns_lookup_function = g_dns_lookup);
156 
157 /**
158  * Resolve a service string with a numeric IP to its first corresponding
159  * service.
160  *
161  * @returns The resulting CService if the resolution was successful, [::]:0 otherwise.
162  *
163  * @see Lookup(const std::string&, std::vector<CService>&, uint16_t, bool, unsigned int, DNSLookupFn)
164  *      for additional parameter descriptions.
165  */
166 CService LookupNumeric(const std::string& name, uint16_t portDefault = 0, DNSLookupFn dns_lookup_function = g_dns_lookup);
167 
168 /**
169  * Parse and resolve a specified subnet string into the appropriate internal
170  * representation.
171  *
172  * @param strSubnet A string representation of a subnet of the form `network
173  *                address [ "/", ( CIDR-style suffix | netmask ) ]`(e.g.
174  *                `2001:db8::/32`, `192.0.2.0/255.255.255.0`, or `8.8.8.8`).
175  *
176  * @returns Whether the operation succeeded or not.
177  */
178 bool LookupSubNet(const std::string& strSubnet, CSubNet& subnet, DNSLookupFn dns_lookup_function = g_dns_lookup);
179 
180 /**
181  * Create a TCP socket in the given address family.
182  * @param[in] address_family The socket is created in the same address family as this address.
183  * @return pointer to the created Sock object or unique_ptr that owns nothing in case of failure
184  */
185 std::unique_ptr<Sock> CreateSockTCP(const CService& address_family);
186 
187 /**
188  * Socket factory. Defaults to `CreateSockTCP()`, but can be overridden by unit tests.
189  */
190 extern std::function<std::unique_ptr<Sock>(const CService&)> CreateSock;
191 
192 /**
193  * Try to connect to the specified service on the specified socket.
194  *
195  * @param addrConnect The service to which to connect.
196  * @param sock The socket on which to connect.
197  * @param nTimeout Wait this many milliseconds for the connection to be
198  *                 established.
199  * @param manual_connection Whether or not the connection was manually requested
200  *                          (e.g. through the addnode RPC)
201  *
202  * @returns Whether or not a connection was successfully made.
203  */
204 bool ConnectSocketDirectly(const CService &addrConnect, const Sock& sock, int nTimeout, bool manual_connection);
205 
206 /**
207  * Connect to a specified destination service through a SOCKS5 proxy by first
208  * connecting to the SOCKS5 proxy.
209  *
210  * @param proxy The SOCKS5 proxy.
211  * @param strDest The destination service to which to connect.
212  * @param port The destination port.
213  * @param sock The socket on which to connect to the SOCKS5 proxy.
214  * @param nTimeout Wait this many milliseconds for the connection to the SOCKS5
215  *                 proxy to be established.
216  * @param[out] outProxyConnectionFailed Whether or not the connection to the
217  *                                      SOCKS5 proxy failed.
218  *
219  * @returns Whether or not the operation succeeded.
220  */
221 bool ConnectThroughProxy(const proxyType& proxy, const std::string& strDest, uint16_t port, const Sock& sock, int nTimeout, bool& outProxyConnectionFailed);
222 
223 /** Disable or enable blocking-mode for a socket */
224 bool SetSocketNonBlocking(const SOCKET& hSocket, bool fNonBlocking);
225 /** Set the TCP_NODELAY flag on a socket */
226 bool SetSocketNoDelay(const SOCKET& hSocket);
227 void InterruptSocks5(bool interrupt);
228 
229 /**
230  * Connect to a specified destination service through an already connected
231  * SOCKS5 proxy.
232  *
233  * @param strDest The destination fully-qualified domain name.
234  * @param port The destination port.
235  * @param auth The credentials with which to authenticate with the specified
236  *             SOCKS5 proxy.
237  * @param socket The SOCKS5 proxy socket.
238  *
239  * @returns Whether or not the operation succeeded.
240  *
241  * @note The specified SOCKS5 proxy socket must already be connected to the
242  *       SOCKS5 proxy.
243  *
244  * @see <a href="https://www.ietf.org/rfc/rfc1928.txt">RFC1928: SOCKS Protocol
245  *      Version 5</a>
246  */
247 bool Socks5(const std::string& strDest, uint16_t port, const ProxyCredentials* auth, const Sock& socket);
248 
249 #endif // BITCOIN_NETBASE_H
250