dhcp4_srv.h 9.66 KB
Newer Older
1
// Copyright (C) 2011-2012 Internet Systems Consortium, Inc. ("ISC")
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
//
// 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 DHCPV4_SRV_H
#define DHCPV4_SRV_H

18
#include <dhcp/dhcp4.h>
19 20
#include <dhcp/pkt4.h>
#include <dhcp/option.h>
21 22
#include <dhcpsrv/subnet.h>
#include <dhcpsrv/alloc_engine.h>
23 24 25

#include <boost/noncopyable.hpp>

26 27 28 29
#include <iostream>

namespace isc {
namespace dhcp {
30

31 32 33 34 35 36 37 38
/// @brief DHCPv4 server service.
///
/// This singleton class represents DHCPv4 server. It contains all
/// top-level methods and routines necessary for server operation.
/// In particular, it instantiates IfaceMgr, loads or generates DUID
/// that is going to be used as server-identifier, receives incoming
/// packets, processes them, manages leases assignment and generates
/// appropriate responses.
39 40
///
/// This class does not support any controlling mechanisms directly.
41
/// See the derived \ref ControlledDhcpv4Srv class for support for
42 43 44 45
/// command and configuration updates over msgq.
///
/// For detailed explanation or relations between main(), ControlledDhcpv4Srv,
/// Dhcpv4Srv and other classes, see \ref dhcpv4Session.
46 47
class Dhcpv4Srv : public boost::noncopyable {

Tomek Mrugalski's avatar
Tomek Mrugalski committed
48
    public:
49 50 51 52 53 54 55 56

    /// @brief defines if certain option may, must or must not appear
    typedef enum {
        FORBIDDEN,
        MANDATORY,
        OPTIONAL
    } RequirementLevel;

57 58
    /// @brief Default constructor.
    ///
59
    /// Instantiates necessary services, required to run DHCPv4 server.
60 61
    /// In particular, creates IfaceMgr that will be responsible for
    /// network interaction. Will instantiate lease manager, and load
Tomek Mrugalski's avatar
Tomek Mrugalski committed
62 63 64 65 66
    /// old or create new DUID. It is possible to specify alternate
    /// port on which DHCPv4 server will listen on. That is mostly useful
    /// for testing purposes.
    ///
    /// @param port specifies port number to listen on
67 68 69 70
    /// @param dbconfig Lease manager configuration string.  The default
    ///        of the "memfile" manager is used for testing.
    Dhcpv4Srv(uint16_t port = DHCP4_SERVER_PORT,
              const char* dbconfig = "type=memfile");
71

72
    /// @brief Destructor. Used during DHCPv4 service shutdown.
73 74 75 76 77 78 79 80 81 82 83 84
    ~Dhcpv4Srv();

    /// @brief Main server processing loop.
    ///
    /// Main server processing loop. Receives incoming packets, verifies
    /// their correctness, generates appropriate answer (if needed) and
    /// transmits respones.
    ///
    /// @return true, if being shut down gracefully, fail if experienced
    ///         critical error.
    bool run();

85
    /// @brief Instructs the server to shut down.
86 87
    void shutdown();

88 89 90 91 92
    /// @brief Return textual type of packet received by server
    ///
    /// Returns the name of valid packet received by the server (e.g. DISCOVER).
    /// If the packet is unknown - or if it is a valid DHCP packet but not one
    /// expected to be received by the server (such as an OFFER), the string
93
    /// "UNKNOWN" is returned.  This method is used in debug messages.
94 95 96 97
    ///
    /// As the operation of the method does not depend on any server state, it
    /// is declared static.
    ///
98 99
    /// @todo: This should be named static Pkt4::getName()
    ///
100 101 102 103 104 105 106
    /// @param type DHCPv4 packet type
    ///
    /// @return Pointer to "const" string containing the packet name.
    ///         Note that this string is statically allocated and MUST NOT
    ///         be freed by the caller.
    static const char* serverReceivedPacketName(uint8_t type);

107
protected:
108 109 110 111 112 113 114 115 116 117 118

    /// @brief verifies if specified packet meets RFC requirements
    ///
    /// Checks if mandatory option is really there, that forbidden option
    /// is not there, and that client-id or server-id appears only once.
    ///
    /// @param pkt packet to be checked
    /// @param serverid expectation regarding server-id option
    /// @throw RFCViolation if any issues are detected
    void sanityCheck(const Pkt4Ptr& pkt, RequirementLevel serverid);

119 120 121 122 123 124
    /// @brief Processes incoming DISCOVER and returns response.
    ///
    /// Processes received DISCOVER message and verifies that its sender
    /// should be served. In particular, a lease is selected and sent
    /// as an offer to a client if it should be served.
    ///
125
    /// @param discover DISCOVER message received from client
126 127
    ///
    /// @return OFFER message or NULL
128
    Pkt4Ptr processDiscover(Pkt4Ptr& discover);
129 130 131 132 133

