diff options
Diffstat (limited to 'framework/src/onos/apps/dhcp/app/src/main/java/org/onosproject/dhcp/impl/DhcpManager.java')
-rw-r--r-- | framework/src/onos/apps/dhcp/app/src/main/java/org/onosproject/dhcp/impl/DhcpManager.java | 699 |
1 files changed, 699 insertions, 0 deletions
diff --git a/framework/src/onos/apps/dhcp/app/src/main/java/org/onosproject/dhcp/impl/DhcpManager.java b/framework/src/onos/apps/dhcp/app/src/main/java/org/onosproject/dhcp/impl/DhcpManager.java new file mode 100644 index 00000000..96d94a2b --- /dev/null +++ b/framework/src/onos/apps/dhcp/app/src/main/java/org/onosproject/dhcp/impl/DhcpManager.java @@ -0,0 +1,699 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * 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.onosproject.dhcp.impl; + +import com.google.common.collect.ImmutableSet; +import org.apache.felix.scr.annotations.Activate; +import org.apache.felix.scr.annotations.Component; +import org.apache.felix.scr.annotations.Deactivate; +import org.apache.felix.scr.annotations.Reference; +import org.apache.felix.scr.annotations.ReferenceCardinality; +import org.apache.felix.scr.annotations.Service; +import org.jboss.netty.util.Timeout; +import org.jboss.netty.util.TimerTask; +import org.onlab.packet.ARP; +import org.onlab.packet.DHCP; +import org.onlab.packet.DHCPOption; +import org.onlab.packet.DHCPPacketType; +import org.onlab.packet.Ethernet; +import org.onlab.packet.IPv4; +import org.onlab.packet.Ip4Address; +import org.onlab.packet.IpAddress; +import org.onlab.packet.MacAddress; +import org.onlab.packet.TpPort; +import org.onlab.packet.UDP; +import org.onlab.packet.VlanId; +import org.onlab.util.Timer; +import org.onosproject.core.ApplicationId; +import org.onosproject.core.CoreService; +import org.onosproject.dhcp.DhcpService; +import org.onosproject.dhcp.DhcpStore; +import org.onosproject.dhcp.IpAssignment; +import org.onosproject.net.ConnectPoint; +import org.onosproject.net.Host; +import org.onosproject.net.HostId; +import org.onosproject.net.HostLocation; +import org.onosproject.net.config.ConfigFactory; +import org.onosproject.net.config.NetworkConfigEvent; +import org.onosproject.net.config.NetworkConfigListener; +import org.onosproject.net.config.NetworkConfigRegistry; +import org.onosproject.net.flow.DefaultTrafficSelector; +import org.onosproject.net.flow.DefaultTrafficTreatment; +import org.onosproject.net.flow.TrafficSelector; +import org.onosproject.net.flow.TrafficTreatment; +import org.onosproject.net.host.DefaultHostDescription; +import org.onosproject.net.host.HostProvider; +import org.onosproject.net.host.HostProviderRegistry; +import org.onosproject.net.host.HostProviderService; +import org.onosproject.net.packet.DefaultOutboundPacket; +import org.onosproject.net.packet.PacketContext; +import org.onosproject.net.packet.PacketPriority; +import org.onosproject.net.packet.PacketProcessor; +import org.onosproject.net.packet.PacketService; +import org.onosproject.net.provider.AbstractProvider; +import org.onosproject.net.provider.ProviderId; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.nio.ByteBuffer; +import java.util.ArrayList; +import java.util.Date; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Set; +import java.util.concurrent.TimeUnit; + +import static org.onlab.packet.MacAddress.valueOf; +import static org.onosproject.net.config.basics.SubjectFactories.APP_SUBJECT_FACTORY; + +/** + * Skeletal ONOS DHCP Server application. + */ +@Component(immediate = true) +@Service +public class DhcpManager implements DhcpService { + + private static final ProviderId PID = new ProviderId("of", "org.onosproject.dhcp", true); + private final Logger log = LoggerFactory.getLogger(getClass()); + + private final InternalConfigListener cfgListener = new InternalConfigListener(); + + private final Set<ConfigFactory> factories = ImmutableSet.of( + new ConfigFactory<ApplicationId, DhcpConfig>(APP_SUBJECT_FACTORY, + DhcpConfig.class, + "dhcp") { + @Override + public DhcpConfig createConfig() { + return new DhcpConfig(); + } + } + ); + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) + protected NetworkConfigRegistry cfgService; + + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) + protected PacketService packetService; + + private DHCPPacketProcessor processor = new DHCPPacketProcessor(); + + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) + protected CoreService coreService; + + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) + protected DhcpStore dhcpStore; + + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) + protected HostProviderRegistry hostProviderRegistry; + + protected HostProviderService hostProviderService; + + private final HostProvider hostProvider = new InternalHostProvider(); + + private ApplicationId appId; + + // Hardcoded values are default values. + + private static Ip4Address myIP = Ip4Address.valueOf("10.0.0.2"); + + private static MacAddress myMAC = valueOf("4f:4f:4f:4f:4f:4f"); + + /** + * leaseTime - 10 mins or 600s. + * renewalTime - 5 mins or 300s. + * rebindingTime - 6 mins or 360s. + */ + + private static int leaseTime = 600; + + private static int renewalTime = 300; + + private static int rebindingTime = 360; + + private static byte packetTTL = (byte) 127; + + private static Ip4Address subnetMask = Ip4Address.valueOf("255.0.0.0"); + + private static Ip4Address broadcastAddress = Ip4Address.valueOf("10.255.255.255"); + + private static Ip4Address routerAddress = Ip4Address.valueOf("10.0.0.2"); + + private static Ip4Address domainServer = Ip4Address.valueOf("10.0.0.2"); + + private static final Ip4Address IP_BROADCAST = Ip4Address.valueOf("255.255.255.255"); + + protected Timeout timeout; + + protected static int timerDelay = 2; + + @Activate + protected void activate() { + // start the dhcp server + appId = coreService.registerApplication("org.onosproject.dhcp"); + + cfgService.addListener(cfgListener); + factories.forEach(cfgService::registerConfigFactory); + cfgListener.reconfigureNetwork(cfgService.getConfig(appId, DhcpConfig.class)); + + hostProviderService = hostProviderRegistry.register(hostProvider); + packetService.addProcessor(processor, PacketProcessor.director(0)); + requestPackets(); + timeout = Timer.getTimer().newTimeout(new PurgeListTask(), timerDelay, TimeUnit.MINUTES); + log.info("Started"); + } + + @Deactivate + protected void deactivate() { + cfgService.removeListener(cfgListener); + factories.forEach(cfgService::unregisterConfigFactory); + packetService.removeProcessor(processor); + hostProviderRegistry.unregister(hostProvider); + hostProviderService = null; + cancelPackets(); + timeout.cancel(); + log.info("Stopped"); + } + + /** + * Request packet in via PacketService. + */ + private void requestPackets() { + + TrafficSelector.Builder selectorServer = DefaultTrafficSelector.builder() + .matchEthType(Ethernet.TYPE_IPV4) + .matchIPProtocol(IPv4.PROTOCOL_UDP) + .matchUdpDst(TpPort.tpPort(UDP.DHCP_SERVER_PORT)) + .matchUdpSrc(TpPort.tpPort(UDP.DHCP_CLIENT_PORT)); + packetService.requestPackets(selectorServer.build(), PacketPriority.CONTROL, appId); + + selectorServer = DefaultTrafficSelector.builder() + .matchEthType(Ethernet.TYPE_ARP); + packetService.requestPackets(selectorServer.build(), PacketPriority.CONTROL, appId); + } + + /** + * Cancel requested packets in via packet service. + */ + private void cancelPackets() { + TrafficSelector.Builder selectorServer = DefaultTrafficSelector.builder() + .matchEthType(Ethernet.TYPE_IPV4) + .matchIPProtocol(IPv4.PROTOCOL_UDP) + .matchUdpDst(TpPort.tpPort(UDP.DHCP_SERVER_PORT)) + .matchUdpSrc(TpPort.tpPort(UDP.DHCP_CLIENT_PORT)); + packetService.cancelPackets(selectorServer.build(), PacketPriority.CONTROL, appId); + + selectorServer = DefaultTrafficSelector.builder() + .matchEthType(Ethernet.TYPE_ARP); + packetService.cancelPackets(selectorServer.build(), PacketPriority.CONTROL, appId); + } + + @Override + public Map<HostId, IpAssignment> listMapping() { + return dhcpStore.listAssignedMapping(); + } + + @Override + public int getLeaseTime() { + return leaseTime; + } + + @Override + public int getRenewalTime() { + return renewalTime; + } + + @Override + public int getRebindingTime() { + return rebindingTime; + } + + @Override + public boolean setStaticMapping(MacAddress macID, Ip4Address ipAddress) { + return dhcpStore.assignStaticIP(macID, ipAddress); + } + + @Override + public boolean removeStaticMapping(MacAddress macID) { + return dhcpStore.removeStaticIP(macID); + } + + @Override + public Iterable<Ip4Address> getAvailableIPs() { + return dhcpStore.getAvailableIPs(); + } + + private class DHCPPacketProcessor implements PacketProcessor { + + /** + * Builds the DHCP Reply packet. + * + * @param packet the incoming Ethernet frame + * @param ipOffered the IP offered by the DHCP Server + * @param outgoingMessageType the message type of the outgoing packet + * @return the Ethernet reply frame + */ + private Ethernet buildReply(Ethernet packet, Ip4Address ipOffered, byte outgoingMessageType) { + + // Ethernet Frame. + Ethernet ethReply = new Ethernet(); + ethReply.setSourceMACAddress(myMAC); + ethReply.setDestinationMACAddress(packet.getSourceMAC()); + ethReply.setEtherType(Ethernet.TYPE_IPV4); + ethReply.setVlanID(packet.getVlanID()); + + // IP Packet + IPv4 ipv4Packet = (IPv4) packet.getPayload(); + IPv4 ipv4Reply = new IPv4(); + ipv4Reply.setSourceAddress(myIP.toInt()); + ipv4Reply.setDestinationAddress(ipOffered.toInt()); + ipv4Reply.setTtl(packetTTL); + + // UDP Datagram. + UDP udpPacket = (UDP) ipv4Packet.getPayload(); + UDP udpReply = new UDP(); + udpReply.setSourcePort((byte) UDP.DHCP_SERVER_PORT); + udpReply.setDestinationPort((byte) UDP.DHCP_CLIENT_PORT); + + // DHCP Payload. + DHCP dhcpPacket = (DHCP) udpPacket.getPayload(); + DHCP dhcpReply = new DHCP(); + dhcpReply.setOpCode(DHCP.OPCODE_REPLY); + dhcpReply.setFlags(dhcpPacket.getFlags()); + dhcpReply.setGatewayIPAddress(dhcpPacket.getGatewayIPAddress()); + dhcpReply.setClientHardwareAddress(dhcpPacket.getClientHardwareAddress()); + dhcpReply.setTransactionId(dhcpPacket.getTransactionId()); + + if (outgoingMessageType != DHCPPacketType.DHCPNAK.getValue()) { + dhcpReply.setYourIPAddress(ipOffered.toInt()); + dhcpReply.setServerIPAddress(myIP.toInt()); + if (dhcpPacket.getGatewayIPAddress() == 0) { + ipv4Reply.setDestinationAddress(IP_BROADCAST.toInt()); + } + } + dhcpReply.setHardwareType(DHCP.HWTYPE_ETHERNET); + dhcpReply.setHardwareAddressLength((byte) 6); + + // DHCP Options. + DHCPOption option = new DHCPOption(); + List<DHCPOption> optionList = new ArrayList<>(); + + // DHCP Message Type. + option.setCode(DHCP.DHCPOptionCode.OptionCode_MessageType.getValue()); + option.setLength((byte) 1); + byte[] optionData = {outgoingMessageType}; + option.setData(optionData); + optionList.add(option); + + // DHCP Server Identifier. + option = new DHCPOption(); + option.setCode(DHCP.DHCPOptionCode.OptionCode_DHCPServerIp.getValue()); + option.setLength((byte) 4); + option.setData(myIP.toOctets()); + optionList.add(option); + + if (outgoingMessageType != DHCPPacketType.DHCPNAK.getValue()) { + + // IP Address Lease Time. + option = new DHCPOption(); + option.setCode(DHCP.DHCPOptionCode.OptionCode_LeaseTime.getValue()); + option.setLength((byte) 4); + option.setData(ByteBuffer.allocate(4).putInt(leaseTime).array()); + optionList.add(option); + + // IP Address Renewal Time. + option = new DHCPOption(); + option.setCode(DHCP.DHCPOptionCode.OptionCode_RenewalTime.getValue()); + option.setLength((byte) 4); + option.setData(ByteBuffer.allocate(4).putInt(renewalTime).array()); + optionList.add(option); + + // IP Address Rebinding Time. + option = new DHCPOption(); + option.setCode(DHCP.DHCPOptionCode.OPtionCode_RebindingTime.getValue()); + option.setLength((byte) 4); + option.setData(ByteBuffer.allocate(4).putInt(rebindingTime).array()); + optionList.add(option); + + // Subnet Mask. + option = new DHCPOption(); + option.setCode(DHCP.DHCPOptionCode.OptionCode_SubnetMask.getValue()); + option.setLength((byte) 4); + option.setData(subnetMask.toOctets()); + optionList.add(option); + + // Broadcast Address. + option = new DHCPOption(); + option.setCode(DHCP.DHCPOptionCode.OptionCode_BroadcastAddress.getValue()); + option.setLength((byte) 4); + option.setData(broadcastAddress.toOctets()); + optionList.add(option); + + // Router Address. + option = new DHCPOption(); + option.setCode(DHCP.DHCPOptionCode.OptionCode_RouterAddress.getValue()); + option.setLength((byte) 4); + option.setData(routerAddress.toOctets()); + optionList.add(option); + + // DNS Server Address. + option = new DHCPOption(); + option.setCode(DHCP.DHCPOptionCode.OptionCode_DomainServer.getValue()); + option.setLength((byte) 4); + option.setData(domainServer.toOctets()); + optionList.add(option); + } + + // End Option. + option = new DHCPOption(); + option.setCode(DHCP.DHCPOptionCode.OptionCode_END.getValue()); + option.setLength((byte) 1); + optionList.add(option); + + dhcpReply.setOptions(optionList); + + udpReply.setPayload(dhcpReply); + ipv4Reply.setPayload(udpReply); + ethReply.setPayload(ipv4Reply); + + return ethReply; + } + + /** + * Sends the Ethernet reply frame via the Packet Service. + * + * @param context the context of the incoming frame + * @param reply the Ethernet reply frame + */ + private void sendReply(PacketContext context, Ethernet reply) { + if (reply != null) { + TrafficTreatment.Builder builder = DefaultTrafficTreatment.builder(); + ConnectPoint sourcePoint = context.inPacket().receivedFrom(); + builder.setOutput(sourcePoint.port()); + context.block(); + packetService.emit(new DefaultOutboundPacket(sourcePoint.deviceId(), + builder.build(), ByteBuffer.wrap(reply.serialize()))); + } + } + + /** + * Processes the DHCP Payload and initiates a reply to the client. + * + * @param context context of the incoming message + * @param dhcpPayload the extracted DHCP payload + */ + private void processDHCPPacket(PacketContext context, DHCP dhcpPayload) { + Ethernet packet = context.inPacket().parsed(); + boolean flagIfRequestedIP = false; + boolean flagIfServerIP = false; + Ip4Address requestedIP = Ip4Address.valueOf("0.0.0.0"); + Ip4Address serverIP = Ip4Address.valueOf("0.0.0.0"); + + if (dhcpPayload != null) { + + DHCPPacketType incomingPacketType = DHCPPacketType.getType(0); + for (DHCPOption option : dhcpPayload.getOptions()) { + if (option.getCode() == DHCP.DHCPOptionCode.OptionCode_MessageType.getValue()) { + byte[] data = option.getData(); + incomingPacketType = DHCPPacketType.getType(data[0]); + } + if (option.getCode() == DHCP.DHCPOptionCode.OptionCode_RequestedIP.getValue()) { + byte[] data = option.getData(); + requestedIP = Ip4Address.valueOf(data); + flagIfRequestedIP = true; + } + if (option.getCode() == DHCP.DHCPOptionCode.OptionCode_DHCPServerIp.getValue()) { + byte[] data = option.getData(); + serverIP = Ip4Address.valueOf(data); + flagIfServerIP = true; + } + } + DHCPPacketType outgoingPacketType; + MacAddress clientMAC = new MacAddress(dhcpPayload.getClientHardwareAddress()); + VlanId vlanId = VlanId.vlanId(packet.getVlanID()); + HostId hostId = HostId.hostId(clientMAC, vlanId); + + if (incomingPacketType.getValue() == DHCPPacketType.DHCPDISCOVER.getValue()) { + + outgoingPacketType = DHCPPacketType.DHCPOFFER; + Ip4Address ipOffered = dhcpStore.suggestIP(hostId, requestedIP); + if (ipOffered != null) { + Ethernet ethReply = buildReply(packet, ipOffered, + (byte) outgoingPacketType.getValue()); + sendReply(context, ethReply); + } + + } else if (incomingPacketType.getValue() == DHCPPacketType.DHCPREQUEST.getValue()) { + + if (flagIfServerIP && flagIfRequestedIP) { + // SELECTING state + if (myIP.equals(serverIP)) { + + if (dhcpStore.assignIP(hostId, requestedIP, leaseTime)) { + outgoingPacketType = DHCPPacketType.DHCPACK; + discoverHost(context, requestedIP); + } else { + outgoingPacketType = DHCPPacketType.DHCPNAK; + } + Ethernet ethReply = buildReply(packet, requestedIP, (byte) outgoingPacketType.getValue()); + sendReply(context, ethReply); + } + } else if (flagIfRequestedIP) { + // INIT-REBOOT state + if (dhcpStore.assignIP(hostId, requestedIP, leaseTime)) { + outgoingPacketType = DHCPPacketType.DHCPACK; + Ethernet ethReply = buildReply(packet, requestedIP, (byte) outgoingPacketType.getValue()); + sendReply(context, ethReply); + discoverHost(context, requestedIP); + } + + } else { + // RENEWING and REBINDING state + int ciaadr = dhcpPayload.getClientIPAddress(); + if (ciaadr != 0) { + Ip4Address clientIaddr = Ip4Address.valueOf(ciaadr); + if (dhcpStore.assignIP(hostId, clientIaddr, leaseTime)) { + outgoingPacketType = DHCPPacketType.DHCPACK; + discoverHost(context, clientIaddr); + } else if (packet.getEtherType() == Ethernet.TYPE_IPV4 && + ((IPv4) packet.getPayload()).getDestinationAddress() == myIP.toInt()) { + outgoingPacketType = DHCPPacketType.DHCPNAK; + } else { + return; + } + Ethernet ethReply = buildReply(packet, clientIaddr, (byte) outgoingPacketType.getValue()); + sendReply(context, ethReply); + } + } + } else if (incomingPacketType.getValue() == DHCPPacketType.DHCPRELEASE.getValue()) { + Ip4Address ip4Address = dhcpStore.releaseIP(hostId); + if (ip4Address != null) { + hostProviderService.removeIpFromHost(hostId, ip4Address); + } + } + } + } + + /** + * Processes the ARP Payload and initiates a reply to the client. + * + * @param context context of the incoming message + * @param packet the ethernet payload + */ + private void processARPPacket(PacketContext context, Ethernet packet) { + + ARP arpPacket = (ARP) packet.getPayload(); + + ARP arpReply = (ARP) arpPacket.clone(); + arpReply.setOpCode(ARP.OP_REPLY); + + arpReply.setTargetProtocolAddress(arpPacket.getSenderProtocolAddress()); + arpReply.setTargetHardwareAddress(arpPacket.getSenderHardwareAddress()); + arpReply.setSenderProtocolAddress(arpPacket.getTargetProtocolAddress()); + arpReply.setSenderHardwareAddress(myMAC.toBytes()); + + // Ethernet Frame. + Ethernet ethReply = new Ethernet(); + ethReply.setSourceMACAddress(myMAC); + ethReply.setDestinationMACAddress(packet.getSourceMAC()); + ethReply.setEtherType(Ethernet.TYPE_ARP); + ethReply.setVlanID(packet.getVlanID()); + + ethReply.setPayload(arpReply); + sendReply(context, ethReply); + } + + /** + * Integrates hosts learned through DHCP into topology. + * @param context context of the incoming message + * @param ipAssigned IP Address assigned to the host by DHCP Manager + */ + private void discoverHost(PacketContext context, Ip4Address ipAssigned) { + Ethernet packet = context.inPacket().parsed(); + MacAddress mac = packet.getSourceMAC(); + VlanId vlanId = VlanId.vlanId(packet.getVlanID()); + HostLocation hostLocation = new HostLocation(context.inPacket().receivedFrom(), 0); + + Set<IpAddress> ips = new HashSet<>(); + ips.add(ipAssigned); + + HostId hostId = HostId.hostId(mac, vlanId); + DefaultHostDescription desc = new DefaultHostDescription(mac, vlanId, hostLocation, ips); + hostProviderService.hostDetected(hostId, desc); + } + + + @Override + public void process(PacketContext context) { + Ethernet packet = context.inPacket().parsed(); + if (packet == null) { + return; + } + + if (packet.getEtherType() == Ethernet.TYPE_IPV4) { + IPv4 ipv4Packet = (IPv4) packet.getPayload(); + + if (ipv4Packet.getProtocol() == IPv4.PROTOCOL_UDP) { + UDP udpPacket = (UDP) ipv4Packet.getPayload(); + + if (udpPacket.getDestinationPort() == UDP.DHCP_SERVER_PORT && + udpPacket.getSourcePort() == UDP.DHCP_CLIENT_PORT) { + // This is meant for the dhcp server so process the packet here. + + DHCP dhcpPayload = (DHCP) udpPacket.getPayload(); + processDHCPPacket(context, dhcpPayload); + } + } + } else if (packet.getEtherType() == Ethernet.TYPE_ARP) { + ARP arpPacket = (ARP) packet.getPayload(); + + if ((arpPacket.getOpCode() == ARP.OP_REQUEST) && + Objects.equals(myIP, Ip4Address.valueOf(arpPacket.getTargetProtocolAddress()))) { + + processARPPacket(context, packet); + + } + } + } + } + + private class InternalConfigListener implements NetworkConfigListener { + + /** + * Reconfigures the DHCP Server according to the configuration parameters passed. + * + * @param cfg configuration object + */ + private void reconfigureNetwork(DhcpConfig cfg) { + if (cfg == null) { + return; + } + if (cfg.ip() != null) { + myIP = cfg.ip(); + } + if (cfg.mac() != null) { + myMAC = cfg.mac(); + } + if (cfg.subnetMask() != null) { + subnetMask = cfg.subnetMask(); + } + if (cfg.broadcastAddress() != null) { + broadcastAddress = cfg.broadcastAddress(); + } + if (cfg.routerAddress() != null) { + routerAddress = cfg.routerAddress(); + } + if (cfg.domainServer() != null) { + domainServer = cfg.domainServer(); + } + if (cfg.ttl() != -1) { + packetTTL = (byte) cfg.ttl(); + } + if (cfg.leaseTime() != -1) { + leaseTime = cfg.leaseTime(); + } + if (cfg.renewTime() != -1) { + renewalTime = cfg.renewTime(); + } + if (cfg.rebindTime() != -1) { + rebindingTime = cfg.rebindTime(); + } + if (cfg.defaultTimeout() != -1) { + dhcpStore.setDefaultTimeoutForPurge(cfg.defaultTimeout()); + } + if (cfg.timerDelay() != -1) { + timerDelay = cfg.timerDelay(); + } + if ((cfg.startIp() != null) && (cfg.endIp() != null)) { + dhcpStore.populateIPPoolfromRange(cfg.startIp(), cfg.endIp()); + } + } + + + @Override + public void event(NetworkConfigEvent event) { + + if ((event.type() == NetworkConfigEvent.Type.CONFIG_ADDED || + event.type() == NetworkConfigEvent.Type.CONFIG_UPDATED) && + event.configClass().equals(DhcpConfig.class)) { + + DhcpConfig cfg = cfgService.getConfig(appId, DhcpConfig.class); + reconfigureNetwork(cfg); + log.info("Reconfigured"); + } + } + } + + private class InternalHostProvider extends AbstractProvider implements HostProvider { + + /** + * Creates a provider with the supplier identifier. + */ + protected InternalHostProvider() { + super(PID); + } + + @Override + public void triggerProbe(Host host) { + // nothing to do + } + } + + private class PurgeListTask implements TimerTask { + + @Override + public void run(Timeout to) { + IpAssignment ipAssignment; + Date dateNow = new Date(); + + Map<HostId, IpAssignment> ipAssignmentMap = dhcpStore.listAllMapping(); + for (Map.Entry<HostId, IpAssignment> entry: ipAssignmentMap.entrySet()) { + ipAssignment = entry.getValue(); + + long timeLapsed = dateNow.getTime() - ipAssignment.timestamp().getTime(); + if ((ipAssignment.assignmentStatus() != IpAssignment.AssignmentStatus.Option_Expired) && + (ipAssignment.leasePeriod() > 0) && (timeLapsed > (ipAssignment.leasePeriodMs()))) { + + Ip4Address ip4Address = dhcpStore.releaseIP(entry.getKey()); + if (ip4Address != null) { + hostProviderService.removeIpFromHost(entry.getKey(), ipAssignment.ipAddress()); + } + } + } + timeout = Timer.getTimer().newTimeout(new PurgeListTask(), timerDelay, TimeUnit.MINUTES); + } + } +}
\ No newline at end of file |