Fixed documentation in folly/Random.h
[folly.git] / folly / SocketAddress.h
1 /*
2  * Copyright 2017 Facebook, Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *   http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #pragma once
18
19 #include <sys/types.h>
20 #include <cstddef>
21 #include <iosfwd>
22 #include <string>
23
24 #include <folly/IPAddress.h>
25 #include <folly/Portability.h>
26 #include <folly/Range.h>
27 #include <folly/portability/Sockets.h>
28
29 namespace folly {
30
31 class SocketAddress {
32  public:
33   SocketAddress() = default;
34
35   /**
36    * Construct a SocketAddress from a hostname and port.
37    *
38    * Note: If the host parameter is not a numeric IP address, hostname
39    * resolution will be performed, which can be quite slow.
40    *
41    * Raises std::system_error on error.
42    *
43    * @param host The IP address (or hostname, if allowNameLookup is true)
44    * @param port The port (in host byte order)
45    * @pram allowNameLookup  If true, attempt to perform hostname lookup
46    *        if the hostname does not appear to be a numeric IP address.
47    *        This is potentially a very slow operation, so is disabled by
48    *        default.
49    */
50   SocketAddress(const char* host, uint16_t port,
51                  bool allowNameLookup = false) {
52     // Initialize the address family first,
53     // since setFromHostPort() and setFromIpPort() will check it.
54
55     if (allowNameLookup) {
56       setFromHostPort(host, port);
57     } else {
58       setFromIpPort(host, port);
59     }
60   }
61
62   SocketAddress(const std::string& host, uint16_t port,
63                  bool allowNameLookup = false) {
64     // Initialize the address family first,
65     // since setFromHostPort() and setFromIpPort() will check it.
66
67     if (allowNameLookup) {
68       setFromHostPort(host.c_str(), port);
69     } else {
70       setFromIpPort(host.c_str(), port);
71     }
72   }
73
74   SocketAddress(const IPAddress& ipAddr, uint16_t port) {
75     setFromIpAddrPort(ipAddr, port);
76   }
77
78   SocketAddress(const SocketAddress& addr) {
79     port_ = addr.port_;
80     if (addr.getFamily() == AF_UNIX) {
81       storage_.un.init(addr.storage_.un);
82     } else {
83       storage_ = addr.storage_;
84     }
85     external_ = addr.external_;
86   }
87
88   SocketAddress& operator=(const SocketAddress& addr) {
89     if (!external_) {
90       if (addr.getFamily() != AF_UNIX) {
91         storage_ = addr.storage_;
92       } else {
93         storage_ = addr.storage_;
94         storage_.un.init(addr.storage_.un);
95       }
96     } else {
97       if (addr.getFamily() == AF_UNIX) {
98         storage_.un.copy(addr.storage_.un);
99       } else {
100         storage_.un.free();
101         storage_ = addr.storage_;
102       }
103     }
104     port_ = addr.port_;
105     external_ = addr.external_;
106     return *this;
107   }
108
109   SocketAddress(SocketAddress&& addr) noexcept {
110     storage_ = addr.storage_;
111     port_ = addr.port_;
112     external_ = addr.external_;
113     addr.external_ = false;
114   }
115
116   SocketAddress& operator=(SocketAddress&& addr) {
117     std::swap(storage_, addr.storage_);
118     std::swap(port_, addr.port_);
119     std::swap(external_, addr.external_);
120     return *this;
121   }
122
123   ~SocketAddress() {
124     if (external_) {
125       storage_.un.free();
126     }
127   }
128
129   bool isInitialized() const {
130     return (getFamily() != AF_UNSPEC);
131   }
132
133   /**
134    * Return whether this address is within private network.
135    *
136    * According to RFC1918, the 10/8 prefix, 172.16/12 prefix, and 192.168/16
137    * prefix are reserved for private networks.
138    * fc00::/7 is the IPv6 version, defined in RFC4139.  IPv6 link-local
139    * addresses (fe80::/10) are also considered private addresses.
140    *
141    * The loopback addresses 127/8 and ::1 are also regarded as private networks
142    * for the purpose of this function.
143    *
144    * Returns true if this is a private network address, and false otherwise.
145    */
146   bool isPrivateAddress() const;
147
148   /**
149    * Return whether this address is a loopback address.
150    */
151   bool isLoopbackAddress() const;
152
153   void reset() {
154     if (external_) {
155       storage_.un.free();
156     }
157     storage_.addr = folly::IPAddress();
158     external_ = false;
159   }
160
161   /**
162    * Initialize this SocketAddress from a hostname and port.
163    *
164    * Note: If the host parameter is not a numeric IP address, hostname
165    * resolution will be performed, which can be quite slow.
166    *
167    * If the hostname resolves to multiple addresses, only the first will be
168    * returned.
169    *
170    * Raises std::system_error on error.
171    *
172    * @param host The hostname or IP address
173    * @param port The port (in host byte order)
174    */
175   void setFromHostPort(const char* host, uint16_t port);
176
177   void setFromHostPort(const std::string& host, uint16_t port) {
178     setFromHostPort(host.c_str(), port);
179   }
180
181   /**
182    * Initialize this SocketAddress from an IP address and port.
183    *
184    * This is similar to setFromHostPort(), but only accepts numeric IP
185    * addresses.  If the IP string does not look like an IP address, it throws a
186    * std::invalid_argument rather than trying to perform a hostname resolution.
187    *
188    * Raises std::system_error on error.
189    *
190    * @param ip The IP address, as a human-readable string.
191    * @param port The port (in host byte order)
192    */
193   void setFromIpPort(const char* ip, uint16_t port);
194
195   void setFromIpPort(const std::string& ip, uint16_t port) {
196     setFromIpPort(ip.c_str(), port);
197   }
198
199   /**
200    * Initialize this SocketAddress from an IPAddress struct and port.
201    *
202    * @param ip The IP address in IPAddress format
203    * @param port The port (in host byte order)
204    */
205   void setFromIpAddrPort(const IPAddress& ip, uint16_t port);
206
207   /**
208    * Initialize this SocketAddress from a local port number.
209    *
210    * This is intended to be used by server code to determine the address to
211    * listen on.
212    *
213    * If the current machine has any IPv6 addresses configured, an IPv6 address
214    * will be returned (since connections from IPv4 clients can be mapped to the
215    * IPv6 address).  If the machine does not have any IPv6 addresses, an IPv4
216    * address will be returned.
217    */
218   void setFromLocalPort(uint16_t port);
219
220   /**
221    * Initialize this SocketAddress from a local port number.
222    *
223    * This version of setFromLocalPort() accepts the port as a string.  A
224    * std::invalid_argument will be raised if the string does not refer to a port
225    * number.  Non-numeric service port names are not accepted.
226    */
227   void setFromLocalPort(const char* port);
228   void setFromLocalPort(const std::string& port) {
229     return setFromLocalPort(port.c_str());
230   }
231
232   /**
233    * Initialize this SocketAddress from a local port number and optional IP
234    * address.
235    *
236    * The addressAndPort string may be specified either as "<ip>:<port>", or
237    * just as "<port>".  If the IP is not specified, the address will be
238    * initialized to 0, so that a server socket bound to this address will
239    * accept connections on all local IP addresses.
240    *
241    * Both the IP address and port number must be numeric.  DNS host names and
242    * non-numeric service port names are not accepted.
243    */
244   void setFromLocalIpPort(const char* addressAndPort);
245   void setFromLocalIpPort(const std::string& addressAndPort) {
246     return setFromLocalIpPort(addressAndPort.c_str());
247   }
248
249   /**
250    * Initialize this SocketAddress from an IP address and port number.
251    *
252    * The addressAndPort string must be of the form "<ip>:<port>".  E.g.,
253    * "10.0.0.1:1234".
254    *
255    * Both the IP address and port number must be numeric.  DNS host names and
256    * non-numeric service port names are not accepted.
257    */
258   void setFromIpPort(const char* addressAndPort);
259   void setFromIpPort(const std::string& addressAndPort) {
260     return setFromIpPort(addressAndPort.c_str());
261   }
262
263   /**
264    * Initialize this SocketAddress from a host name and port number.
265    *
266    * The addressAndPort string must be of the form "<host>:<port>".  E.g.,
267    * "www.facebook.com:443".
268    *
269    * If the host name is not a numeric IP address, a DNS lookup will be
270    * performed.  Beware that the DNS lookup may be very slow.  The port number
271    * must be numeric; non-numeric service port names are not accepted.
272    */
273   void setFromHostPort(const char* hostAndPort);
274   void setFromHostPort(const std::string& hostAndPort) {
275     return setFromHostPort(hostAndPort.c_str());
276   }
277
278   /**
279    * Returns the port number from the given socketaddr structure.
280    *
281    * Currently only IPv4 and IPv6 are supported.
282    *
283    * Returns -1 for unsupported socket families.
284    */
285   static int getPortFrom(const struct sockaddr* address);
286
287   /**
288    * Returns the family name from the given socketaddr structure (e.g.: AF_INET6
289    * for IPv6).
290    *
291    * Returns `defaultResult` for unsupported socket families.
292    */
293   static const char* getFamilyNameFrom(
294       const struct sockaddr* address,
295       const char* defaultResult = nullptr);
296
297   /**
298    * Initialize this SocketAddress from a local unix path.
299    *
300    * Raises std::invalid_argument on error.
301    */
302   void setFromPath(StringPiece path);
303
304   void setFromPath(const char* path, size_t length) {
305     setFromPath(StringPiece{path, length});
306   }
307
308   /**
309    * Initialize this SocketAddress from a socket's peer address.
310    *
311    * Raises std::system_error on error.
312    */
313   void setFromPeerAddress(int socket);
314
315   /**
316    * Initialize this SocketAddress from a socket's local address.
317    *
318    * Raises std::system_error on error.
319    */
320   void setFromLocalAddress(int socket);
321
322   /**
323    * Initialize this folly::SocketAddress from a struct sockaddr.
324    *
325    * Raises std::system_error on error.
326    *
327    * This method is not supported for AF_UNIX addresses.  For unix addresses,
328    * the address length must be explicitly specified.
329    *
330    * @param address  A struct sockaddr.  The size of the address is implied
331    *                 from address->sa_family.
332    */
333   void setFromSockaddr(const struct sockaddr* address);
334
335   /**
336    * Initialize this SocketAddress from a struct sockaddr.
337    *
338    * Raises std::system_error on error.
339    *
340    * @param address  A struct sockaddr.
341    * @param addrlen  The length of address data available.  This must be long
342    *                 enough for the full address type required by
343    *                 address->sa_family.
344    */
345   void setFromSockaddr(const struct sockaddr* address,
346                        socklen_t addrlen);
347
348   /**
349    * Initialize this SocketAddress from a struct sockaddr_in.
350    */
351   void setFromSockaddr(const struct sockaddr_in* address);
352
353   /**
354    * Initialize this SocketAddress from a struct sockaddr_in6.
355    */
356   void setFromSockaddr(const struct sockaddr_in6* address);
357
358   /**
359    * Initialize this SocketAddress from a struct sockaddr_un.
360    *
361    * Note that the addrlen parameter is necessary to properly detect anonymous
362    * addresses, which have 0 valid path bytes, and may not even have a NUL
363    * character at the start of the path.
364    *
365    * @param address  A struct sockaddr_un.
366    * @param addrlen  The length of address data.  This should include all of
367    *                 the valid bytes of sun_path, not including any NUL
368    *                 terminator.
369    */
370   void setFromSockaddr(const struct sockaddr_un* address,
371                        socklen_t addrlen);
372
373
374   /**
375    * Fill in a given sockaddr_storage with the ip or unix address.
376    *
377    * Returns the actual size of the storage used.
378    */
379   socklen_t getAddress(sockaddr_storage* addr) const {
380     if (!external_) {
381       return storage_.addr.toSockaddrStorage(addr, htons(port_));
382     } else {
383       memcpy(addr, storage_.un.addr, sizeof(*storage_.un.addr));
384       return storage_.un.len;
385     }
386   }
387
388   const folly::IPAddress& getIPAddress() const;
389
390   // Deprecated: getAddress() above returns the same size as getActualSize()
391   socklen_t getActualSize() const;
392
393   sa_family_t getFamily() const {
394     DCHECK(external_ || AF_UNIX != storage_.addr.family());
395     return external_ ? sa_family_t(AF_UNIX) : storage_.addr.family();
396   }
397
398   bool empty() const {
399     return getFamily() == AF_UNSPEC;
400   }
401
402   /**
403    * Get a string representation of the IPv4 or IPv6 address.
404    *
405    * Raises std::invalid_argument if an error occurs (for example, if
406    * the address is not an IPv4 or IPv6 address).
407    */
408   std::string getAddressStr() const;
409
410   /**
411    * Get a string representation of the IPv4 or IPv6 address.
412    *
413    * Raises std::invalid_argument if an error occurs (for example, if
414    * the address is not an IPv4 or IPv6 address).
415    */
416   void getAddressStr(char* buf, size_t buflen) const;
417
418   /**
419    * Return true if it is a valid IPv4 or IPv6 address.
420    */
421   bool isFamilyInet() const;
422
423   /**
424    * For v4 & v6 addresses, return the fully qualified address string
425    */
426   std::string getFullyQualified() const;
427
428   /**
429    * Get the IPv4 or IPv6 port for this address.
430    *
431    * Raises std::invalid_argument if this is not an IPv4 or IPv6 address.
432    *
433    * @return Returns the port, in host byte order.
434    */
435   uint16_t getPort() const;
436
437   /**
438    * Set the IPv4 or IPv6 port for this address.
439    *
440    * Raises std::invalid_argument if this is not an IPv4 or IPv6 address.
441    */
442   void setPort(uint16_t port);
443
444   /**
445    * Return true if this is an IPv4-mapped IPv6 address.
446    */
447   bool isIPv4Mapped() const {
448     return (getFamily() == AF_INET6 &&
449             storage_.addr.isIPv4Mapped());
450   }
451
452   /**
453    * Convert an IPv4-mapped IPv6 address to an IPv4 address.
454    *
455    * Raises std::invalid_argument if this is not an IPv4-mapped IPv6 address.
456    */
457   void convertToIPv4();
458
459   /**
460    * Try to convert an address to IPv4.
461    *
462    * This attempts to convert an address to an IPv4 address if possible.
463    * If the address is an IPv4-mapped IPv6 address, it is converted to an IPv4
464    * address and true is returned.  Otherwise nothing is done, and false is
465    * returned.
466    */
467   bool tryConvertToIPv4();
468
469   /**
470    * Convert an IPv4 address to IPv6 [::ffff:a.b.c.d]
471    */
472
473   bool mapToIPv6();
474
475   /**
476    * Get string representation of the host name (or IP address if the host name
477    * cannot be resolved).
478    *
479    * Warning: Using this method is strongly discouraged.  It performs a
480    * DNS lookup, which may block for many seconds.
481    *
482    * Raises std::invalid_argument if an error occurs.
483    */
484   std::string getHostStr() const;
485
486   /**
487    * Get the path name for a Unix domain socket.
488    *
489    * Returns a std::string containing the path.  For anonymous sockets, an
490    * empty string is returned.
491    *
492    * For addresses in the abstract namespace (Linux-specific), a std::string
493    * containing binary data is returned.  In this case the first character will
494    * always be a NUL character.
495    *
496    * Raises std::invalid_argument if called on a non-Unix domain socket.
497    */
498   std::string getPath() const;
499
500   /**
501    * Get human-readable string representation of the address.
502    *
503    * This prints a string representation of the address, for human consumption.
504    * For IP addresses, the string is of the form "<IP>:<port>".
505    */
506   std::string describe() const;
507
508   bool operator==(const SocketAddress& other) const;
509   bool operator!=(const SocketAddress& other) const {
510     return !(*this == other);
511   }
512
513   /**
514    * Check whether the first N bits of this address match the first N
515    * bits of another address.
516    * @note returns false if the addresses are not from the same
517    *       address family or if the family is neither IPv4 nor IPv6
518    */
519   bool prefixMatch(const SocketAddress& other, unsigned prefixLength) const;
520
521   /**
522    * Use this operator for storing maps based on SocketAddress.
523    */
524   bool operator<(const SocketAddress& other) const;
525
526   /**
527    * Compuate a hash of a SocketAddress.
528    */
529   size_t hash() const;
530
531  private:
532   /**
533    * Unix socket addresses require more storage than IPv4 and IPv6 addresses,
534    * and are comparatively little-used.
535    *
536    * Therefore SocketAddress' internal storage_ member variable doesn't
537    * contain room for a full unix address, to avoid wasting space in the common
538    * case.  When we do need to store a Unix socket address, we use this
539    * ExternalUnixAddr structure to allocate a struct sockaddr_un separately on
540    * the heap.
541    */
542   struct ExternalUnixAddr {
543     struct sockaddr_un *addr;
544     socklen_t len;
545
546     /* For debugging only, will be removed */
547     uint64_t magic;
548     static constexpr uint64_t kMagic = 0x1234faceb00c;
549
550     socklen_t pathLength() const {
551       return socklen_t(len - offsetof(struct sockaddr_un, sun_path));
552     }
553
554     void init() {
555       addr = new sockaddr_un;
556       magic = kMagic;
557       addr->sun_family = AF_UNIX;
558       len = 0;
559     }
560     void init(const ExternalUnixAddr &other) {
561       addr = new sockaddr_un;
562       magic = kMagic;
563       len = other.len;
564       memcpy(addr, other.addr, size_t(len));
565       // Fill the rest with 0s, just for safety
566       memset(reinterpret_cast<char*>(addr) + len, 0,
567              sizeof(struct sockaddr_un) - len);
568     }
569     void copy(const ExternalUnixAddr &other) {
570       CHECK(magic == kMagic);
571       len = other.len;
572       memcpy(addr, other.addr, size_t(len));
573     }
574     void free() {
575       CHECK(magic == kMagic);
576       delete addr;
577       magic = 0;
578     }
579   };
580
581   struct addrinfo* getAddrInfo(const char* host, uint16_t port, int flags);
582   struct addrinfo* getAddrInfo(const char* host, const char* port, int flags);
583   void setFromAddrInfo(const struct addrinfo* results);
584   void setFromLocalAddr(const struct addrinfo* results);
585   void setFromSocket(int socket, int (*fn)(int, struct sockaddr*, socklen_t*));
586   std::string getIpString(int flags) const;
587   void getIpString(char *buf, size_t buflen, int flags) const;
588
589   void updateUnixAddressLength(socklen_t addrlen);
590
591   /*
592    * storage_ contains room for a full IPv4 or IPv6 address, so they can be
593    * stored inline without a separate allocation on the heap.
594    *
595    * If we need to store a Unix socket address, ExternalUnixAddr is a shim to
596    * track a struct sockaddr_un allocated separately on the heap.
597    */
598   union AddrStorage {
599     folly::IPAddress addr;
600     ExternalUnixAddr un;
601     AddrStorage() : addr() {}
602   } storage_{};
603   // IPAddress class does nto save zone or port, and must be saved here
604   uint16_t port_;
605
606   bool external_{false};
607 };
608
609 /**
610  * Hash a SocketAddress object.
611  *
612  * boost::hash uses hash_value(), so this allows boost::hash to automatically
613  * work for SocketAddress.
614  */
615 size_t hash_value(const SocketAddress& address);
616
617 std::ostream& operator<<(std::ostream& os, const SocketAddress& addr);
618
619 }
620
621 namespace std {
622
623 // Provide an implementation for std::hash<SocketAddress>
624 template<>
625 struct hash<folly::SocketAddress> {
626   size_t operator()(
627       const folly::SocketAddress& addr) const {
628     return addr.hash();
629   }
630 };
631
632 }