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