+
+ private void startPeriodicTimer() {
+ this.periodicTimer = new Timer("ArpHandler Periodic Timer");
+ this.periodicTimer.scheduleAtFixedRate(new TimerTask() {
+ @Override
+ public void run() {
+ Set<InetAddress> targetIPs = countDownTimers.keySet();
+ Set<InetAddress> expiredTargets = new HashSet<InetAddress>();
+ for (InetAddress t : targetIPs) {
+ short tick = countDownTimers.get(t);
+ tick--;
+ if (tick <= 0) {
+ expiredTargets.add(t);
+ } else {
+ countDownTimers.replace(t, tick);
+ }
+ }
+ for (InetAddress t : expiredTargets) {
+ countDownTimers.remove(t);
+ // remove the requestor(s) who have been waited for the ARP
+ // reply from this target for more than 1sec
+ arpRequestors.remove(t);
+ logger.debug("{} didn't respond to ARP request", t);
+ }
+ }
+ }, 0, 1000);
+ }
+
+ private void cancelPeriodicTimer() {
+ if (this.periodicTimer != null) {
+ this.periodicTimer.cancel();
+ }
+ }
+
+ private void generateAndSendReply(InetAddress sourceIP, byte[] sourceMAC) {
+ Set<HostNodeConnector> hosts = arpRequestors.remove(sourceIP);
+ if ((hosts == null) || hosts.isEmpty()) {
+ return;
+ }
+ countDownTimers.remove(sourceIP);
+ for (HostNodeConnector host : hosts) {
+ logger.debug(
+ "Sending ARP Reply with src {}/{}, target {}/{}",
+ new Object[] { sourceMAC, sourceIP,
+ host.getDataLayerAddressBytes(),
+ host.getNetworkAddress() });
+ sendARPReply(host.getnodeConnector(), sourceMAC, sourceIP,
+ host.getDataLayerAddressBytes(), host.getNetworkAddress());
+ }
+ }