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