mirror of https://github.com/apache/cloudstack.git
156 lines
4.3 KiB
Java
156 lines
4.3 KiB
Java
/**
|
|
* * Copyright (C) 2011 Citrix Systems, Inc. All rights reserved
|
|
*
|
|
*
|
|
* This software is licensed under the GNU General Public License v3 or later.
|
|
*
|
|
* It is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation, either version 3 of the License, or any later version.
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*
|
|
*/
|
|
|
|
package com.cloud.agent;
|
|
|
|
import java.io.IOException;
|
|
import java.net.DatagramPacket;
|
|
import java.net.DatagramSocket;
|
|
import java.net.InetAddress;
|
|
import java.net.MulticastSocket;
|
|
import java.net.NetworkInterface;
|
|
import java.net.SocketException;
|
|
import java.util.ArrayList;
|
|
import java.util.List;
|
|
|
|
import org.apache.log4j.Logger;
|
|
|
|
public class MultiCaster implements Runnable {
|
|
private static final Logger s_logger = Logger.getLogger(MultiCaster.class);
|
|
|
|
public final int MAX_PACKET_SIZE = 8096;
|
|
|
|
private List<MultiCasterListener> listeners;
|
|
private DatagramSocket socket;
|
|
private byte[] recvBuffer;
|
|
|
|
private Thread driver;
|
|
private volatile boolean stopRequested = false;
|
|
|
|
public MultiCaster() {
|
|
listeners = new ArrayList<MultiCasterListener>();
|
|
recvBuffer = new byte[MAX_PACKET_SIZE];
|
|
}
|
|
|
|
public void addListener(MultiCasterListener listener) {
|
|
synchronized(listeners) {
|
|
listeners.add(listener);
|
|
}
|
|
}
|
|
|
|
public void removeListener(MultiCasterListener listener) {
|
|
synchronized(listeners) {
|
|
listeners.remove(listener);
|
|
}
|
|
}
|
|
|
|
public void cast(byte[] buf, int off, int len,
|
|
InetAddress toAddress, int nToPort) throws IOException {
|
|
|
|
if(socket == null)
|
|
throw new IOException("multi caster is not started");
|
|
|
|
if(len >= MAX_PACKET_SIZE)
|
|
throw new IOException("packet size exceeds limit of " + MAX_PACKET_SIZE);
|
|
|
|
DatagramPacket packet = new DatagramPacket(buf, off,
|
|
len, toAddress, nToPort);
|
|
|
|
socket.send(packet);
|
|
}
|
|
|
|
public void start(String strOutboundAddress,
|
|
String strClusterAddress, int nPort) throws SocketException {
|
|
assert(socket == null);
|
|
|
|
InetAddress addr = null;
|
|
try {
|
|
addr = InetAddress.getByName(strClusterAddress);
|
|
} catch(IOException e) {
|
|
s_logger.error("Unexpected exception " , e);
|
|
}
|
|
|
|
if(addr != null && addr.isMulticastAddress()) {
|
|
try {
|
|
socket = new MulticastSocket(nPort);
|
|
socket.setReuseAddress(true);
|
|
|
|
if(s_logger.isInfoEnabled())
|
|
s_logger.info("Join multicast group : " + addr);
|
|
|
|
((MulticastSocket)socket).joinGroup(addr);
|
|
((MulticastSocket)socket).setTimeToLive(1);
|
|
|
|
if(strOutboundAddress != null) {
|
|
if(s_logger.isInfoEnabled())
|
|
s_logger.info("set outgoing interface to : " + strOutboundAddress);
|
|
|
|
InetAddress ia = InetAddress.getByName(strOutboundAddress);
|
|
NetworkInterface ni = NetworkInterface.getByInetAddress(ia);
|
|
((MulticastSocket)socket).setNetworkInterface(ni);
|
|
}
|
|
} catch(IOException e) {
|
|
s_logger.error("Unexpected exception " , e);
|
|
}
|
|
} else {
|
|
socket = new DatagramSocket(nPort);
|
|
socket.setReuseAddress(true);
|
|
}
|
|
|
|
driver = new Thread(this, "Multi-caster");
|
|
driver.setDaemon(true);
|
|
driver.start();
|
|
}
|
|
|
|
public void stop() {
|
|
if(socket != null) {
|
|
stopRequested = true;
|
|
|
|
socket.close();
|
|
if(driver != null) {
|
|
try {
|
|
driver.join();
|
|
} catch(InterruptedException e) {
|
|
}
|
|
driver = null;
|
|
}
|
|
}
|
|
|
|
socket = null;
|
|
stopRequested = false;
|
|
}
|
|
|
|
public void run() {
|
|
while(!stopRequested) {
|
|
try {
|
|
DatagramPacket packet = new DatagramPacket(recvBuffer, recvBuffer.length);
|
|
socket.receive(packet);
|
|
|
|
for(Object listener : listeners.toArray()) {
|
|
((MultiCasterListener)listener).onMultiCasting(packet.getData(),
|
|
packet.getOffset(), packet.getLength(), packet.getAddress());
|
|
}
|
|
} catch(IOException e) {
|
|
} catch(Throwable e) {
|
|
s_logger.error("Unhandled exception : ", e);
|
|
}
|
|
}
|
|
}
|
|
}
|