X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=folly%2FSocketAddress.h;h=21c35a0546eab2c573ebffba5a509e04dbb19e8c;hb=6283c759b82a2a5764ef77c025aee1d40a77a839;hp=4f0d9cfc258539ad108d3c1b00ba7b9a606083c7;hpb=aa6e8869f59cab90bae4e3be69619d6c2ce1b3e7;p=folly.git diff --git a/folly/SocketAddress.h b/folly/SocketAddress.h index 4f0d9cfc..21c35a05 100644 --- a/folly/SocketAddress.h +++ b/folly/SocketAddress.h @@ -1,5 +1,5 @@ /* - * Copyright 2015 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. @@ -17,16 +17,14 @@ #pragma once #include -#include -#include -#include -#include #include -#include +#include #include #include #include +#include +#include namespace folly { @@ -49,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. @@ -61,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. @@ -153,7 +152,11 @@ class SocketAddress { bool isLoopbackAddress() const; void reset() { - prepFamilyChange(AF_UNSPEC); + if (external_) { + storage_.un.free(); + } + storage_.addr = folly::IPAddress(); + external_ = false; } /** @@ -273,37 +276,62 @@ class SocketAddress { return setFromHostPort(hostAndPort.c_str()); } + /** + * Returns the port number from the given socketaddr structure. + * + * Currently only IPv4 and IPv6 are supported. + * + * Returns -1 for unsupported socket families. + */ + static int getPortFrom(const struct sockaddr* address); + + /** + * Returns the family name from the given socketaddr structure (e.g.: AF_INET6 + * for IPv6). + * + * Returns `defaultResult` for unsupported socket families. + */ + static const char* getFamilyNameFrom( + const struct sockaddr* address, + const char* defaultResult = nullptr); + /** * Initialize this SocketAddress from a local unix path. * * Raises std::invalid_argument on error. */ - void setFromPath(const char* path) { - setFromPath(path, strlen(path)); - } + void setFromPath(StringPiece path); - void setFromPath(const std::string& path) { - setFromPath(path.data(), path.length()); + void setFromPath(const char* path, size_t length) { + setFromPath(StringPiece{path, length}); } - void setFromPath(const char* path, size_t length); - - // a typedef that allow us to compile against both winsock & POSIX sockets: - using SocketDesc = decltype(socket(0,0,0)); // POSIX: int, winsock: unsigned + /** + * 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. * * Raises std::system_error on error. */ - void setFromPeerAddress(SocketDesc socket); + void setFromPeerAddress(int socket); /** * Initialize this SocketAddress from a socket's local address. * * Raises std::system_error on error. */ - void setFromLocalAddress(SocketDesc socket); + void setFromLocalAddress(int socket); /** * Initialize this folly::SocketAddress from a struct sockaddr. @@ -328,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. @@ -353,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. @@ -378,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 { @@ -401,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 */ @@ -426,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()); } /** @@ -521,77 +550,42 @@ 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; } }; - // a typedef that allow us to compile against both winsock & POSIX sockets: - // (both arg types and calling conventions differ for both) - // POSIX: void setFromSocket(int socket, - // int(*fn)(int, struct sockaddr*, socklen_t*)); - // mingw: void setFromSocket(unsigned socket, - // int(*fn)(unsigned, struct sockaddr*, socklen_t*)); - using GetPeerNameFunc = decltype(getpeername); - struct addrinfo* getAddrInfo(const char* host, uint16_t port, int flags); struct addrinfo* getAddrInfo(const char* host, const char* port, int flags); void setFromAddrInfo(const struct addrinfo* results); void setFromLocalAddr(const struct addrinfo* results); - void setFromSocket(SocketDesc socket, GetPeerNameFunc fn); + 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. @@ -599,9 +593,10 @@ class SocketAddress { * If we need to store a Unix socket address, ExternalUnixAddr is a shim to * track a struct sockaddr_un allocated separately on the heap. */ - union { - folly::IPAddress addr{}; + union AddrStorage { + folly::IPAddress addr; ExternalUnixAddr un; + AddrStorage() : addr() {} } storage_{}; // IPAddress class does nto save zone or port, and must be saved here uint16_t port_; @@ -618,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