LogCabin
RPC/Address.h
Go to the documentation of this file.
00001 /* Copyright (c) 2012 Stanford University
00002  * Copyright (c) 2014 Diego Ongaro
00003  *
00004  * Permission to use, copy, modify, and distribute this software for any
00005  * purpose with or without fee is hereby granted, provided that the above
00006  * copyright notice and this permission notice appear in all copies.
00007  *
00008  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR(S) DISCLAIM ALL WARRANTIES
00009  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
00010  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL AUTHORS BE LIABLE FOR
00011  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
00012  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
00013  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
00014  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
00015  */
00016 
00017 #ifndef LOGCABIN_RPC_ADDRESS_H
00018 #define LOGCABIN_RPC_ADDRESS_H
00019 
00020 #include <sys/socket.h>
00021 #include <string>
00022 #include <vector>
00023 
00024 #include "Core/Time.h"
00025 
00026 namespace LogCabin {
00027 namespace RPC {
00028 
00029 /**
00030  * This class resolves user-friendly addresses for services into socket-level
00031  * addresses. It supports DNS lookups for addressing hosts by name, and it
00032  * supports multiple (alternative) addresses.
00033  */
00034 class Address {
00035   public:
00036     /// Clock used for timeouts.
00037     typedef Core::Time::SteadyClock Clock;
00038     /// Type for absolute time values used for timeouts.
00039     typedef Clock::time_point TimePoint;
00040 
00041     /**
00042      * Constructor. You will usually need to call #refresh() before using this
00043      * class.
00044      * \param str
00045      *      A string representation of the host and, optionally, a port number.
00046      *          - hostname:port
00047      *          - hostname
00048      *          - IPv4Address:port
00049      *          - IPv4Address
00050      *          - [IPv6Address]:port
00051      *          - [IPv6Address]
00052      *      Or a comma-delimited list of these to represent multiple hosts.
00053      * \param defaultPort
00054      *      The port number to use if none is specified in str.
00055      */
00056     Address(const std::string& str, uint16_t defaultPort);
00057 
00058     /// Default constructor.
00059     Address();
00060 
00061     /// Copy constructor.
00062     Address(const Address& other);
00063 
00064     /// Assignment.
00065     Address& operator=(const Address& other);
00066 
00067     /**
00068      * Return true if the sockaddr returned by getSockAddr() is valid.
00069      * \return
00070      *      True if refresh() has ever succeeded for this host and port.
00071      *      False otherwise.
00072      */
00073     bool isValid() const;
00074 
00075     /**
00076      * Return a sockaddr that may be used to connect a socket to this Address.
00077      * \return
00078      *      The returned value will never be NULL and it is always safe to read
00079      *      the protocol field from it, even if getSockAddrLen() returns 0.
00080      */
00081     const sockaddr* getSockAddr() const;
00082 
00083     /**
00084      * Return the length in bytes of the sockaddr in getSockAddr().
00085      * This is the value you'll want to pass in to connect() or bind().
00086      */
00087     socklen_t getSockAddrLen() const;
00088 
00089     /**
00090      * Return a string describing the sockaddr within this Address.
00091      * This string will reflect the numeric address produced by the latest
00092      * successful call to refresh(), or "Unspecified".
00093      */
00094     std::string getResolvedString() const;
00095 
00096     /**
00097      * Return a string describing this Address.
00098      * This will contain both the user-provided string passed into the
00099      * constructor and the numeric address produced by the latest successful
00100      * call to refresh(). It's the best representation to use in error messages
00101      * for the user.
00102      */
00103     std::string toString() const;
00104 
00105     /**
00106      * Convert (a random one of) the host(s) and port(s) to a sockaddr.
00107      * If the host is a name instead of numeric, this will run a DNS query and
00108      * select a random result. If this query fails, any previous sockaddr will
00109      * be left intact.
00110      * \param timeout
00111      *      Not yet implemented.
00112      * \warning
00113      *      Timeouts have not been implemented.
00114      *      See https://github.com/logcabin/logcabin/issues/75
00115      */
00116     void refresh(TimePoint timeout);
00117 
00118   private:
00119 
00120     /**
00121      * The host name(s) or numeric address(es) as passed into the constructor.
00122      */
00123     std::string originalString;
00124 
00125     /**
00126      * A list of (host, port) pairs as parsed from originalString.
00127      * - First component: the host name or numeric address as parsed from the
00128      *   string passed into the constructor. This has brackets stripped out of
00129      *   IPv6 addresses and is in the form needed by getaddrinfo().
00130      * - Second component: an ASCII representation of the port number to use.
00131      *   It is stored in string form because that's sometimes how it comes into
00132      *   the constructor and always what refresh() needs to call getaddrinfo().
00133      */
00134     std::vector<std::pair<std::string, std::string>> hosts;
00135 
00136     /**
00137      * Storage for the sockaddr returned by getSockAddr.
00138      * This is always zeroed out from len to the end.
00139      */
00140     sockaddr_storage storage;
00141 
00142     /**
00143      * The length in bytes of storage that are in use.
00144      * The remaining bytes of storage are always zeroed out.
00145      */
00146     socklen_t len;
00147 };
00148 
00149 } // namespace LogCabin::RPC
00150 } // namespace LogCabin
00151 
00152 #endif /* LOGCABIN_RPC_ADDRESS_H */
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines