1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.directory.server.dhcp.store;
21
22
23 import java.net.InetAddress;
24 import java.util.Map;
25
26 import org.apache.directory.server.dhcp.DhcpException;
27 import org.apache.directory.server.dhcp.messages.HardwareAddress;
28 import org.apache.directory.server.dhcp.options.OptionsField;
29 import org.apache.directory.server.dhcp.options.vendor.HostName;
30 import org.apache.directory.server.dhcp.options.vendor.SubnetMask;
31 import org.apache.directory.server.dhcp.service.Lease;
32 import org.slf4j.Logger;
33 import org.slf4j.LoggerFactory;
34
35
36
37
38
39
40
41 public abstract class AbstractDhcpStore implements DhcpStore
42 {
43 private static final Logger LOG = LoggerFactory.getLogger( AbstractDhcpStore.class );
44
45
46
47
48
49
50
51 public Lease getLeaseOffer( HardwareAddress hardwareAddress, InetAddress requestedAddress,
52 InetAddress selectionBase, long requestedLeaseTime, OptionsField options ) throws DhcpException
53 {
54 Subnet subnet = findSubnet( selectionBase );
55
56 if ( null == subnet )
57 {
58 LOG.warn( "Don't know anything about the sbnet containing {}", selectionBase );
59 return null;
60 }
61
62
63 Lease lease = null;
64 lease = findExistingLease( hardwareAddress, lease );
65
66 if ( null != lease )
67 {
68 return lease;
69 }
70
71 Host host = null;
72 host = findDesignatedHost( hardwareAddress );
73
74 if ( null != host )
75 {
76
77
78
79 if ( !subnet.contains( host.getAddress() ) )
80 {
81 LOG.warn( "Host {} is not within the subnet for which an address is requested", host );
82 }
83 else
84 {
85
86 Map properties = getProperties( subnet );
87 properties.putAll( getProperties( host ) );
88
89
90 lease = new Lease();
91 lease.setAcquired( System.currentTimeMillis() );
92
93 long leaseTime = determineLeaseTime( requestedLeaseTime, properties );
94
95 lease.setExpires( System.currentTimeMillis() + leaseTime );
96
97 lease.setHardwareAddress( hardwareAddress );
98 lease.setState( Lease.STATE_NEW );
99 lease.setClientAddress( host.getAddress() );
100
101
102 OptionsField o = lease.getOptions();
103
104
105 o.add( new HostName( host.getName() ) );
106
107
108 o.add( new SubnetMask( subnet.getNetmask() ) );
109 o.merge( subnet.getOptions() );
110
111
112
113 o.merge( host.getOptions() );
114 }
115 }
116
117
118 if ( null != lease && lease.getState() != Lease.STATE_ACTIVE )
119 {
120 lease.setState( Lease.STATE_OFFERED );
121 updateLease( lease );
122 }
123
124 return lease;
125 }
126
127
128
129
130
131
132
133 public Lease getExistingLease( HardwareAddress hardwareAddress, InetAddress requestedAddress,
134 InetAddress selectionBase, long requestedLeaseTime, OptionsField options ) throws DhcpException
135 {
136
137
138
139 Lease lease = null;
140 lease = findExistingLease( hardwareAddress, lease );
141
142 if ( null == lease )
143 {
144 return null;
145 }
146
147
148 if ( !lease.getClientAddress().equals( requestedAddress ) )
149 {
150 LOG.warn( "Requested address " + requestedAddress + " for " + hardwareAddress
151 + " doesn't match existing lease " + lease );
152 return null;
153 }
154
155
156 Subnet subnet = findSubnet( selectionBase );
157
158 if ( null == subnet )
159 {
160 LOG.warn( "No subnet found for existing lease {}", lease );
161 return null;
162 }
163
164 if ( !subnet.contains( lease.getClientAddress() ) )
165 {
166 LOG.warn( "Client with existing lease {} is on wrong subnet {}", lease, subnet );
167 return null;
168 }
169
170 if ( !subnet.isInRange( lease.getClientAddress() ) )
171 {
172 LOG.warn( "Client with existing lease {} is out of valid range for subnet {}", lease, subnet );
173 return null;
174 }
175
176
177 Map properties = getProperties( subnet );
178
179
180 OptionsField o = lease.getOptions();
181 o.clear();
182
183
184 o.add( new SubnetMask( subnet.getNetmask() ) );
185 o.merge( subnet.getOptions() );
186
187
188 Host host = findDesignatedHost( hardwareAddress );
189 if ( null != host )
190 {
191
192
193 if ( host.getAddress() != null && !host.getAddress().equals( lease.getClientAddress() ) )
194 {
195 LOG.warn( "Existing fixed address for " + hardwareAddress + " conflicts with existing lease "
196 + lease );
197 return null;
198 }
199
200 properties.putAll( getProperties( host ) );
201
202
203 o.add( new HostName( host.getName() ) );
204
205
206 o.merge( host.getOptions() );
207 }
208
209
210 long leaseTime = determineLeaseTime( requestedLeaseTime, properties );
211 lease.setExpires( System.currentTimeMillis() + leaseTime );
212 lease.setHardwareAddress( hardwareAddress );
213
214
215 if ( lease.getState() != Lease.STATE_ACTIVE )
216 {
217 lease.setState( Lease.STATE_ACTIVE );
218 updateLease( lease );
219 }
220
221
222 updateLease( lease );
223
224 return lease;
225 }
226
227
228
229
230
231
232
233
234
235
236 private long determineLeaseTime( long requestedLeaseTime, Map properties )
237 {
238
239 long leaseTime = 1000L * 3600;
240 Integer propMaxLeaseTime = ( Integer ) properties.get( DhcpConfigElement.PROPERTY_MAX_LEASE_TIME );
241
242 if ( null != propMaxLeaseTime )
243 {
244 if ( requestedLeaseTime > 0 )
245 {
246 leaseTime = Math.min( propMaxLeaseTime.intValue() * 1000L, requestedLeaseTime );
247 }
248 else
249 {
250 leaseTime = propMaxLeaseTime.intValue() * 1000L;
251 }
252 }
253
254 return leaseTime;
255 }
256
257
258
259
260
261 public void releaseLease( Lease lease )
262 {
263 lease.setState( Lease.STATE_RELEASED );
264 updateLease( lease );
265 }
266
267
268
269
270
271
272
273 protected abstract void updateLease( Lease lease );
274
275
276
277
278
279
280
281
282
283
284
285
286 protected abstract OptionsField getOptions( DhcpConfigElement element );
287
288
289
290
291
292
293
294
295
296
297
298
299 protected abstract Map getProperties( DhcpConfigElement element );
300
301
302
303
304
305
306
307
308
309 protected abstract Leaserver/dhcp/service/Lease.html#Lease">Lease findExistingLease( HardwareAddress hardwareAddress, Lease existingLease );
310
311
312
313
314
315
316
317
318
319 protected abstract Host findDesignatedHost( HardwareAddress hardwareAddress ) throws DhcpException;
320
321
322
323
324
325
326
327
328 protected abstract Subnet findSubnet( InetAddress clientAddress );
329 }