    /// @brief Processes incoming REQUEST and returns REPLY response.
    ///
    /// Processes incoming REQUEST message and verifies that its sender
    /// should be served. In particular, verifies that requested lease
Tomek Mrugalski's avatar
Tomek Mrugalski committed
134
    /// is valid, not expired, not reserved, not used by other client and
135 136
    /// that requesting client is allowed to use it.
    ///
137
    /// Returns ACK message, NAK message, or NULL
138 139 140
    ///
    /// @param request a message received from client
    ///
141
    /// @return ACK or NAK message
142
    Pkt4Ptr processRequest(Pkt4Ptr& request);
143 144 145 146 147 148 149

    /// @brief Stub function that will handle incoming RELEASE messages.
    ///
    /// In DHCPv4, server does not respond to RELEASE messages, therefore
    /// this function does not return anything.
    ///
    /// @param release message received from client
150
    void processRelease(Pkt4Ptr& release);
151 152 153 154

    /// @brief Stub function that will handle incoming DHCPDECLINE messages.
    ///
    /// @param decline message received from client
155
    void processDecline(Pkt4Ptr& decline);
156 157 158

    /// @brief Stub function that will handle incoming INFORM messages.
    ///
159
    /// @param inform message received from client
160
    Pkt4Ptr processInform(Pkt4Ptr& inform);
161

162 163 164 165 166 167 168
    /// @brief Copies default parameters from client's to server's message
    ///
    /// Some fields are copied from client's message into server's response,
    /// e.g. client HW address, number of hops, transaction-id etc.
    ///
    /// @param question any message sent by client
    /// @param answer any message server is going to send as response
169
    void copyDefaultFields(const Pkt4Ptr& question, Pkt4Ptr& answer);
Tomek Mrugalski's avatar
Tomek Mrugalski committed
170 171 172 173

    /// @brief Appends options requested by client.
    ///
    /// This method assigns options that were requested by client
Tomek Mrugalski's avatar
Tomek Mrugalski committed
174
    /// (sent in PRL) or are enforced by server.
Tomek Mrugalski's avatar
Tomek Mrugalski committed
175 176
    ///
    /// @param msg outgoing message (options will be added here)
177
    void appendRequestedOptions(Pkt4Ptr& msg);
Tomek Mrugalski's avatar
Tomek Mrugalski committed
178 179 180 181 182 183 184

    /// @brief Assigns a lease and appends corresponding options
    ///
    /// This method chooses the most appropriate lease for reqesting
    /// client and assigning it. Options corresponding to the lease
    /// are added to specific message.
    ///
185 186 187 188 189 190 191 192 193
    /// @param question DISCOVER or REQUEST message from client
    /// @param answer OFFER or ACK/NAK message (lease options will be added here)
    void assignLease(const Pkt4Ptr& question, Pkt4Ptr& answer);

    /// @brief Attempts to renew received addresses
    ///
    /// Attempts to renew existing lease. This typically includes finding a lease that
    /// corresponds to the received address. If no such lease is found, a status code
    /// response is generated.
Tomek Mrugalski's avatar
Tomek Mrugalski committed
194
    ///
195 196 197
    /// @param renew client's message asking for renew
    /// @param reply server's response (ACK or NAK)
    void renewLease(const Pkt4Ptr& renew, Pkt4Ptr& reply);
Tomek Mrugalski's avatar
Tomek Mrugalski committed
198

199 200 201 202
    /// @brief Appends default options to a message
    ///
    /// @param msg message object (options will be added to it)
    /// @param msg_type specifies message type
203
    void appendDefaultOptions(Pkt4Ptr& msg, uint8_t msg_type);
204

205 206 207
    /// @brief Returns server-intentifier option
    ///
    /// @return server-id option
208
    OptionPtr getServerID() { return serverid_; }
209 210 211 212 213 214 215 216 217 218 219 220

    /// @brief Sets server-identifier.
    ///
    /// This method attempts to set server-identifier DUID. It tries to
    /// load previously stored IP from configuration. If there is no previously
    /// stored server identifier, it will pick up one address from configured
    /// and supported network interfaces.
    ///
    /// @throws isc::Unexpected Failed to obtain server identifier (i.e. no
    //          previously stored configuration and no network interfaces available)
    void setServerID();

221 222 223 224 225 226
    /// @brief Selects a subnet for a given client's packet.
    ///
    /// @param question client's message
    /// @return selected subnet (or NULL if no suitable subnet was found)
    isc::dhcp::Subnet4Ptr selectSubnet(const Pkt4Ptr& question);

227
    /// server DUID (to be sent in server-identifier option)
228
    OptionPtr serverid_;
229 230 231

    /// indicates if shutdown is in progress. Setting it to true will
    /// initiate server shutdown procedure.
Tomek Mrugalski's avatar
Tomek Mrugalski committed
232
    volatile bool shutdown_;
233 234 235 236

    private:

    /// @brief Constructs netmask option based on subnet4
237
    /// @param subnet subnet for which the netmask will be calculated
238 239 240 241 242 243 244 245 246 247
    ///
    /// @return Option that contains netmask information
    static OptionPtr getNetmaskOption(const Subnet4Ptr& subnet);

    /// @brief Allocation Engine.
    /// Pointer to the allocation engine that we are currently using
    /// It must be a pointer, because we will support changing engines
    /// during normal operation (e.g. to use different allocators)
    boost::shared_ptr<AllocEngine> alloc_engine_;

248 249 250 251 252 253
};

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

#endif // DHCP4_SRV_H