1 19 20 package com.sslexplorer.agent.client.tunneling; 21 22 import java.io.IOException ; 23 import java.net.DatagramSocket ; 24 import java.net.InetAddress ; 25 import java.net.ServerSocket ; 26 import java.net.Socket ; 27 import java.util.Enumeration ; 28 import java.util.Vector ; 29 30 import com.maverick.multiplex.Channel; 31 import com.maverick.multiplex.channels.LocalForwardingChannel; 32 import com.sslexplorer.agent.client.Agent; 33 import com.sslexplorer.agent.client.util.IOStreamConnectorListener; 34 import com.sslexplorer.agent.client.util.TunnelConfiguration; 35 36 37 62 public class LocalTunnelServer implements LocalTunnelConnectionEventListener { 63 64 private Agent vpn; 66 private ServerSocket server; 67 private Thread thread; 68 private boolean listening; 69 private Vector activeTunnels; 70 private IOStreamConnectorListener txListener; 71 private IOStreamConnectorListener rxListener; 72 private String ticket; 73 private TunnelConfiguration listeningSocketConfiguration; 74 private long dataLastTransferred; 75 private DatagramSocket datagramSocket; 76 private boolean stopping = false; 77 private int totalTunnels; 78 private Vector listeners; 79 80 static org.apache.commons.logging.Log log = org.apache.commons.logging.LogFactory.getLog(LocalTunnelServer.class); 82 84 92 public LocalTunnelServer(Agent vpn, IOStreamConnectorListener txListener, IOStreamConnectorListener rxListener, 93 TunnelConfiguration listeningSocketConfiguration) { 94 this.vpn = vpn; 95 this.listeningSocketConfiguration = listeningSocketConfiguration; 96 this.txListener = txListener; 97 this.rxListener = rxListener; 98 listeners = new Vector (); 99 this.activeTunnels = new Vector (); 100 dataLastTransferred = System.currentTimeMillis(); 101 } 102 103 108 public void addListener(LocalTunnelServerListener listener) { 109 if (listener != null) 110 listeners.addElement(listener); 111 } 112 113 118 public int getActiveTunnelCount() { 119 return activeTunnels.size(); 120 } 121 122 128 public int getTotalTunnelCount() { 129 return totalTunnels; 130 } 131 132 137 public TunnelConfiguration getTunnel() { 138 return listeningSocketConfiguration; 139 } 140 141 147 public int getId() { 148 return listeningSocketConfiguration.getId(); 149 } 150 151 158 public int getLocalPort() { 159 return (server == null) ? (datagramSocket == null ? -1 : datagramSocket.getLocalPort()) : server.getLocalPort(); 160 } 161 162 170 public boolean isListening() { 171 return listening; 172 } 173 174 181 public long getDataLastTransferredTime() { 182 return dataLastTransferred; 183 } 184 185 193 public boolean isRunning() { 194 return (thread != null) && thread.isAlive(); 195 } 196 197 203 public String getTicket() { 204 return ticket; 205 } 206 207 213 public void start() throws IOException { 214 if(stopping) { 215 throw new IOException ("Local forwarding is currently stopping."); 216 } 217 if(isListening()) { 218 throw new IOException ("Local forwarding is already listening."); 219 } 220 221 dataLastTransferred = System.currentTimeMillis(); 222 223 if(listeningSocketConfiguration.isPermanent()) { 225 log.info("Starting permanent listening socket on port " + listeningSocketConfiguration.getSourcePort()); } 227 else { 228 log.info("Starting temporary listening socket on port " + listeningSocketConfiguration.getSourcePort()); } 230 232 233 if (listeningSocketConfiguration.getTransport().equals(TunnelConfiguration.UDP_TUNNEL)) { 234 log.info("Creating UDP server socket on port " + listeningSocketConfiguration.getSourcePort()); datagramSocket = new DatagramSocket (listeningSocketConfiguration.getSourcePort()); 238 } else { 239 if(listeningSocketConfiguration.getSourcePort() == 0) 241 log.info("Creating TCP server socket random port") ; else 243 log.info("Creating TCP server socket on port " + listeningSocketConfiguration.getSourcePort()) ; 250 boolean resetPort = listeningSocketConfiguration.getSourcePort() == 0; 251 server = new ServerSocket (listeningSocketConfiguration.getSourcePort(), 50, InetAddress.getByName(getAddressToBind())); 252 if(resetPort) { 253 log.info("Chosen port " + server.getLocalPort()) ; listeningSocketConfiguration.setSourcePort(server.getLocalPort()); 257 } 258 } 259 260 fireLocalTunnelServerStarted(); 261 thread = new Thread (new Runnable () { 262 public void run() { 263 tunnelTCP(); 264 } 265 }); 266 thread.setDaemon(true); 267 thread.setName("SocketListener " + getAddressToBind() + ":" + String.valueOf(listeningSocketConfiguration.getSourcePort())); thread.start(); 269 } 270 271 276 public boolean isStopping() { 277 return stopping; 278 } 279 280 287 public void stop() { 288 try { 289 stopping = true; 290 291 if(listeningSocketConfiguration.isPermanent()) { 293 log.info("Stopping permanent listening socket on port " + listeningSocketConfiguration.getSourcePort()); } 295 else { 296 log.info("Stopping temporary listening socket on port " + listeningSocketConfiguration.getSourcePort()); } 298 300 synchronized(activeTunnels) { 301 302 for (Enumeration e = activeTunnels.elements(); e.hasMoreElements();) { 303 ((LocalTunnelConnection) e.nextElement()).stop(); 304 } 305 306 activeTunnels.removeAllElements(); 307 } 308 309 310 if (server != null) { 311 log.info("Closing server socket on port " + server.getLocalPort()); 313 server.close(); 315 } 316 } catch (IOException ioe) { 317 } 318 319 server = null; 320 thread = null; 321 listening = false; 322 fireLocalTunnelServerStopped(); 323 stopping = false; 324 } 325 326 329 public void run() { 330 tunnelTCP(); 331 } 332 333 private Channel openChannel(TunnelConfiguration conf) throws IOException { 334 335 try { 336 LocalForwardingChannel channel = new LocalForwardingChannel(conf.getDestinationHost(), conf.getDestinationPort()); 337 vpn.getConnection().openChannel(channel); 338 return channel; 339 } catch (Exception e) { 340 throw new IOException ("Failed to open direct-tcpip channel to " + conf.getDestinationHost() + ":" + conf.getDestinationPort()); 341 } 342 } 343 344 void tunnelTCP() { 345 stopping = false; 346 Socket socket = null; 347 try { 348 349 listening = true; 350 351 while (listening) { 352 try { 353 socket = server.accept(); 354 if (!listening || (socket == null)) { 355 break; 356 } 357 358 try { 359 LocalTunnelConnection vpntunnel = new LocalTunnelConnection(this, openChannel(listeningSocketConfiguration), socket, getTunnel(), txListener, rxListener); 361 vpntunnel.addListener(this); 362 vpntunnel.start(); 363 364 } catch (Throwable ex) { 365 log.info(Messages.getString("LocalTunnelConnectionListener.failedToConnectTunnelingRequest"), ex); try { 369 socket.close(); 370 } catch (IOException ioe) { 371 } 372 373 if (listeningSocketConfiguration.isTemporarySingleConnect()) { 374 throw ex; 375 } 376 } 377 378 if(listeningSocketConfiguration.isTemporarySingleConnect()) { 379 log.info(Messages.getString("LocalTunnelConnectionListener.notAcceptingMoreAsTemp")); break; 383 } 384 } catch (IOException ioe) { 385 log.info(Messages.getString("LocalTunnelConnectionListener.failedToConnectTunnelingRequest")); } 389 } 390 } catch (Throwable ex) { 391 if (!stopping) { 392 log.info(Messages.getString("LocalTunnelConnectionListener.connectionListenerThreadFailed"), ex); stop(); 396 } 397 } 398 } 399 400 void fireLocalTunnelServerStopped() { 401 for(Enumeration e = listeners.elements(); e.hasMoreElements(); ) { 402 ((LocalTunnelServerListener)e.nextElement()).localTunnelStopped(this); 403 } 404 } 405 406 void fireLocalTunnelServerStarted() { 407 for(Enumeration e = listeners.elements(); e.hasMoreElements(); ) { 408 ((LocalTunnelServerListener)e.nextElement()).localTunnelServerStarted(this); 409 } 410 } 411 412 void fireLocalTunnelDataTransferred(byte[] buf, int count, boolean sent) { 413 for(Enumeration e = listeners.elements(); e.hasMoreElements(); ) { 414 ((LocalTunnelServerListener)e.nextElement()).localTunnelDataTransferred(this, buf, count, sent); 415 } 416 } 417 418 void fireActiveTunnelStarted(LocalTunnelConnection activeTunnel) { 419 for(Enumeration e = listeners.elements(); e.hasMoreElements(); ) { 420 ((LocalTunnelServerListener)e.nextElement()).localTunnelConnectionStarted(this, activeTunnel); 421 } 422 } 423 424 void fireActiveTunnelDataTransferred(LocalTunnelConnection activeTunnel, byte[] buf, int count, boolean sent) { 425 for(Enumeration e = listeners.elements(); e.hasMoreElements(); ) { 426 ((LocalTunnelServerListener)e.nextElement()).localTunnelConnectionDataTransferred(this, activeTunnel, buf, count, sent); 427 } 428 } 429 430 void fireActiveTunnelStopped(LocalTunnelConnection activeTunnel) { 431 for(Enumeration e = listeners.elements(); e.hasMoreElements(); ) { 432 ((LocalTunnelServerListener)e.nextElement()).localTunnelConnectionStopped(this, activeTunnel); 433 } 434 } 435 436 String getAddressToBind() { 437 if(listeningSocketConfiguration.getSourceInterface() != null && 438 !listeningSocketConfiguration.getSourceInterface().equals("")) { return listeningSocketConfiguration.getSourceInterface(); 440 } 441 else { 442 return "0.0.0.0"; 443 } 444 } 445 446 public void localTunnelConnectionStarted(LocalTunnelConnection tunnel) { 447 synchronized (activeTunnels) { 448 totalTunnels++; 449 activeTunnels.addElement(tunnel); 450 fireActiveTunnelStarted(tunnel); 451 } 452 } 453 454 public void localTunnelConnectionStopped(LocalTunnelConnection tunnel) { 455 synchronized (activeTunnels) { 456 if(!stopping) 457 activeTunnels.removeElement(tunnel); 458 fireActiveTunnelStopped(tunnel); 459 } 460 } 461 462 public void localTunnelConnectionDataTransferred(LocalTunnelConnection tunnel, byte[] buffer, int count, boolean sent) { 463 dataLastTransferred = System.currentTimeMillis(); 464 fireActiveTunnelDataTransferred(tunnel, buffer, count, sent); 465 fireLocalTunnelDataTransferred(buffer, count, sent); 466 } 467 } 468 | Popular Tags |