X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=folly%2FSocketAddress.h;h=21c35a0546eab2c573ebffba5a509e04dbb19e8c;hb=67300dac6ed429facd7c6f5e03b7c245e32f8383;hp=788490d0e05b34694205584aacc6b0d0e2a074c5;hpb=c98aec4e22a8b71c7e5d6d35ebd2671be811ea2b;p=folly.git diff --git a/folly/SocketAddress.h b/folly/SocketAddress.h index 788490d0..21c35a05 100644 --- a/folly/SocketAddress.h +++ b/folly/SocketAddress.h @@ -1,5 +1,5 @@ /* - * Copyright 2016 Facebook, Inc. + * Copyright 2017 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -47,8 +47,7 @@ class SocketAddress { * This is potentially a very slow operation, so is disabled by * default. */ - SocketAddress(const char* host, uint16_t port, - bool allowNameLookup = false) { + SocketAddress(const char* host, uint16_t port, bool allowNameLookup = false) { // Initialize the address family first, // since setFromHostPort() and setFromIpPort() will check it. @@ -59,8 +58,10 @@ class SocketAddress { } } - SocketAddress(const std::string& host, uint16_t port, - bool allowNameLookup = false) { + SocketAddress( + const std::string& host, + uint16_t port, + bool allowNameLookup = false) { // Initialize the address family first, // since setFromHostPort() and setFromIpPort() will check it. @@ -151,7 +152,11 @@ class SocketAddress { bool isLoopbackAddress() const; void reset() { - prepFamilyChange(AF_UNSPEC); + if (external_) { + storage_.un.free(); + } + storage_.addr = folly::IPAddress(); + external_ = false; } /** @@ -301,6 +306,19 @@ class SocketAddress { setFromPath(StringPiece{path, length}); } + /** + * Construct a SocketAddress from a local unix socket path. + * + * Raises std::invalid_argument on error. + * + * @param path The Unix domain socket path. + */ + static SocketAddress makeFromPath(StringPiece path) { + SocketAddress addr; + addr.setFromPath(path); + return addr; + } + /** * Initialize this SocketAddress from a socket's peer address. * @@ -338,8 +356,7 @@ class SocketAddress { * enough for the full address type required by * address->sa_family. */ - void setFromSockaddr(const struct sockaddr* address, - socklen_t addrlen); + void setFromSockaddr(const struct sockaddr* address, socklen_t addrlen); /** * Initialize this SocketAddress from a struct sockaddr_in. @@ -363,9 +380,7 @@ class SocketAddress { * the valid bytes of sun_path, not including any NUL * terminator. */ - void setFromSockaddr(const struct sockaddr_un* address, - socklen_t addrlen); - + void setFromSockaddr(const struct sockaddr_un* address, socklen_t addrlen); /** * Fill in a given sockaddr_storage with the ip or unix address. @@ -388,7 +403,7 @@ class SocketAddress { sa_family_t getFamily() const { DCHECK(external_ || AF_UNIX != storage_.addr.family()); - return external_ ? AF_UNIX : storage_.addr.family(); + return external_ ? sa_family_t(AF_UNIX) : storage_.addr.family(); } bool empty() const { @@ -411,6 +426,11 @@ class SocketAddress { */ void getAddressStr(char* buf, size_t buflen) const; + /** + * Return true if it is a valid IPv4 or IPv6 address. + */ + bool isFamilyInet() const; + /** * For v4 & v6 addresses, return the fully qualified address string */ @@ -436,8 +456,7 @@ class SocketAddress { * Return true if this is an IPv4-mapped IPv6 address. */ bool isIPv4Mapped() const { - return (getFamily() == AF_INET6 && - storage_.addr.isIPv4Mapped()); + return (getFamily() == AF_INET6 && storage_.addr.isIPv4Mapped()); } /** @@ -531,41 +550,29 @@ class SocketAddress { * the heap. */ struct ExternalUnixAddr { - struct sockaddr_un *addr; + struct sockaddr_un* addr; socklen_t len; - /* For debugging only, will be removed */ - uint64_t magic; - static constexpr uint64_t kMagic = 0x1234faceb00c; - socklen_t pathLength() const { - return len - offsetof(struct sockaddr_un, sun_path); + return socklen_t(len - offsetof(struct sockaddr_un, sun_path)); } void init() { - addr = new sockaddr_un; - magic = kMagic; + addr = new struct sockaddr_un; addr->sun_family = AF_UNIX; len = 0; } - void init(const ExternalUnixAddr &other) { - addr = new sockaddr_un; - magic = kMagic; + void init(const ExternalUnixAddr& other) { + addr = new struct sockaddr_un; len = other.len; - memcpy(addr, other.addr, len); - // Fill the rest with 0s, just for safety - memset(reinterpret_cast(addr) + len, 0, - sizeof(struct sockaddr_un) - len); + memcpy(addr, other.addr, size_t(len)); } - void copy(const ExternalUnixAddr &other) { - CHECK(magic == kMagic); + void copy(const ExternalUnixAddr& other) { len = other.len; - memcpy(addr, other.addr, len); + memcpy(addr, other.addr, size_t(len)); } void free() { - CHECK(magic == kMagic); delete addr; - magic = 0; } }; @@ -575,25 +582,10 @@ class SocketAddress { void setFromLocalAddr(const struct addrinfo* results); void setFromSocket(int socket, int (*fn)(int, struct sockaddr*, socklen_t*)); std::string getIpString(int flags) const; - void getIpString(char *buf, size_t buflen, int flags) const; + void getIpString(char* buf, size_t buflen, int flags) const; void updateUnixAddressLength(socklen_t addrlen); - void prepFamilyChange(sa_family_t newFamily) { - if (newFamily != AF_UNIX) { - if (external_) { - storage_.un.free(); - storage_.addr = folly::IPAddress(); - } - external_ = false; - } else { - if (!external_) { - storage_.un.init(); - } - external_ = true; - } - } - /* * storage_ contains room for a full IPv4 or IPv6 address, so they can be * stored inline without a separate allocation on the heap. @@ -621,18 +613,15 @@ class SocketAddress { size_t hash_value(const SocketAddress& address); std::ostream& operator<<(std::ostream& os, const SocketAddress& addr); - -} +} // namespace folly namespace std { // Provide an implementation for std::hash -template<> +template <> struct hash { - size_t operator()( - const folly::SocketAddress& addr) const { + size_t operator()(const folly::SocketAddress& addr) const { return addr.hash(); } }; - -} +} // namespace std