summaryrefslogtreecommitdiffstats
path: root/src/lib/asiolink/io_endpoint.h
blob: 89bc247398de13a3de3236ba959fa5f8f77e882f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
// Copyright (C) 2010  Internet Systems Consortium, Inc. ("ISC")
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.

#ifndef IO_ENDPOINT_H
#define IO_ENDPOINT_H 1

// IMPORTANT NOTE: only very few ASIO headers files can be included in
// this file.  In particular, asio.hpp should never be included here.
// See the description of the namespace below.

#include <functional>
#include <string>

#include <exceptions/exceptions.h>
#include <asiolink/io_address.h>

# include <ostream>

#include <unistd.h>             // for some network system calls

#include <sys/socket.h>         // for sockaddr

namespace isc {
namespace asiolink {

/// \brief The \c IOEndpoint class is an abstract base class to represent
/// a communication endpoint.
///
/// This class is a wrapper for the ASIO endpoint classes such as
/// \c ip::tcp::endpoint and \c ip::udp::endpoint.
///
/// Derived class implementations are completely hidden within the
/// implementation.  User applications only get access to concrete
/// \c IOEndpoint objects via the abstract interfaces.
class IOEndpoint {
    ///
    /// \name Constructors and Destructor
    ///
    /// Note: The copy constructor and the assignment operator are
    /// intentionally defined as private, making this class non-copyable.
    //@{
private:
    IOEndpoint(const IOEndpoint& source);
    IOEndpoint& operator=(const IOEndpoint& source);
protected:
    /// \brief The default constructor.
    ///
    /// This is intentionally defined as \c protected as this base class
    /// should never be instantiated (except as part of a derived class).
    IOEndpoint() {}
public:
    /// The destructor.
    virtual ~IOEndpoint() {}
    //@}

    /// \brief Returns the address of the endpoint.
    ///
    /// This method returns an IOAddress object corresponding to \c this
    /// endpoint.
    ///
    /// Note that the return value is a real object, not a reference or
    /// a pointer.
    ///
    /// This is aligned with the interface of the ASIO counterpart:
    /// the \c address() method of \c ip::xxx::endpoint classes returns
    /// an \c ip::address object.
    ///
    /// This also means handling the address of an endpoint using this method
    /// can be expensive.  If the address information is necessary in a
    /// performance sensitive context and there's a more efficient interface
    /// for that purpose, it's probably better to avoid using this method.
    ///
    /// This method never throws an exception.
    ///
    /// \return A copy of \c IOAddress object corresponding to the endpoint.
    virtual IOAddress getAddress() const = 0;

    /// \brief Returns the port of the endpoint.
    virtual uint16_t getPort() const = 0;

    /// \brief Returns the protocol number of the endpoint (TCP, UDP...)
    virtual short getProtocol() const = 0;

    /// \brief Returns the address family of the endpoint.
    virtual short getFamily() const = 0;

    /// \brief Returns the address of the endpoint in the form of sockaddr
    /// structure.
    ///
    /// The actual instance referenced by the returned value of this method
    /// is of per address family structure: For IPv4 (AF_INET), it's
    /// \c sockaddr_in; for IPv6 (AF_INET6), it's \c sockaddr_in6.
    /// The corresponding port and address members of the underlying structure
    /// will be set in the network byte order.
    ///
    /// This method is "redundant" in that all information to construct the
    /// \c sockaddr is available via the other "get" methods.
    /// It is still defined for performance sensitive applications that need
    /// to get the address information, such as for address based access
    /// control at a high throughput.  Internally it is implemented with
    /// minimum overhead such as data copy (this is another reason why this
    /// method returns a reference).
    ///
    /// As a tradeoff, this method is more fragile; it assumes that the
    /// underlying ASIO implementation stores the address information in
    /// the form of \c sockaddr and it can be accessed in an efficient way.
    /// This is the case as of this writing, but if the underlying
    /// implementation changes this method may become much slower or its
    /// interface may have to be changed, too.
    ///
    /// It is therefore discouraged for normal applications to use this
    /// method.  Unless the application is very performance sensitive, it
    /// should use the other "get" method to retrieve specific information
    /// of the endpoint.
    ///
    /// The returned reference is only valid while the corresponding
    /// \c IOEndpoint is valid.  Once it's destructed the reference will
    /// become invalid.
    ///
    /// \exception None
    /// \return Reference to a \c sockaddr structure corresponding to the
    /// endpoint.
    virtual const struct sockaddr& getSockAddr() const = 0;

    bool operator==(const IOEndpoint& other) const;
    bool operator!=(const IOEndpoint& other) const;

    /// \brief A polymorphic factory of endpoint from address and port.
    ///
    /// This method creates a new instance of (a derived class of)
    /// \c IOEndpoint object that identifies the pair of given address
    /// and port.
    /// The appropriate derived class is chosen based on the specified
    /// transport protocol.  If the \c protocol doesn't specify a protocol
    /// supported in this implementation, an exception of class \c IOError
    /// will be thrown.
    ///
    /// Memory for the created object will be dynamically allocated.  It's
    /// the caller's responsibility to \c delete it later.
    /// If resource allocation for the new object fails, a corresponding
    /// standard exception will be thrown.
    ///
    /// \param protocol The transport protocol used for the endpoint.
    /// Currently, only \c IPPROTO_UDP and \c IPPROTO_TCP can be specified.
    /// \param address The (IP) address of the endpoint.
    /// \param port The transport port number of the endpoint
    /// \return A pointer to a newly created \c IOEndpoint object.
    static const IOEndpoint* create(const int protocol,
                                    const IOAddress& address,
                                    const unsigned short port);
};

/// \brief Insert the \c IOEndpoint as a string into stream.
///
/// This method converts \c endpoint into a string and inserts it into the
/// output stream \c os.
///
/// This method converts the address and port of the endpoint in the textual
/// format that other BIND 10 modules would use in logging, i.e.,
/// - For IPv6 address: [&lt;address&gt;]:port (e.g., [2001:db8::5300]:53)
/// - For IPv4 address: &lt;address&gt;:port (e.g., 192.0.2.53:5300)
///
/// If it's neither IPv6 nor IPv4, it converts the endpoint into text in the
/// same format as that for IPv4, although in practice such a case is not
/// really expected.
///
/// \param os A \c std::ostream object on which the insertion operation is
/// performed.
/// \param endpoint A reference to an \c IOEndpoint object output by the
/// operation.
/// \return A reference to the same \c std::ostream object referenced by
/// parameter \c os after the insertion operation.
std::ostream& operator<<(std::ostream& os, const IOEndpoint& endpoint);
} // namespace asiolink
} // namespace isc
#endif // IO_ENDPOINT_H

// Local Variables:
// mode: c++
// End: