Package org.vngx.jsch

Source Code of org.vngx.jsch.ChannelDirectTCPIP

/*
* Copyright (c) 2002-2010 Atsuhiko Yamanaka, JCraft,Inc.  All rights reserved.
* Copyright (c) 2010-2011 Michael Laudati, N1 Concepts LLC.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The names of the authors may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
* INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

package org.vngx.jsch;

import static org.vngx.jsch.constants.ConnectionProtocol.*;

import org.vngx.jsch.constants.SSHConstants;
import org.vngx.jsch.exception.JSchException;
import org.vngx.jsch.util.Logger.Level;

/**
* Implementation of <code>Channel</code> for client-to-server forwarded
* connections over TCP/IP.
*
* @author Atsuhiko Yamanaka
* @author Michael Laudati
*/
public class ChannelDirectTCPIP extends Channel {

  /** Local maximum window size. */
  private static final int LOCAL_WINDOW_SIZE_MAX = 0x20000;
  /** Local maximum packet size. */
  private static final int LOCAL_MAXIMUM_PACKET_SIZE = 0x4000;

  /** Host for direct TCP/IP channel. */
  private String _host;
  /** Port for direct TCP/IP channel. */
  private int _port;
  /** Originator IP address for direct TCP/IP channel. */
  private String _originatorIPAddress = SSHConstants.LOCALHOST;
  /** Originator port for direct TCP/IP channel. */
  private int _originatorPort = 0;

 
  /**
   * Creates a new instance of <code>ChannelDirectTCPIP</code>.
   *
   * @param session
   */
  ChannelDirectTCPIP(Session session) {
    super(session, ChannelType.DIRECT_TCP_IP);
    setLocalWindowSizeMax(LOCAL_WINDOW_SIZE_MAX);
    setLocalWindowSize(LOCAL_WINDOW_SIZE_MAX);
    setLocalPacketSize(LOCAL_MAXIMUM_PACKET_SIZE);
    _io = new IO();
  }

  /*
   * Override of connected to connect as direct TCP/IP (must pass different
   * parameters when creating channel).
   */
  @Override
  public void connect() throws JSchException {
    try {
      if( !_session.isConnected() ) {
        throw new JSchException("Failed to open channel: session is not connected");
      }
      Buffer buffer = new Buffer(150);
      Packet packet = new Packet(buffer);
      // send
      // byte   SSH_MSG_CHANNEL_OPEN(90)
      // string channel type         //
      // uint32 sender channel       // 0
      // uint32 initial window size  // 0x100000(65536)
      // uint32 maxmum packet size   // 0x4000(16384)
      packet.reset();
      buffer.putByte(SSH_MSG_CHANNEL_OPEN);
      buffer.putString(_type);
      buffer.putInt(_id);
      buffer.putInt(_localWindowSize);
      buffer.putInt(_localMaxPacketSize);
      buffer.putString(_host);
      buffer.putInt(_port);
      buffer.putString(_originatorIPAddress);
      buffer.putInt(_originatorPort);
      _session.write(packet);

      int retry = 1000;
      while( _recipient == -1 && _session.isConnected() && retry-- > 0 && !_eofRemote ) {
        try { Thread.sleep(50); } catch(InterruptedException e) { /* Ignore error. */ }
      }
      if( !_session.isConnected() ) {
        throw new JSchException("Failed to open channel: session is not connected");
      } else if( retry == 0 || _eofRemote ) {
        throw new JSchException("Failed to open channel: no response");
      }
      _connected = true;

      if( _io.in != null ) {
        _thread = new Thread(this, "DirectTCPIP thread " + _session.getHost());
        _thread.setDaemon(_session.isDaemonThread());
        _thread.start();
      }
    } catch(JSchException e) {
      _connected = false;
      disconnect();
      throw e;
    } catch(Exception e) {
      _connected = false;
      disconnect();
      throw new JSchException("Failed to open channel "+getClass().getSimpleName()+": "+_exitstatus, e);
    }
  }

  /*
   * Override of Channel.connect(timeout) to forward to connect() method.
   * Without this override, if a call to connect(timeout) is made on an
   * instance of ChannelDirectTCPIP, it will call the base Channel
   * implementation and not work correctly as a direct TCPIP channel.
   */
  @Override
  public void connect(int timeout) throws JSchException {
    connect();
  }

  /*
   * Implementation of <code>Runnable</code> to run this as a thread to
   * continue reading from the input stream and writing out to the channel.
   */
  @Override
  public void run() {
    Buffer buffer = new Buffer(_remoteMaxPacketSize);
    Packet packet = new Packet(buffer);
    int i = 0;
    try {
      while( isConnected() && _thread != null && _io != null && _io.in != null ) {
        if( (i = _io.in.read(buffer.buffer, 14, buffer.buffer.length - 14 - (32 - 20 /* padding and mac */))) <= 0 ) {
          eof();
          break;
        } else if( _closed ) {
          break;
        }
        packet.reset();
        buffer.putByte(SSH_MSG_CHANNEL_DATA);
        buffer.putInt(_recipient);
        buffer.putInt(i);
        buffer.skip(i);
        _session.write(packet, this, i);
      }
    } catch(Exception e) {
      /* Ignore error, don't bubble exception. */
      JSch.getLogger().log(Level.DEBUG, "Failed to run ChannelDirectTCPIP", e);
    }
    disconnect()// Disconnect after finished reading from stream
  }

  /**
   * Sets the host for the direct TCP/IP channel.
   *
   * @param host
   */
  public void setHost(String host) {
    _host = host;
  }

  /**
   * Sets the port for the direct TCP/IP channel.
   *
   * @param port
   */
  public void setPort(int port) {
    _port = port;
  }

  /**
   * Sets the originator IP address for the direct TCP/IP channel.
   *
   * @param originatorIPAddress
   */
  public void setOriginatorIPAddress(String originatorIPAddress) {
    _originatorIPAddress = originatorIPAddress;
  }

  /**
   * Sets the originator port for the direct TCP/IP channel.
   *
   * @param originatorPort
   */
  public void setOriginatorPort(int originatorPort) {
    _originatorPort = originatorPort;
  }
 
}
TOP

Related Classes of org.vngx.jsch.ChannelDirectTCPIP

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.