VirtualBox

source: vbox/trunk/src/VBox/NetworkServices/Dhcpd/Db.h@ 106061

Last change on this file since 106061 was 106061, checked in by vboxsync, 8 weeks ago

Copyright year updates by scm.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 6.5 KB
Line 
1/* $Id: Db.h 106061 2024-09-16 14:03:52Z vboxsync $ */
2/** @file
3 * DHCP server - address database
4 */
5
6/*
7 * Copyright (C) 2017-2024 Oracle and/or its affiliates.
8 *
9 * This file is part of VirtualBox base platform packages, as
10 * available from https://www.virtualbox.org.
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation, in version 3 of the
15 * License.
16 *
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, see <https://www.gnu.org/licenses>.
24 *
25 * SPDX-License-Identifier: GPL-3.0-only
26 */
27
28#ifndef VBOX_INCLUDED_SRC_Dhcpd_Db_h
29#define VBOX_INCLUDED_SRC_Dhcpd_Db_h
30#ifndef RT_WITHOUT_PRAGMA_ONCE
31# pragma once
32#endif
33
34#include "DhcpdInternal.h"
35#include <iprt/net.h>
36
37#include <iprt/cpp/ministring.h>
38#include <iprt/cpp/xml.h>
39
40#include <list>
41
42#include "Timestamp.h"
43#include "ClientId.h"
44#include "IPv4Pool.h"
45#include "Config.h"
46#include "DhcpMessage.h"
47
48
49/**
50 * An address binding in the lease database.
51 *
52 * This is how an allocated IPv4 address is mananged.
53 */
54class Binding
55{
56 friend class Db;
57
58public:
59 enum State { FREE, RELEASED, EXPIRED, OFFERED, ACKED };
60
61private:
62 const RTNETADDRIPV4 m_addr;
63 State m_state;
64 ClientId m_id;
65 Timestamp m_issued;
66 uint32_t m_secLease;
67 /** Set if this is a fixed assignment. */
68 bool m_fFixed;
69
70public:
71 Binding();
72 Binding(const Binding &);
73
74 explicit Binding(RTNETADDRIPV4 a_Addr)
75 : m_addr(a_Addr), m_state(FREE), m_issued(), m_secLease(0), m_fFixed(false)
76 {}
77
78 Binding(RTNETADDRIPV4 a_Addr, const ClientId &a_id)
79 : m_addr(a_Addr), m_state(FREE), m_id(a_id), m_issued(), m_secLease(0), m_fFixed(false)
80 {}
81
82 Binding(RTNETADDRIPV4 a_Addr, const RTMAC &a_MACAddress, bool a_fFixed)
83 : m_addr(a_Addr)
84 , m_state(ACKED)
85 , m_id(ClientId(a_MACAddress, OptClientId()))
86 , m_issued(Timestamp::now())
87 , m_secLease(UINT32_MAX - 1)
88 , m_fFixed(a_fFixed)
89 {}
90
91
92 /** @name Attribute accessors
93 * @{ */
94 RTNETADDRIPV4 addr() const RT_NOEXCEPT { return m_addr; }
95
96 const ClientId &id() const RT_NOEXCEPT { return m_id; }
97 void idUpdate(const ClientId &a_ridClient);
98
99 uint32_t leaseTime() const RT_NOEXCEPT { return m_secLease; }
100 Timestamp issued() const RT_NOEXCEPT { return m_issued; }
101
102 State state() const RT_NOEXCEPT { return m_state; }
103 const char *stateName() const RT_NOEXCEPT;
104 Binding &setState(const char *pszStateName) RT_NOEXCEPT;
105 Binding &setState(State stateParam) RT_NOEXCEPT
106 {
107 m_state = stateParam;
108 return *this;
109 }
110
111 bool isFixed() const RT_NOEXCEPT { return m_fFixed; }
112 /** @} */
113
114
115 Binding &setLeaseTime(uint32_t secLease) RT_NOEXCEPT
116 {
117 m_issued = Timestamp::now();
118 m_secLease = secLease;
119 return *this;
120 }
121
122 /** Reassigns the binding to the given client. */
123 Binding &giveTo(const ClientId &a_id) RT_NOEXCEPT
124 {
125 m_id = a_id;
126 m_state = FREE;
127 return *this;
128 }
129
130 void free()
131 {
132 m_id = ClientId();
133 m_state = FREE;
134 }
135
136 bool expire(Timestamp tsDeadline) RT_NOEXCEPT;
137 bool expire() RT_NOEXCEPT
138 {
139 return expire(Timestamp::now());
140 }
141
142 /** @name Serialization
143 * @{ */
144 static Binding *fromXML(const xml::ElementNode *pElmLease);
145 void toXML(xml::ElementNode *pElmParent) const;
146 /** @} */
147
148 /** @name String formatting of %R[binding].
149 * @{ */
150 static void registerFormat() RT_NOEXCEPT;
151private:
152 static DECLCALLBACK(size_t) rtStrFormat(PFNRTSTROUTPUT pfnOutput, void *pvArgOutput, const char *pszType,
153 void const *pvValue, int cchWidth, int cchPrecision, unsigned fFlags, void *pvUser);
154 static bool g_fFormatRegistered;
155 /** @} */
156
157 Binding &operator=(const Binding &); /**< Shuts up warning C4626 (incorrect warning?). */
158};
159
160
161/**
162 * The lease database.
163 *
164 * There is currently just one instance of this class in a running DHCP server
165 * residing in Dhcpd::m_db. It covers one single range of IPv4 addresses, which
166 * currently unbound addressed are managed by m_pool. The allocated addresses
167 * are kept in the m_bindings list. Once an address has been allocated, it will
168 * stay in the m_bindings list even after released or expired.
169 */
170class Db
171{
172private:
173 typedef std::list<Binding *> bindings_t;
174
175 /** Configuration (set at init).
176 * @note Currently not used. */
177 const Config *m_pConfig;
178 /** The lease database.
179 * @note Since fixed assignments are added during initialization, they will
180 * always be first. The allocateBinding() code depends on this. */
181 bindings_t m_bindings;
182 /** Address allocation pool. */
183 IPv4Pool m_pool;
184
185public:
186 Db();
187 ~Db();
188
189 int init(const Config *pConfig);
190
191 /** Check if @a addr belonges to this lease database. */
192 bool addressBelongs(RTNETADDRIPV4 addr) const RT_NOEXCEPT { return m_pool.contains(addr); }
193
194 Binding *allocateBinding(const DhcpClientMessage &req, Config::ConfigVec const &rConfigVec);
195 bool releaseBinding(const DhcpClientMessage &req) RT_NOEXCEPT;
196
197 void cancelOffer(const DhcpClientMessage &req) RT_NOEXCEPT;
198
199 void expire() RT_NOEXCEPT;
200
201 /** @name Database serialization methods
202 * @{ */
203 int loadLeases(const RTCString &strFilename) RT_NOEXCEPT;
204private:
205 int i_loadLease(const xml::ElementNode *pElmLease) RT_NOEXCEPT;
206public:
207 int writeLeases(const RTCString &strFilename) const RT_NOEXCEPT;
208 /** @} */
209
210private:
211 int i_enterFixedAddressAssignment(RTNETADDRIPV4 const &a_rAddress, RTMAC const &a_rMACAddress) RT_NOEXCEPT;
212 Binding *i_createBinding(const ClientId &id = ClientId());
213 Binding *i_createBinding(RTNETADDRIPV4 addr, const ClientId &id = ClientId());
214
215 Binding *i_allocateAddress(const ClientId &id, RTNETADDRIPV4 addr);
216
217 /* add binding e.g. from the leases file */
218 int i_addBinding(Binding *pNewBinding) RT_NOEXCEPT;
219};
220
221#endif /* !VBOX_INCLUDED_SRC_Dhcpd_Db_h */
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette