1 /* 2 * Copyright (c) 2006-2011 Christian Plattner. All rights reserved. 3 * Please refer to the LICENSE.txt for licensing details. 4 */ 5 package ch.ethz.ssh2.channel; 6 7 import java.io.IOException; 8 import java.net.Socket; 9 10 import ch.ethz.ssh2.log.Logger; 11 12 /** 13 * RemoteAcceptThread. 14 * 15 * @author Christian Plattner 16 * @version $Id: RemoteAcceptThread.java 41 2011-06-02 10:36:41Z dkocher@sudo.ch $ 17 */ 18 public class RemoteAcceptThread extends Thread 19 { 20 private static final Logger log = Logger.getLogger(RemoteAcceptThread.class); 21 22 Channel c; 23 24 String remoteConnectedAddress; 25 int remoteConnectedPort; 26 String remoteOriginatorAddress; 27 int remoteOriginatorPort; 28 String targetAddress; 29 int targetPort; 30 31 Socket s; 32 RemoteAcceptThread(Channel c, String remoteConnectedAddress, int remoteConnectedPort, String remoteOriginatorAddress, int remoteOriginatorPort, String targetAddress, int targetPort)33 public RemoteAcceptThread(Channel c, String remoteConnectedAddress, int remoteConnectedPort, 34 String remoteOriginatorAddress, int remoteOriginatorPort, String targetAddress, int targetPort) 35 { 36 this.c = c; 37 this.remoteConnectedAddress = remoteConnectedAddress; 38 this.remoteConnectedPort = remoteConnectedPort; 39 this.remoteOriginatorAddress = remoteOriginatorAddress; 40 this.remoteOriginatorPort = remoteOriginatorPort; 41 this.targetAddress = targetAddress; 42 this.targetPort = targetPort; 43 44 log.debug("RemoteAcceptThread: " + remoteConnectedAddress + "/" + remoteConnectedPort + ", R: " 45 + remoteOriginatorAddress + "/" + remoteOriginatorPort); 46 } 47 48 @Override run()49 public void run() 50 { 51 try 52 { 53 c.cm.sendOpenConfirmation(c); 54 55 s = new Socket(targetAddress, targetPort); 56 57 StreamForwarder r2l = new StreamForwarder(c, null, null, c.getStdoutStream(), s.getOutputStream(), 58 "RemoteToLocal"); 59 StreamForwarder l2r = new StreamForwarder(c, null, null, s.getInputStream(), c.getStdinStream(), 60 "LocalToRemote"); 61 62 /* No need to start two threads, one can be executed in the current thread */ 63 64 r2l.setDaemon(true); 65 r2l.start(); 66 l2r.run(); 67 68 while (r2l.isAlive()) 69 { 70 try 71 { 72 r2l.join(); 73 } 74 catch (InterruptedException ignored) 75 { 76 } 77 } 78 79 /* If the channel is already closed, then this is a no-op */ 80 81 c.cm.closeChannel(c, "EOF on both streams reached.", true); 82 s.close(); 83 } 84 catch (IOException e) 85 { 86 log.warning("IOException in proxy code: " + e.getMessage()); 87 88 try 89 { 90 c.cm.closeChannel(c, "IOException in proxy code (" + e.getMessage() + ")", true); 91 } 92 catch (IOException ignored) 93 { 94 } 95 try 96 { 97 if (s != null) 98 s.close(); 99 } 100 catch (IOException ignored) 101 { 102 } 103 } 104 } 105 } 106