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