summaryrefslogtreecommitdiffstats
path: root/src/lib/dhcpsrv/triplet.h
blob: a60510305aa430c377182751a46205c0302e5a14 (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
// Copyright (C) 2012, 2014 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 TRIPLET_H
#define TRIPLET_H

#include <exceptions/exceptions.h>

namespace isc {
namespace dhcp {

/// @brief This template specifies a parameter value
///
/// This template class is used to store configuration parameters, like lifetime
/// or T1. It defines 3 parameters: min, default, and max value. If the
/// particular configuration parameter is not mandatory, it is possible to
/// mark the parameter described by a @c Triplet "unspecified". For example, the
/// T1 and T2 values in DHCPv4 server are optional and may be not specified
/// in the configuration. The @c Triplets describing these parameters will be
/// marked "unspecified". If the server finds that the particular parameter
/// is unspecified it will not include it (e.g. option 58 or 59) in the message
/// to a client.
///
/// There are 3 constructors:
/// - without parameters - marks the parameter "unspecified"
/// - simple (just one value that sets all parameters)
/// - extended (that sets default value and two thresholds)
///
/// It will be used with integer types. It provides necessary operators, so
/// it can be assigned to a plain integer or integer assigned to a Triplet.
/// See TripletTest.operator test for details on an easy Triplet usage.
template <class T>
class Triplet {
public:

    /// @brief Base type to Triplet conversion.
    ///
    /// Typically: uint32_t to Triplet assignment. It is very convenient
    /// to be able to simply write Triplet<uint32_t> x = 7;
    ///
    /// @param other A number to be assigned as min, max and default value.
    Triplet<T>& operator=(T other) {
        min_ = other;
        default_ = other;
        max_ = other;
        // The value is now specified because we just assigned one.
        unspecified_ = false;
        return (*this);
    }

    /// @brief Triplet to base type conversion
    ///
    /// Typically: Triplet to uint32_t assignment. It is very convenient
    /// to be able to simply write uint32_t z = x; (where x is a Triplet)
    operator T() const {
        return (default_);
    }

    /// @brief Constructor without parameters.
    ///
    /// Marks value in @c Triplet unspecified.
    Triplet()
        : min_(0), default_(0), max_(0),
          unspecified_(true) {
    }

    /// @brief Sets a fixed value.
    ///
    /// This constructor assigns a fixed (i.e. no range, just a single value)
    /// value.
    ///
    /// @param value A number to be assigned as min, max and default value.
    Triplet(T value)
        : min_(value), default_(value), max_(value),
          unspecified_(false) {
    }

    /// @brief Sets the default value and thresholds
    ///
    /// @throw BadValue if min <= def <= max rule is violated
    Triplet(T min, T def, T max)
        : min_(min), default_(def), max_(max),
          unspecified_(false) {
        if ( (min_ > def) || (def > max_) ) {
            isc_throw(BadValue, "Invalid triplet values.");
        }
    }

    /// @brief Returns a minimum allowed value
    T getMin() const { return (min_);}

    /// @brief Returns the default value
    T get() const { return (default_); }

    /// @brief Returns value with a hint
    ///
    /// DHCP protocol treats any values sent by a client as hints.
    /// This is a method that implements that. We can assign any value
    /// from configured range that client asks.
    ///
    /// @param hint A value being returned when if it is within the range
    /// between min and max value of @c Triplet. If the hint value is lower
    /// than min value, the min value is returned. if the hint is greater
    /// than max value, the max value is returned.
    ///
    /// @return A value adjusted to the hint.
    T get(T hint) const {
        if (hint <= min_) {
            return (min_);
        }

        if (hint >= max_) {
            return (max_);
        }

        return (hint);
    }

    /// @brief Returns a maximum allowed value
    T getMax() const { return (max_); }

    /// @brief Check if the value has been specified.
    ///
    /// @return true if the value hasn't been specified, or false otherwise.
    bool unspecified() const {
        return (unspecified_);
    }

private:

    /// @brief the minimum value
    T min_;

    /// @brief the default value
    T default_;

    /// @brief the maximum value
    T max_;

    /// @brief Indicates whether the value is unspecified.
    bool unspecified_;
};


} // namespace isc::dhcp
} // namespace isc

#endif // TRIPLET_H