/*
* Copyright 2011 Future Systems
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.krakenapps.dhcp.server;
import java.io.File;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.nio.ByteBuffer;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.CopyOnWriteArraySet;
import org.krakenapps.dhcp.DhcpMessage;
import org.krakenapps.dhcp.DhcpMessageListener;
import org.krakenapps.dhcp.MacAddress;
import org.krakenapps.dhcp.model.DhcpFilter;
import org.krakenapps.dhcp.model.DhcpIpLease;
import org.krakenapps.dhcp.model.DhcpIpReservation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
class DhcpServerContext {
public static InetAddress ZERO_ADDRESS;
private final Logger logger = LoggerFactory.getLogger(DhcpServerContext.class.getName());
public Connection conn;
public CopyOnWriteArraySet<DhcpMessageListener> callbacks;
/**
* offered ip address (can be timeout'd)
*/
public ConcurrentMap<InetAddress, DhcpIpLease> offerMap;
/**
* leased ip address map
*/
public ConcurrentMap<InetAddress, DhcpIpLease> leaseMap;
/**
* reserved mac address mappings
*/
public ConcurrentMap<MacAddress, DhcpIpReservation> reserveMap;
public ConcurrentMap<MacAddress, DhcpFilter> blockFilters;
public ConcurrentMap<MacAddress, DhcpFilter> allowFilters;
private byte[] buf = new byte[4096];
private DatagramSocket socket;
static {
try {
ZERO_ADDRESS = InetAddress.getByName("0.0.0.0");
} catch (UnknownHostException e) {
// not reachable
}
}
public DhcpServerContext() throws Exception {
offerMap = new ConcurrentHashMap<InetAddress, DhcpIpLease>();
leaseMap = new ConcurrentHashMap<InetAddress, DhcpIpLease>();
reserveMap = new ConcurrentHashMap<MacAddress, DhcpIpReservation>();
blockFilters = new ConcurrentHashMap<MacAddress, DhcpFilter>();
allowFilters = new ConcurrentHashMap<MacAddress, DhcpFilter>();
socket = new DatagramSocket(67);
System.setProperty("derby.system.home", System.getProperty("user.dir"));
new File(System.getProperty("kraken.data.dir"), "kraken-dhcp").mkdirs();
conn = DhcpDatabase.newConnection();
}
public DhcpMessage receive() throws IOException {
DatagramPacket p = new DatagramPacket(buf, buf.length);
socket.receive(p);
ByteBuffer bb = ByteBuffer.wrap(p.getData(), 0, p.getLength());
return DhcpMessageParser.parse(bb);
}
public void send(DhcpMessage msg) throws IOException {
send(InetAddress.getByName("255.255.255.255"), msg);
}
public void send(InetAddress destination, DhcpMessage msg) throws IOException {
byte[] buf = DhcpMessageBuilder.encode(msg);
DatagramPacket p = new DatagramPacket(buf, buf.length, destination, 68);
socket.send(p);
}
public void close() {
if (socket != null)
socket.close();
try {
if (conn != null)
conn.close();
} catch (SQLException e) {
logger.error("kraken dhcp: cannot close database", e);
}
}
}