148ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood/*
248ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood * Copyright (c) 2006-2011 Christian Plattner. All rights reserved.
348ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood * Please refer to the LICENSE.txt for licensing details.
448ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood */
548ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwoodpackage ch.ethz.ssh2.channel;
648ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood
748ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwoodimport java.io.IOException;
848ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwoodimport java.net.InetSocketAddress;
948ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwoodimport java.net.ServerSocket;
1048ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwoodimport java.net.Socket;
1148ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood
1248ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood/**
1348ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood * LocalAcceptThread.
1448ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood *
1548ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood * @author Christian Plattner
1648ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood * @version 2.50, 03/15/10
1748ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood */
1848ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwoodpublic class LocalAcceptThread extends Thread implements IChannelWorkerThread
1948ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood{
2048ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood	ChannelManager cm;
2148ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood	String host_to_connect;
2248ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood	int port_to_connect;
2348ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood
2448ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood	final ServerSocket ss;
2548ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood
2648ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood	public LocalAcceptThread(ChannelManager cm, int local_port, String host_to_connect, int port_to_connect)
2748ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood			throws IOException
2848ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood	{
2948ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood		this.cm = cm;
3048ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood		this.host_to_connect = host_to_connect;
3148ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood		this.port_to_connect = port_to_connect;
3248ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood
3348ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood		ss = new ServerSocket(local_port);
3448ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood	}
3548ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood
3648ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood	public LocalAcceptThread(ChannelManager cm, InetSocketAddress localAddress, String host_to_connect,
3748ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood			int port_to_connect) throws IOException
3848ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood	{
3948ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood		this.cm = cm;
4048ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood		this.host_to_connect = host_to_connect;
4148ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood		this.port_to_connect = port_to_connect;
4248ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood
4348ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood		ss = new ServerSocket();
4448ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood		ss.bind(localAddress);
4548ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood	}
4648ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood
4748ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood	@Override
4848ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood	public void run()
4948ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood	{
5048ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood		try
5148ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood		{
5248ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood			cm.registerThread(this);
5348ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood		}
5448ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood		catch (IOException e)
5548ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood		{
5648ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood			stopWorking();
5748ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood			return;
5848ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood		}
5948ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood
6048ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood		while (true)
6148ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood		{
6248ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood			Socket s = null;
6348ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood
6448ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood			try
6548ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood			{
6648ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood				s = ss.accept();
6748ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood			}
6848ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood			catch (IOException e)
6948ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood			{
7048ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood				stopWorking();
7148ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood				return;
7248ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood			}
7348ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood
7448ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood			Channel cn = null;
7548ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood			StreamForwarder r2l = null;
7648ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood			StreamForwarder l2r = null;
7748ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood
7848ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood			try
7948ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood			{
8048ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood				/* This may fail, e.g., if the remote port is closed (in optimistic terms: not open yet) */
8148ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood
8248ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood				cn = cm.openDirectTCPIPChannel(host_to_connect, port_to_connect, s.getInetAddress().getHostAddress(), s
8348ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood						.getPort());
8448ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood
8548ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood			}
8648ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood			catch (IOException e)
8748ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood			{
8848ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood				/* Simply close the local socket and wait for the next incoming connection */
8948ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood
9048ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood				try
9148ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood				{
9248ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood					s.close();
9348ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood				}
9448ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood				catch (IOException ignore)
9548ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood				{
9648ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood				}
9748ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood
9848ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood				continue;
9948ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood			}
10048ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood
10148ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood			try
10248ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood			{
10348ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood				r2l = new StreamForwarder(cn, null, null, cn.stdoutStream, s.getOutputStream(), "RemoteToLocal");
10448ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood				l2r = new StreamForwarder(cn, r2l, s, s.getInputStream(), cn.stdinStream, "LocalToRemote");
10548ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood			}
10648ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood			catch (IOException e)
10748ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood			{
10848ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood				try
10948ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood				{
11048ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood					/* This message is only visible during debugging, since we discard the channel immediatelly */
11148ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood					cn.cm.closeChannel(cn, "Weird error during creation of StreamForwarder (" + e.getMessage() + ")",
11248ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood							true);
11348ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood				}
11448ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood				catch (IOException ignore)
11548ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood				{
11648ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood				}
11748ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood
11848ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood				continue;
11948ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood			}
12048ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood
12148ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood			r2l.setDaemon(true);
12248ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood			l2r.setDaemon(true);
12348ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood			r2l.start();
12448ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood			l2r.start();
12548ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood		}
12648ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood	}
12748ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood
12848ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood	public void stopWorking()
12948ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood	{
13048ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood		try
13148ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood		{
13248ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood			/* This will lead to an IOException in the ss.accept() call */
13348ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood			ss.close();
13448ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood		}
13548ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood		catch (IOException ignored)
13648ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood		{
13748ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood		}
13848ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood	}
13948ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood}
140