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 Lockwood/**
848ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood * Channel.
948ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood *
1048ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood * @author Christian Plattner
1148ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood * @version $Id: Channel.java 14 2011-05-27 14:28:21Z dkocher@sudo.ch $
1248ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood */
1348ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwoodpublic class Channel
1448ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood{
1548ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood	/*
1648ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood		  * OK. Here is an important part of the JVM Specification:
1748ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood		  * (http://java.sun.com/docs/books/vmspec/2nd-edition/html/Threads.doc.html#22214)
1848ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood		  *
1948ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood		  * Any association between locks and variables is purely conventional.
2048ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood		  * Locking any lock conceptually flushes all variables from a thread's
2148ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood		  * working memory, and unlocking any lock forces the writing out to main
2248ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood		  * memory of all variables that the thread has assigned. That a lock may be
2348ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood		  * associated with a particular object or a class is purely a convention.
2448ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood		  * (...)
2548ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood		  *
2648ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood		  * If a thread uses a particular shared variable only after locking a
2748ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood		  * particular lock and before the corresponding unlocking of that same lock,
2848ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood		  * then the thread will read the shared value of that variable from main
2948ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood		  * memory after the lock operation, if necessary, and will copy back to main
3048ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood		  * memory the value most recently assigned to that variable before the
3148ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood		  * unlock operation.
3248ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood		  *
3348ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood		  * This, in conjunction with the mutual exclusion rules for locks, suffices
3448ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood		  * to guarantee that values are correctly transmitted from one thread to
3548ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood		  * another through shared variables.
3648ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood		  *
3748ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood		  * ====> Always keep that in mind when modifying the Channel/ChannelManger
3848ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood		  * code.
3948ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood		  *
4048ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood		  */
4148ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood
4248ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood	public static final int STATE_OPENING = 1;
4348ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood	public static final int STATE_OPEN = 2;
4448ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood	public static final int STATE_CLOSED = 4;
4548ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood
4648ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood	static final int CHANNEL_BUFFER_SIZE = 32 * 1024 * 3 * 2;
4748ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood
4848ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood	/*
4948ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood		  * To achieve correctness, the following rules have to be respected when
5048ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood		  * accessing this object:
5148ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood		  */
5248ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood
5348ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood	// These fields can always be read
5448ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood	final ChannelManager cm;
5548ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood	final ChannelOutputStream stdinStream;
5648ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood	final ChannelInputStream stdoutStream;
5748ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood	final ChannelInputStream stderrStream;
5848ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood
5948ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood	// These two fields will only be written while the Channel is in state
6048ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood	// STATE_OPENING.
6148ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood	// The code makes sure that the two fields are written out when the state is
6248ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood	// changing to STATE_OPEN.
6348ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood	// Therefore, if you know that the Channel is in state STATE_OPEN, then you
6448ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood	// can read these two fields without synchronizing on the Channel. However, make
6548ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood	// sure that you get the latest values (e.g., flush caches by synchronizing on any
6648ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood	// object). However, to be on the safe side, you can lock the channel.
6748ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood
6848ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood	int localID = -1;
6948ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood	int remoteID = -1;
7048ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood
7148ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood	/*
7248ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood		  * Make sure that we never send a data/EOF/WindowChange msg after a CLOSE
7348ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood		  * msg.
7448ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood		  *
7548ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood		  * This is a little bit complicated, but we have to do it in that way, since
7648ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood		  * we cannot keep a lock on the Channel during the send operation (this
7748ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood		  * would block sometimes the receiver thread, and, in extreme cases, can
7848ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood		  * lead to a deadlock on both sides of the connection (senders are blocked
7948ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood		  * since the receive buffers on the other side are full, and receiver
8048ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood		  * threads wait for the senders to finish). It all depends on the
8148ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood		  * implementation on the other side. But we cannot make any assumptions, we
8248ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood		  * have to assume the worst case. Confused? Just believe me.
8348ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood		  */
8448ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood
8548ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood	/*
8648ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood		  * If you send a message on a channel, then you have to aquire the
8748ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood		  * "channelSendLock" and check the "closeMessageSent" flag (this variable
8848ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood		  * may only be accessed while holding the "channelSendLock" !!!
8948ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood		  *
9048ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood		  * BTW: NEVER EVER SEND MESSAGES FROM THE RECEIVE THREAD - see explanation
9148ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood		  * above.
9248ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood		  */
9348ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood
9448ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood	final Object channelSendLock = new Object();
9548ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood	boolean closeMessageSent = false;
9648ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood
9748ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood	/*
9848ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood		  * Stop memory fragmentation by allocating this often used buffer.
9948ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood		  * May only be used while holding the channelSendLock
10048ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood		  */
10148ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood
10248ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood	final byte[] msgWindowAdjust = new byte[9];
10348ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood
10448ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood	// If you access (read or write) any of the following fields, then you have
10548ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood	// to synchronize on the channel.
10648ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood
10748ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood	int state = STATE_OPENING;
10848ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood
10948ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood	boolean closeMessageRecv = false;
11048ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood
11148ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood	/* This is a stupid implementation. At the moment we can only wait
11248ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood		  * for one pending request per channel.
11348ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood		  */
11448ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood	int successCounter = 0;
11548ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood	int failedCounter = 0;
11648ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood
11748ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood	int localWindow = 0; /* locally, we use a small window, < 2^31 */
11848ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood	long remoteWindow = 0; /* long for readable  2^32 - 1 window support */
11948ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood
12048ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood	int localMaxPacketSize = -1;
12148ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood	int remoteMaxPacketSize = -1;
12248ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood
12348ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood	final byte[] stdoutBuffer = new byte[CHANNEL_BUFFER_SIZE];
12448ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood	final byte[] stderrBuffer = new byte[CHANNEL_BUFFER_SIZE];
12548ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood
12648ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood	int stdoutReadpos = 0;
12748ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood	int stdoutWritepos = 0;
12848ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood	int stderrReadpos = 0;
12948ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood	int stderrWritepos = 0;
13048ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood
13148ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood	boolean EOF = false;
13248ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood
13348ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood	Integer exit_status;
13448ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood
13548ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood	String exit_signal;
13648ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood
13748ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood	// we keep the x11 cookie so that this channel can be closed when this
13848ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood	// specific x11 forwarding gets stopped
13948ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood
14048ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood	String hexX11FakeCookie;
14148ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood
14248ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood	// reasonClosed is special, since we sometimes need to access it
14348ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood	// while holding the channelSendLock.
14448ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood	// We protect it with a private short term lock.
14548ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood
14648ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood	private final Object reasonClosedLock = new Object();
14748ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood	private String reasonClosed = null;
14848ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood
14948ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood	public Channel(ChannelManager cm)
15048ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood	{
15148ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood		this.cm = cm;
15248ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood
15348ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood		this.localWindow = CHANNEL_BUFFER_SIZE;
15448ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood		this.localMaxPacketSize = 32 * 1024;
15548ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood
15648ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood		this.stdinStream = new ChannelOutputStream(this);
15748ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood		this.stdoutStream = new ChannelInputStream(this, false);
15848ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood		this.stderrStream = new ChannelInputStream(this, true);
15948ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood	}
16048ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood
16148ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood	/* Methods to allow access from classes outside of this package */
16248ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood
16348ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood	public ChannelInputStream getStderrStream()
16448ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood	{
16548ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood		return stderrStream;
16648ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood	}
16748ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood
16848ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood	public ChannelOutputStream getStdinStream()
16948ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood	{
17048ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood		return stdinStream;
17148ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood	}
17248ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood
17348ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood	public ChannelInputStream getStdoutStream()
17448ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood	{
17548ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood		return stdoutStream;
17648ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood	}
17748ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood
17848ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood	public String getExitSignal()
17948ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood	{
18048ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood		synchronized (this)
18148ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood		{
18248ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood			return exit_signal;
18348ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood		}
18448ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood	}
18548ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood
18648ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood	public Integer getExitStatus()
18748ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood	{
18848ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood		synchronized (this)
18948ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood		{
19048ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood			return exit_status;
19148ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood		}
19248ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood	}
19348ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood
19448ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood	public String getReasonClosed()
19548ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood	{
19648ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood		synchronized (reasonClosedLock)
19748ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood		{
19848ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood			return reasonClosed;
19948ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood		}
20048ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood	}
20148ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood
20248ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood	public void setReasonClosed(String reasonClosed)
20348ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood	{
20448ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood		synchronized (reasonClosedLock)
20548ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood		{
20648ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood			if (this.reasonClosed == null)
20748ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood			{
20848ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood				this.reasonClosed = reasonClosed;
20948ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood			}
21048ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood		}
21148ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood	}
21248ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood
21348ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood	public int getState()
21448ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood	{
21548ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood		return this.state;
21648ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood	}
21748ded2421114c4c87ef3f8005c9f793a5d077cbdMike Lockwood}
218