summaryrefslogtreecommitdiffstats
path: root/src/lib/asiolink/io_address.h
blob: 6c18a66d57befea8ee51e0b2b55956d8adb42ecf (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
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
// 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_ADDRESS_H
#define IO_ADDRESS_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 <unistd.h>             // for some network system calls
#include <stdint.h>             // for uint32_t
#include <asio/ip/address.hpp>

#include <functional>
#include <string>

#include <exceptions/exceptions.h>

namespace isc {
namespace asiolink {

    /// Defines length of IPv6 address.
    const static size_t V6ADDRESS_LEN = 16;

    /// Defines length of IPv4 address.
    const static size_t V4ADDRESS_LEN = 4;

/// \brief The \c IOAddress class represents an IP addresses (version
/// agnostic)
///
/// This class is a wrapper for the ASIO \c ip::address class.
class IOAddress {
public:
    ///
    /// \name Constructors and Destructor
    ///
    /// This class is copyable.  We use default versions of copy constructor
    /// and the assignment operator.
    /// We use the default destructor.
    //@{
    /// \brief Constructor from string.
    ///
    /// This constructor converts a textual representation of IPv4 and IPv6
    /// addresses into an IOAddress object.
    /// If \c address_str is not a valid representation of any type of
    /// address, an exception of class \c IOError will be thrown.
    /// This constructor allocates memory for the object, and if that fails
    /// a corresponding standard exception will be thrown.
    ///
    /// \param address_str Textual representation of address.
    IOAddress(const std::string& address_str);

    /// \brief Constructor from an ASIO \c ip::address object.
    ///
    /// This constructor is intended to be used within the wrapper
    /// implementation; user applications of the wrapper API won't use it.
    ///
    /// This constructor never throws an exception.
    ///
    /// \param asio_address The ASIO \c ip::address to be converted.
    IOAddress(const asio::ip::address& asio_address);
    //@}

    /// @brief Constructor for ip::address_v4 object.
    ///
    /// This constructor is intented to be used when constructing
    /// IPv4 address out of uint32_t type. Passed value must be in
    /// network byte order
    ///
    /// @param v4address IPv4 address represnted by uint32_t
    IOAddress(uint32_t v4address);

    /// \brief Convert the address to a string.
    ///
    /// This method is basically expected to be exception free, but
    /// generating the string will involve resource allocation,
    /// and if it fails the corresponding standard exception will be thrown.
    ///
    /// \return A string representation of the address.
    std::string toText() const;

    /// \brief Returns const reference to the underlying address object.
    ///
    /// This is useful, when access to interface offerted by
    //  asio::ip::address_v4 and asio::ip::address_v6 is beneficial.
    /// 
    /// \return A const reference to asio::ip::address object
    const asio::ip::address& getAddress() const;

    /// \brief Returns the address family
    ///
    /// \return AF_INET for IPv4 or AF_INET6 for IPv6.
    short getFamily() const;


    /// \brief Creates an address from over wire data.
    ///
    /// \param family AF_NET for IPv4 or AF_NET6 for IPv6.
    /// \param data pointer to first char of data
    ///
    /// \return Created IOAddress object
    static IOAddress
    from_bytes(short family, const uint8_t* data);

    /// \brief Compare addresses for equality
    ///
    /// \param other Address to compare against.
    ///
    /// \return true if addresses are equal, false if not.
    bool equals(const IOAddress& other) const {
        return (asio_address_ == other.asio_address_);
    }

    /// \brief Compare addresses for equality
    ///
    /// \param other Address to compare against.
    ///
    /// \return true if addresses are equal, false if not.
    bool operator==(const IOAddress& other) const {
        return equals(other);
    }

    /// \brief Compare addresses for inequality
    ///
    /// \param other Address to compare against.
    ///
    /// \return false if addresses are equal, true if not.
    bool nequals(const IOAddress& other) const {
        return (!equals(other));
    }

    /// \brief Checks if one address is smaller than the other
    ///
    /// \param other Address to compare against.
    ///
    /// \return true if this address is smaller than the other address.
    ///
    /// It is useful for comparing which address is bigger.
    /// Operations within one protocol family are obvious.
    /// Comparisons between v4 and v6 will allways return v4
    /// being smaller. This follows boost::asio::ip implementation
    bool lessThan(const IOAddress& other) const {
        if (this->getFamily() == other.getFamily()) {
            if (this->getFamily() == AF_INET6) {
                return (this->asio_address_.to_v6() < other.asio_address_.to_v6());
            } else {
                return (this->asio_address_.to_v4() < other.asio_address_.to_v4());
            }
        }
        return (this->getFamily() < other.getFamily());
    }

    /// \brief Checks if one address is smaller or equal than the other
    ///
    /// \param other Address to compare against.
    ///
    /// \return true if this address is smaller than the other address.
    bool smallerEqual(const IOAddress& other) const {
        if (equals(other)) {
            return (true);
        }
        return (lessThan(other));
    }

    /// \brief Checks if one address is smaller than the other
    ///
    /// \param other Address to compare against.
    ///
    /// See \ref smaller_than method for details.
    bool operator<(const IOAddress& other) const {
        return (lessThan(other));
    }

    /// \brief Checks if one address is smaller or equal than the other
    ///
    /// \param other Address to compare against.
    ///
    /// See \ref smaller_equal method for details.
    bool operator<=(const IOAddress& other) const {
        return (smallerEqual(other));
    }

    /// \brief Compare addresses for inequality
    ///
    /// \param other Address to compare against.
    ///
    /// \return false if addresses are equal, true if not.
    bool operator!=(const IOAddress& other) const {
        return (nequals(other));
    }

    /// \brief Converts IPv4 address to uint32_t
    ///
    /// Will throw BadValue exception if that is not IPv4
    /// address.
    ///
    /// \return uint32_t that represents IPv4 address in
    ///         network byte order
    operator uint32_t () const;

private:
    asio::ip::address asio_address_;
};

} // namespace asiolink
} // namespace isc
#endif // IO_ADDRESS_H