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
// Copyright (C) 2010-2024 Internet Systems Consortium, Inc. ("ISC")
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

#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 file:  not found. Please note: Cppcheck does not need standard library headers to get proper results.
#include <string><--- Include file:  not found. Please note: Cppcheck does not need standard library headers to get proper results.

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

# include <ostream><--- Include file:  not found. Please note: Cppcheck does not need standard library headers to get proper results.

#include <unistd.h>             // for some network system calls<--- Include file:  not found. Please note: Cppcheck does not need standard library headers to get proper results.

#include <sys/socket.h>         // for sockaddr<--- Include file:  not found. Please note: Cppcheck does not need standard library headers to get proper results.

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 Kea 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