package org.torproject.jtor.control.impl; import java.io.IOException; import java.net.ServerSocket; import java.net.Socket; import java.util.Iterator; import java.util.Vector; import org.torproject.jtor.TorConfig; import org.torproject.jtor.control.ControlConnectionHandler; import org.torproject.jtor.control.ControlServer; import org.torproject.jtor.directory.Directory; import org.torproject.jtor.events.Event; import org.torproject.jtor.events.EventHandler; import org.torproject.jtor.logging.LogManager; /** * * @author Merlijn Hofstra */ public class ControlServerTCP extends ControlServer implements EventHandler { private Vector<ControlConnectionHandler> connections = new Vector<ControlConnectionHandler>(); private ServerSocket ss; public ControlServerTCP(Directory directory, TorConfig tc, LogManager logManager) { super(directory, tc, logManager); } @Override public void startServer() { if (tc.getControlPort() > 0 && !running) { running = true; this.start(); } } @Override public void run() { try { if (host != null) { ss = new ServerSocket(tc.getControlPort(), 0, host); } else { ss = new ServerSocket(tc.getControlPort()); } } catch (IOException ex) { running = false; } tc.registerConfigChangedHandler(this); while (running) { try { Socket s = ss.accept(); ControlConnectionHandler cch = new ControlConnectionHandlerTCP(this, s); connections.add(cch); logger.debug("Opening new TCP Control Connection on port " + s.getLocalPort()); } catch (Throwable t) {} } } @SuppressWarnings("unchecked") @Override public void stopServer() { running = false; this.interrupt(); Iterator i = connections.iterator(); while (i.hasNext()) { ((ControlConnectionHandler)i.next()).disconnect(); } tc.unregisterConfigChangedHandler(this); } public void disconnectHandler(ControlConnectionHandler cch) { if (connections.remove(cch)) { cch.disconnect(); } } @Override public String getProtocol() { return "TCP"; } /* * Catches configuration updates * (non-Javadoc) * @see org.torproject.jtor.events.EventHandler#handleEvent(org.torproject.jtor.events.Event) */ public void handleEvent(Event event) { if (tc.getControlPort() != ss.getLocalPort()) { stopServer(); startServer(); } } }