import java.net.*; import java.io.*; import java.util.*; public class Tunnel { private String mAddress; private String mPort; private String mTTL; private String dAddress; private String dPort; private String addressServer; private boolean active = true; private HashSet set = new HashSet(); private boolean showActions; private int datagramSize = 8192; private TunnelSender ts = new TunnelSender(); private TunnelReceiver tr = new TunnelReceiver(); public Tunnel(String mAddress, String mPort, String mTTL, String dAddress, String dPort, String addressServer, boolean showActions) { this.mAddress = mAddress; this.mPort = mPort; this.mTTL = mTTL; this.dAddress = dAddress; this.dPort = dPort; this.addressServer = addressServer; this.showActions = showActions; ts.start(); tr.start(); } public void stopTunnel() { if(showActions) System.out.println("STOPPING TUNNEL"); active = false; try { // Nu måste man skicka något till de sockets som låst sig i recevive byte[] data = "foo".getBytes(); // 1. Sänd till ts.ms MulticastSocket ms = new MulticastSocket(); ms.setTimeToLive(Integer.parseInt(mTTL)); if(dAddress.equals(addressServer)) ms.setInterface(InetAddress.getByName("localhost")); DatagramPacket p1 = new DatagramPacket(data, data.length, InetAddress.getByName(mAddress), Integer.parseInt(mPort)); ms.send(p1); if(showActions) System.out.println("MS SENT: " + "foo"); // 2. Sänd till tr.ds DatagramSocket ds = new DatagramSocket(); DatagramPacket p2 = new DatagramPacket(data, data.length, InetAddress.getByName(addressServer), Integer.parseInt(dPort)); ds.send(p2); if(showActions) System.out.println("DS SENT: " + "foo"); } catch(Exception e) { if(showActions) e.printStackTrace(); } } class TunnelSender extends Thread { // 1. läsa multicast-paket från en multicast-socket // 2. sända dem som datagram-paket via en datagram-socket till servern public void run() { MulticastSocket ms = null; DatagramSocket ds = null; try { ms = new MulticastSocket(Integer.parseInt(mPort)); ms.joinGroup(InetAddress.getByName(mAddress)); if(dAddress.equals(addressServer)) ms.setInterface(InetAddress.getByName("localhost")); ds = new DatagramSocket(); } catch(Exception e) { if(showActions) e.printStackTrace(); } String message = null; while(active) { try { // Läsa av multicast-socket byte[] data = new byte[datagramSize]; DatagramPacket p = new DatagramPacket(data, data.length); ms.receive(p); message = new String(data, 0, p.getLength()); if(showActions) System.out.println("MS RECEIVED: " + message); // Sända via datagram-socket // Här måste man lägga in en kontroll så man inte kommer i en oandlig loop :-) if(set.contains(message)) { set.remove(message); } else { p.setAddress(InetAddress.getByName(dAddress)); p.setPort(Integer.parseInt(dPort)); ds.send(p); if(showActions) System.out.println("DS SENT: " + message); } } catch(Exception e) { active = false; if(showActions) e.printStackTrace(); } } ms.close(); ds.close(); } } class TunnelReceiver extends Thread { // 1. ta emot datagram-paket via en datagram-socket från servern // 2. sända dem som multicast-paket från en multicast-socket public void run() { DatagramSocket ds = null; MulticastSocket ms = null; try { ds = new DatagramSocket(Integer.parseInt(dPort)); ms = new MulticastSocket(); ms.setTimeToLive(Integer.parseInt(mTTL)); if(dAddress.equals(addressServer)) ms.setInterface(InetAddress.getByName("localhost")); } catch(Exception e) { if(showActions) e.printStackTrace(); } String message = null; while(active) { try { // Läsa av datagram-socket byte[] data = new byte[datagramSize]; DatagramPacket p = new DatagramPacket(data, data.length); ds.receive(p); message = new String(data, 0, p.getLength()); if(showActions) System.out.println("DS RECEIVED: " + message); // Sända via multicast-socket // Här måste man lägga in meddelandet i en datasamling så man vet att man inte ska ta in det igen :-) set.add(message); p.setAddress(InetAddress.getByName(mAddress)); p.setPort(Integer.parseInt(mPort)); ms.send(p); if(showActions) System.out.println("MS SENT: " + message); } catch(Exception e) { active = false; if(showActions) e.printStackTrace(); } } ms.close(); ds.close(); } } }