/******************************************************************************* * Copyright (c) 2008, 2013 Wind River Systems, Inc. and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Wind River Systems - initial API and implementation *******************************************************************************/ package org.eclipse.tcf.core; import java.io.IOException; import java.io.InterruptedIOException; import java.net.InetAddress; import java.net.NetworkInterface; import java.net.ServerSocket; import java.net.Socket; import java.util.ArrayList; import java.util.Enumeration; import java.util.HashMap; import java.util.List; import java.util.Map; import org.eclipse.tcf.internal.core.ServiceManager; import org.eclipse.tcf.protocol.IPeer; import org.eclipse.tcf.protocol.Protocol; /** * ServerTCP is a TCP server that is listening for incoming connection requests * and creates TCF communication channels over TCP sockets for such requests. * * Clients may create objects of this class to become a TCF server. */ public class ServerTCP extends ServerSocket { private static class ServerPeer extends AbstractPeer { ServerPeer(Map<String,String> attrs) { super(attrs); } } private final String name; private List<ServerPeer> peers; private Thread thread; public ServerTCP(String name, int port) throws IOException { super(port); this.name = name; peers = new ArrayList<ServerPeer>(); Enumeration<NetworkInterface> e = NetworkInterface.getNetworkInterfaces(); while (e.hasMoreElements()) { NetworkInterface f = e.nextElement(); Enumeration<InetAddress> n = f.getInetAddresses(); while (n.hasMoreElements()) getServerPeer(n.nextElement()); } thread = new Thread() { @Override public void run() { while (true) { try { final Socket socket = accept(); Protocol.invokeLater(new Runnable() { public void run() { try { new ChannelTCP( getServerPeer(socket.getLocalAddress()), getTransientPeer(socket.getInetAddress()), socket); } catch (final Throwable x) { Protocol.log("TCF Server: failed to create a channel", x); } } }); } catch (final Throwable x) { Protocol.invokeLater(new Runnable() { public void run() { Protocol.log("TCF Server thread aborted", x); } }); break; } } } }; thread.setName(name); thread.setDaemon(true); thread.start(); } private IPeer getServerPeer(InetAddress addr) { if (addr.isAnyLocalAddress()) return getTransientPeer(addr); if (addr.isMulticastAddress()) return getTransientPeer(addr); if (addr.isLinkLocalAddress()) return getTransientPeer(addr); String host = addr.getHostAddress(); for (ServerPeer p : peers) { if (host.equals(p.getAttributes().get(IPeer.ATTR_IP_HOST))) return p; } String port = Integer.toString(getLocalPort()); Map<String,String> attrs = new HashMap<String,String>(); attrs.put(IPeer.ATTR_ID, "TCP:" + host + ":" + port); attrs.put(IPeer.ATTR_SERVICE_MANGER_ID, ServiceManager.getID()); attrs.put(IPeer.ATTR_AGENT_ID, Protocol.getAgentID()); attrs.put(IPeer.ATTR_NAME, name); attrs.put(IPeer.ATTR_OS_NAME, System.getProperty("os.name")); attrs.put(IPeer.ATTR_TRANSPORT_NAME, "TCP"); attrs.put(IPeer.ATTR_IP_HOST, host); attrs.put(IPeer.ATTR_IP_PORT, port); attrs.put(IPeer.ATTR_PROXY, ""); ServerPeer p = new ServerPeer(attrs); peers.add(p); return p; } private IPeer getTransientPeer(InetAddress addr) { String host = addr.getHostAddress(); Map<String,String> attrs = new HashMap<String,String>(); attrs.put(IPeer.ATTR_ID, "TCP:Transient:" + host + ":" + getLocalPort()); attrs.put(IPeer.ATTR_TRANSPORT_NAME, "TCP"); attrs.put(IPeer.ATTR_IP_HOST, host); return new TransientPeer(attrs); } @Override public void close() throws IOException { if (peers != null) { for (ServerPeer s : peers) s.dispose(); peers = null; } super.close(); if (thread != null) { try { thread.join(); thread = null; } catch (InterruptedException e) { throw new InterruptedIOException(); } } } }