⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 channelmanager.java

📁 thinking in java4 src
💻 JAVA
📖 第 1 页 / 共 3 页
字号:

		int id = ((msg[1] & 0xff) << 24) | ((msg[2] & 0xff) << 16) | ((msg[3] & 0xff) << 8) | (msg[4] & 0xff);
		int windowChange = ((msg[5] & 0xff) << 24) | ((msg[6] & 0xff) << 16) | ((msg[7] & 0xff) << 8) | (msg[8] & 0xff);

		Channel c = getChannel(id);

		if (c == null)
			throw new IOException("Unexpected SSH_MSG_CHANNEL_WINDOW_ADJUST message for non-existent channel " + id);

		synchronized (c)
		{
			final long huge = 0xFFFFffffL; /* 2^32 - 1 */

			c.remoteWindow += (windowChange & huge); /* avoid sign extension */

			if ((c.remoteWindow > huge))
				c.remoteWindow = huge;

			c.notifyAll();
		}

		if (log.isEnabled())
			log.log(80, "Got SSH_MSG_CHANNEL_WINDOW_ADJUST (channel " + id + ", " + windowChange + ")");
	}

	public void msgChannelOpen(byte[] msg, int msglen) throws IOException
	{
		TypesReader tr = new TypesReader(msg, 0, msglen);

		tr.readByte(); // skip packet type
		String channelType = tr.readString();
		int remoteID = tr.readUINT32(); /* sender channel */
		int remoteWindow = tr.readUINT32(); /* initial window size */
		int remoteMaxPacketSize = tr.readUINT32(); /* maximum packet size */

		if ("x11".equals(channelType))
		{
			synchronized (x11_magic_cookies)
			{
				/* If we did not request X11 forwarding, then simply ignore this bogus request. */

				if (x11_magic_cookies.size() == 0)
				{
					PacketChannelOpenFailure pcof = new PacketChannelOpenFailure(remoteID,
							Packets.SSH_OPEN_ADMINISTRATIVELY_PROHIBITED, "X11 forwarding not activated", "");

					tm.sendAsynchronousMessage(pcof.getPayload());

					if (log.isEnabled())
						log.log(20, "Unexpected X11 request, denying it!");

					return;
				}
			}

			String remoteOriginatorAddress = tr.readString();
			int remoteOriginatorPort = tr.readUINT32();

			Channel c = new Channel(this);

			synchronized (c)
			{
				c.remoteID = remoteID;
				c.remoteWindow = remoteWindow & 0xFFFFffffL; /* properly convert UINT32 to long */
				c.remoteMaxPacketSize = remoteMaxPacketSize;
				c.localID = addChannel(c);
			}

			/*
			 * The open confirmation message will be sent from another thread
			 */

			RemoteX11AcceptThread rxat = new RemoteX11AcceptThread(c, remoteOriginatorAddress, remoteOriginatorPort);
			rxat.setDaemon(true);
			rxat.start();

			return;
		}

		if ("forwarded-tcpip".equals(channelType))
		{
			String remoteConnectedAddress = tr.readString(); /* address that was connected */
			int remoteConnectedPort = tr.readUINT32(); /* port that was connected */
			String remoteOriginatorAddress = tr.readString(); /* originator IP address */
			int remoteOriginatorPort = tr.readUINT32(); /* originator port */

			RemoteForwardingData rfd = null;

			synchronized (remoteForwardings)
			{
				rfd = (RemoteForwardingData) remoteForwardings.get(new Integer(remoteConnectedPort));
			}

			if (rfd == null)
			{
				PacketChannelOpenFailure pcof = new PacketChannelOpenFailure(remoteID,
						Packets.SSH_OPEN_ADMINISTRATIVELY_PROHIBITED,
						"No thanks, unknown port in forwarded-tcpip request", "");

				/* Always try to be polite. */

				tm.sendAsynchronousMessage(pcof.getPayload());

				if (log.isEnabled())
					log.log(20, "Unexpected forwarded-tcpip request, denying it!");

				return;
			}

			Channel c = new Channel(this);

			synchronized (c)
			{
				c.remoteID = remoteID;
				c.remoteWindow = remoteWindow & 0xFFFFffffL; /* convert UINT32 to long */
				c.remoteMaxPacketSize = remoteMaxPacketSize;
				c.localID = addChannel(c);
			}

			/*
			 * The open confirmation message will be sent from another thread.
			 */

			RemoteAcceptThread rat = new RemoteAcceptThread(c, remoteConnectedAddress, remoteConnectedPort,
					remoteOriginatorAddress, remoteOriginatorPort, rfd.targetAddress, rfd.targetPort);

			rat.setDaemon(true);
			rat.start();

			return;
		}

		/* Tell the server that we have no idea what it is talkin about */

		PacketChannelOpenFailure pcof = new PacketChannelOpenFailure(remoteID, Packets.SSH_OPEN_UNKNOWN_CHANNEL_TYPE,
				"Unknown channel type", "");

		tm.sendAsynchronousMessage(pcof.getPayload());

		if (log.isEnabled())
			log.log(20, "The peer tried to open an unsupported channel type (" + channelType + ")");
	}

	public void msgChannelRequest(byte[] msg, int msglen) throws IOException
	{
		TypesReader tr = new TypesReader(msg, 0, msglen);

		tr.readByte(); // skip packet type
		int id = tr.readUINT32();

		Channel c = getChannel(id);

		if (c == null)
			throw new IOException("Unexpected SSH_MSG_CHANNEL_REQUEST message for non-existent channel " + id);

		String type = tr.readString("US-ASCII");
		boolean wantReply = tr.readBoolean();

		if (log.isEnabled())
			log.log(80, "Got SSH_MSG_CHANNEL_REQUEST (channel " + id + ", '" + type + "')");

		if (type.equals("exit-status"))
		{
			if (wantReply != false)
				throw new IOException("Badly formatted SSH_MSG_CHANNEL_REQUEST message, 'want reply' is true");

			int exit_status = tr.readUINT32();

			if (tr.remain() != 0)
				throw new IOException("Badly formatted SSH_MSG_CHANNEL_REQUEST message");

			synchronized (c)
			{
				c.exit_status = new Integer(exit_status);
				c.notifyAll();
			}

			if (log.isEnabled())
				log.log(50, "Got EXIT STATUS (channel " + id + ", status " + exit_status + ")");

			return;
		}

		if (type.equals("exit-signal"))
		{
			if (wantReply != false)
				throw new IOException("Badly formatted SSH_MSG_CHANNEL_REQUEST message, 'want reply' is true");

			String signame = tr.readString("US-ASCII");
			tr.readBoolean();
			tr.readString();
			tr.readString();

			if (tr.remain() != 0)
				throw new IOException("Badly formatted SSH_MSG_CHANNEL_REQUEST message");

			synchronized (c)
			{
				c.exit_signal = signame;
				c.notifyAll();
			}

			if (log.isEnabled())
				log.log(50, "Got EXIT SIGNAL (channel " + id + ", signal " + signame + ")");

			return;
		}

		/* We simply ignore unknown channel requests, however, if the server wants a reply,
		 * then we signal that we have no idea what it is about.
		 */

		if (wantReply)
		{
			byte[] reply = new byte[5];

			reply[0] = Packets.SSH_MSG_CHANNEL_FAILURE;
			reply[1] = (byte) (c.remoteID >> 24);
			reply[2] = (byte) (c.remoteID >> 16);
			reply[3] = (byte) (c.remoteID >> 8);
			reply[4] = (byte) (c.remoteID);

			tm.sendAsynchronousMessage(reply);
		}

		if (log.isEnabled())
			log.log(50, "Channel request '" + type + "' is not known, ignoring it");
	}

	public void msgChannelEOF(byte[] msg, int msglen) throws IOException
	{
		if (msglen != 5)
			throw new IOException("SSH_MSG_CHANNEL_EOF message has wrong size (" + msglen + ")");

		int id = ((msg[1] & 0xff) << 24) | ((msg[2] & 0xff) << 16) | ((msg[3] & 0xff) << 8) | (msg[4] & 0xff);

		Channel c = getChannel(id);

		if (c == null)
			throw new IOException("Unexpected SSH_MSG_CHANNEL_EOF message for non-existent channel " + id);

		synchronized (c)
		{
			c.EOF = true;
			c.notifyAll();
		}

		if (log.isEnabled())
			log.log(50, "Got SSH_MSG_CHANNEL_EOF (channel " + id + ")");
	}

	public void msgChannelClose(byte[] msg, int msglen) throws IOException
	{
		if (msglen != 5)
			throw new IOException("SSH_MSG_CHANNEL_CLOSE message has wrong size (" + msglen + ")");

		int id = ((msg[1] & 0xff) << 24) | ((msg[2] & 0xff) << 16) | ((msg[3] & 0xff) << 8) | (msg[4] & 0xff);

		Channel c = getChannel(id);

		if (c == null)
			throw new IOException("Unexpected SSH_MSG_CHANNEL_CLOSE message for non-existent channel " + id);

		synchronized (c)
		{
			c.EOF = true;
			c.state = Channel.STATE_CLOSED;
			c.setReasonClosed("Close requested by remote");
			c.closeMessageRecv = true;

			removeChannel(c.localID);

			c.notifyAll();
		}

		if (log.isEnabled())
			log.log(50, "Got SSH_MSG_CHANNEL_CLOSE (channel " + id + ")");
	}

	public void msgChannelSuccess(byte[] msg, int msglen) throws IOException
	{
		if (msglen != 5)
			throw new IOException("SSH_MSG_CHANNEL_SUCCESS message has wrong size (" + msglen + ")");

		int id = ((msg[1] & 0xff) << 24) | ((msg[2] & 0xff) << 16) | ((msg[3] & 0xff) << 8) | (msg[4] & 0xff);

		Channel c = getChannel(id);

		if (c == null)
			throw new IOException("Unexpected SSH_MSG_CHANNEL_SUCCESS message for non-existent channel " + id);

		synchronized (c)
		{
			c.successCounter++;
			c.notifyAll();
		}

		if (log.isEnabled())
			log.log(80, "Got SSH_MSG_CHANNEL_SUCCESS (channel " + id + ")");
	}

	public void msgChannelFailure(byte[] msg, int msglen) throws IOException
	{
		if (msglen != 5)
			throw new IOException("SSH_MSG_CHANNEL_FAILURE message has wrong size (" + msglen + ")");

		int id = ((msg[1] & 0xff) << 24) | ((msg[2] & 0xff) << 16) | ((msg[3] & 0xff) << 8) | (msg[4] & 0xff);

		Channel c = getChannel(id);

		if (c == null)
			throw new IOException("Unexpected SSH_MSG_CHANNEL_FAILURE message for non-existent channel " + id);

		synchronized (c)
		{
			c.failedCounter++;
			c.notifyAll();
		}

		if (log.isEnabled())
			log.log(50, "Got SSH_MSG_CHANNEL_FAILURE (channel " + id + ")");
	}

	public void msgChannelOpenConfirmation(byte[] msg, int msglen) throws IOException
	{
		PacketChannelOpenConfirmation sm = new PacketChannelOpenConfirmation(msg, 0, msglen);

		Channel c = getChannel(sm.recipientChannelID);

		if (c == null)
			throw new IOException("Unexpected SSH_MSG_CHANNEL_OPEN_CONFIRMATION message for non-existent channel "
					+ sm.recipientChannelID);

		synchronized (c)
		{
			if (c.state != Channel.STATE_OPENING)
				throw new IOException("Unexpected SSH_MSG_CHANNEL_OPEN_CONFIRMATION message for channel "
						+ sm.recipientChannelID);

			c.remoteID = sm.senderChannelID;
			c.remoteWindow = sm.initialWindowSize & 0xFFFFffffL; /* convert UINT32 to long */
			c.remoteMaxPacketSize = sm.maxPacketSize;
			c.state = Channel.STATE_OPEN;
			c.notifyAll();
		}

		if (log.isEnabled())
			log.log(50, "Got SSH_MSG_CHANNEL_OPEN_CONFIRMATION (channel " + sm.recipientChannelID + " / remote: "
					+ sm.senderChannelID + ")");
	}

	public void msgChannelOpenFailure(byte[] msg, int msglen) throws IOException
	{
		if (msglen < 5)
			throw new IOException("SSH_MSG_CHANNEL_OPEN_FAILURE message has wrong size (" + msglen + ")");

		int id = ((msg[1] & 0xff) << 24) | ((msg[2] & 0xff) << 16) | ((msg[3] & 0xff) << 8) | (msg[4] & 0xff);

		Channel c = getChannel(id);

		if (c == null)
			throw new IOException("Unexpected SSH_MSG_CHANNEL_OPEN_FAILURE message for non-existent channel " + id);

		synchronized (c)
		{
			c.EOF = true;
			c.state = Channel.STATE_CLOSED;
			c.notifyAll();
		}

		if (log.isEnabled())
			log.log(50, "Got SSH_MSG_CHANNEL_OPEN_FAILURE (channel " + id + ")");
	}

	public void msgGlobalRequest(byte[] msg, int msglen) throws IOException
	{
		/* Currently we do not support any kind of global request */

		TypesReader tr = new TypesReader(msg, 0, msglen);

		tr.readByte(); // skip packet type
		String requestName = tr.readString();
		boolean wantReply = tr.readBoolean();

		if (wantReply)
		{
			byte[] reply_failure = new byte[1];
			reply_failure[0] = Packets.SSH_MSG_REQUEST_FAILURE;

			tm.sendAsynchronousMessage(reply_failure);
		}

		/* We do not clean up the requestName String - that is OK for debug */

		if (log.isEnabled())
			log.log(80, "Got SSH_MSG_GLOBAL_REQUEST (" + requestName + ")");
	}

	public void msgGlobalSuccess() throws IOException
	{
		synchronized (channels)
		{
			globalSuccessCounter++;
			channels.notifyAll();
		}

		if (log.isEnabled())
			log.log(80, "Got SSH_MSG_REQUEST_SUCCESS");
	}

	public void msgGlobalFailure() throws IOException
	{
		synchronized (channels)
		{
			globalFailedCounter++;
			channels.notifyAll();
		}

		if (log.isEnabled())
			log.log(80, "Got SSH_MSG_REQUEST_FAILURE");
	}

	public void handleMessage(byte[] msg, int msglen) throws IOException
	{
		if (msg == null)
		{
			if (log.isEnabled())
				log.log(50, "HandleMessage: got shutdown");

			synchronized (listenerThreads)
			{
				for (int i = 0; i < listenerThreads.size(); i++)
				{
					IChannelWorkerThread lat = (IChannelWorkerThread) listenerThreads.elementAt(i);
					lat.stopWorking();
				}
				listenerThreadsAllowed = false;
			}

			synchronized (channels)
			{
				shutdown = true;

				for (int i = 0; i < channels.size(); i++)
				{
					Channel c = (Channel) channels.elementAt(i);
					synchronized (c)
					{
						c.EOF = true;
						c.state = Channel.STATE_CLOSED;
						c.setReasonClosed("The connection is being shutdown");
						c.closeMessageRecv = true; /*
						 * You never know, perhaps
						 * we are waiting for a
						 * pending close message
						 * from the server...
						 */
						c.notifyAll();
					}
				}
				/* Works with J2ME */
				channels.setSize(0);
				channels.trimToSize();
				channels.notifyAll(); /* Notify global response waiters */
				return;
			}
		}

		switch (msg[0])
		{
		case Packets.SSH_MSG_CHANNEL_OPEN_CONFIRMATION:
			msgChannelOpenConfirmation(msg, msglen);
			break;
		case Packets.SSH_MSG_CHANNEL_WINDOW_ADJUST:
			msgChannelWindowAdjust(msg, msglen);
			break;
		case Packets.SSH_MSG_CHANNEL_DATA:
			msgChannelData(msg, msglen);
			break;
		case Packets.SSH_MSG_CHANNEL_EXTENDED_DATA:
			msgChannelExtendedData(msg, msglen);
			break;
		case Packets.SSH_MSG_CHANNEL_REQUEST:
			msgChannelRequest(msg, msglen);
			break;
		case Packets.SSH_MSG_CHANNEL_EOF:
			msgChannelEOF(msg, msglen);
			break;
		case Packets.SSH_MSG_CHANNEL_OPEN:
			msgChannelOpen(msg, msglen);
			break;
		case Packets.SSH_MSG_CHANNEL_CLOSE:
			msgChannelClose(msg, msglen);
			break;
		case Packets.SSH_MSG_CHANNEL_SUCCESS:
			msgChannelSuccess(msg, msglen);
			break;
		case Packets.SSH_MSG_CHANNEL_FAILURE:
			msgChannelFailure(msg, msglen);
			break;
		case Packets.SSH_MSG_CHANNEL_OPEN_FAILURE:
			msgChannelOpenFailure(msg, msglen);
			break;
		case Packets.SSH_MSG_GLOBAL_REQUEST:
			msgGlobalRequest(msg, msglen);
			break;
		case Packets.SSH_MSG_REQUEST_SUCCESS:
			msgGlobalSuccess();
			break;
		case Packets.SSH_MSG_REQUEST_FAILURE:
			msgGlobalFailure();
			break;
		default:
			throw new IOException("Cannot handle unknown channel message " + (msg[0] & 0xff));
		}
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -