1/* 2 * Copyright (c) 2006-2011 Christian Plattner. All rights reserved. 3 * Please refer to the LICENSE.txt for licensing details. 4 */ 5package ch.ethz.ssh2.channel; 6 7import java.io.IOException; 8import java.net.Socket; 9 10import 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 */ 18public 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 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 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