1 
2 /**
3  *    Copyright (C) 2018-present MongoDB, Inc.
4  *
5  *    This program is free software: you can redistribute it and/or modify
6  *    it under the terms of the Server Side Public License, version 1,
7  *    as published by MongoDB, Inc.
8  *
9  *    This program is distributed in the hope that it will be useful,
10  *    but WITHOUT ANY WARRANTY; without even the implied warranty of
11  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  *    Server Side Public License for more details.
13  *
14  *    You should have received a copy of the Server Side Public License
15  *    along with this program. If not, see
16  *    <http://www.mongodb.com/licensing/server-side-public-license>.
17  *
18  *    As a special exception, the copyright holders give permission to link the
19  *    code of portions of this program with the OpenSSL library under certain
20  *    conditions as described in each individual source file and distribute
21  *    linked combinations including the program with the OpenSSL library. You
22  *    must comply with the Server Side Public License in all respects for
23  *    all of the code used other than as permitted herein. If you modify file(s)
24  *    with this exception, you may extend this exception to your version of the
25  *    file(s), but you are not obligated to do so. If you do not wish to do so,
26  *    delete this exception statement from your version. If you delete this
27  *    exception statement from all source files in the program, then also delete
28  *    it in the license file.
29  */
30 
31 #pragma once
32 
33 #include <iosfwd>
34 #include <string>
35 
36 #include <boost/optional.hpp>
37 
38 #include "mongo/bson/util/builder.h"
39 #include "mongo/platform/hash_namespace.h"
40 #include "mongo/util/net/sockaddr.h"
41 
42 namespace mongo {
43 
44 class Status;
45 template <typename Allocator>
46 class StringBuilderImpl;
47 class StringData;
48 template <typename T>
49 class StatusWith;
50 
51 /**
52  * Name of a process on the network.
53  *
54  * Composed of some name component, followed optionally by a colon and a numeric port.  The name
55  * might be an IPv4 or IPv6 address or a relative or fully qualified host name, or an absolute
56  * path to a unix socket.
57  */
58 struct HostAndPort {
59     /**
60      * Parses "text" to produce a HostAndPort.  Returns either that or an error
61      * status describing the parse failure.
62      */
63     static StatusWith<HostAndPort> parse(StringData text);
64 
65     /**
66      * Construct an empty/invalid HostAndPort.
67      */
68     HostAndPort();
69 
70     /**
71      * Constructs a HostAndPort by parsing "text" of the form hostname[:portnumber]
72      * Throws an AssertionException if bad config std::string or bad port #.
73      */
74     explicit HostAndPort(StringData text);
75 
76     /**
77      * Constructs a HostAndPort with the hostname "h" and port "p".
78      *
79      * If "p" is -1, port() returns ServerGlobalParams::DefaultDBPort.
80      */
81     HostAndPort(const std::string& h, int p);
82 
83     /**
84      * Constructs a HostAndPort from a SockAddr
85      *
86      * Used by the TransportLayer to convert raw socket addresses into HostAndPorts to be
87      * accessed via tranport::Session
88      */
89     explicit HostAndPort(SockAddr addr);
90 
91     /**
92      * (Re-)initializes this HostAndPort by parsing "s".  Returns
93      * Status::OK on success.  The state of this HostAndPort is unspecified
94      * after initialize() returns a non-OK status, though it is safe to
95      * assign to it or re-initialize it.
96      */
97     Status initialize(StringData s);
98 
99     bool operator<(const HostAndPort& r) const;
100     bool operator==(const HostAndPort& r) const;
101     bool operator!=(const HostAndPort& r) const {
102         return !(*this == r);
103     }
104 
105     /**
106      * Returns true if the hostname looks localhost-y.
107      *
108      * TODO: Make a more rigorous implementation, perhaps elsewhere in
109      * the networking library.
110      */
111     bool isLocalHost() const;
112 
113     /**
114      * Returns true if the hostname is an IP matching the default route.
115      */
116     bool isDefaultRoute() const;
117 
118     /**
119      * Returns a string representation of "host:port".
120      */
121     std::string toString() const;
122 
123     /**
124      * Like toString(), above, but writes to "ss", instead.
125      */
126     void append(StringBuilder& ss) const;
127 
128     /**
129      * Returns true if this object represents no valid HostAndPort.
130      */
131     bool empty() const;
132 
133     /**
134      * Returns the SockAddr representation of this address, if available
135      */
sockAddrHostAndPort136     const boost::optional<SockAddr>& sockAddr() const& {
137         return _addr;
138     }
139     void sockAddr() && = delete;
140 
hostHostAndPort141     const std::string& host() const {
142         return _host;
143     }
144     int port() const;
145 
hasPortHostAndPort146     bool hasPort() const {
147         return _port >= 0;
148     }
149 
150 private:
151     boost::optional<SockAddr> _addr;
152     std::string _host;
153     int _port;  // -1 indicates unspecified
154 };
155 
156 std::ostream& operator<<(std::ostream& os, const HostAndPort& hp);
157 
158 template <typename Allocator>
159 StringBuilderImpl<Allocator>& operator<<(StringBuilderImpl<Allocator>& os, const HostAndPort& hp);
160 
161 }  // namespace mongo
162 
163 MONGO_HASH_NAMESPACE_START
164 
165 template <>
166 struct hash<mongo::HostAndPort> {
167     size_t operator()(const mongo::HostAndPort& host) const;
168 };
169 
170 MONGO_HASH_NAMESPACE_END
171