Class TelnetProtocol

  • All Implemented Interfaces:
    java.lang.Runnable

    public class TelnetProtocol
    extends java.lang.Thread
    This class encapsulates a TELNET connection to a remote server. It processes incoming TELNET protocol data and generates outbound TELNET protocol data. It also manages two sets of TelnetOption objects: one for the local endpoint and one for the remote endpoint.

    IMPORTANT: Understanding this code requires understanding the TELNET protocol and TELNET option processing, as defined in the RFCs listed below.

    See Also:
    RFC 854, RFC 855, RFC 856, RFC 857, RFC 858, RFC 859, RFC 860, RFC 861, RFC 1091, RFC 1096, RFC 1073, RFC 1079, RFC 1143, RFC 1572
    • Nested Class Summary

      • Nested classes/interfaces inherited from class java.lang.Thread

        java.lang.Thread.State, java.lang.Thread.UncaughtExceptionHandler
    • Field Summary

      Fields 
      Modifier and Type Field Description
      protected static int BUFFER_SIZE
      Size of buffer for processing data received from remote endpoint.
      protected java.io.OutputStream clientOutputStream
      This field holds a reference to an OutputStream object used to send data to the client.
      protected int height
      This field holds the height of the Terminal screen in rows.
      protected boolean ignoreSubnegotiation
      This field is true if an error occurs while processing a subnegotiation command.
      protected java.nio.channels.ReadableByteChannel inputChannel
      This field holds a reference to an ReadableByteChannel object used to receive data from the remote endpoint.
      protected boolean localEcho
      UNDER CONSTRUCTION
      protected org.eclipse.remote.telnet.core.TelnetOption[] localOptions
      An array of TelnetOption objects representing the local endpoint's TELNET options.
      protected int nextSubnegotiationByteIndex
      This field holds the index into array receivedSubnegotiation of the next unused byte.
      protected byte[] processedBytes
      Holds incoming network data after the TELNET protocol bytes have been processed and removed.
      protected java.lang.StringBuffer processedStringBuffer
      This field holds a StringBuffer containing text recently received from the remote endpoint (after all TELNET protocol bytes have been processed and removed).
      protected java.nio.ByteBuffer rawBytes
      Holds raw bytes received from the remote endpoint, prior to any TELNET protocol processing.
      protected byte[] receivedSubnegotiation
      An array of bytes that holds the TELNET subnegotiation command most recently received from the remote endpoint.
      protected boolean remoteIsTelnetServer
      This field is true if the remote endpoint is a TELNET server, false if not.
      protected org.eclipse.remote.telnet.core.TelnetOption[] remoteOptions
      An array of TelnetOption objects representing the remote endpoint's TELNET options.
      protected java.io.OutputStream serverOutputStream
      This field holds a reference to an OutputStream object used to send data to the remote endpoint.
      protected TelnetCommandShell shell
      This field holds a reference to the TelnetCommandShell.
      protected java.net.Socket socket
      This method holds the Socket object for the TELNET connection.
      protected static int STATE_DO_RECEIVED
      TELNET connection state: Last byte processed was DO code.
      protected static int STATE_DONT_RECEIVED
      TELNET connection state: Last byte processed was DONT code.
      protected static int STATE_IAC_RECEIVED
      TELNET connection state: Last byte processed was IAC code.
      protected static int STATE_INITIAL
      TELNET connection state: Initial state.
      protected static int STATE_RECEIVING_SUBNEGOTIATION
      TELNET connection state: Currently receiving sub-negotiation data.
      protected static int STATE_SUBNEGOTIATION_STARTED
      TELNET connection state: Last byte processed was SB.
      protected static int STATE_WILL_RECEIVED
      TELNET connection state: Last byte processed was WILL code.
      protected static int STATE_WONT_RECEIVED
      TELNET connection state: Last byte processed was WONT code.
      static byte TELNET_AO
      Command code: Abort Output.
      static byte TELNET_AYT
      Command code: Are You There.
      static byte TELNET_BREAK
      Command code: Break.
      static byte TELNET_DM
      Command code: Data Mark.
      static byte TELNET_DO
      Command code: Do.
      static byte TELNET_DONT
      Command code: Don't.
      static byte TELNET_EC
      Command code: Erase Character.
      static byte TELNET_EL
      Command code: Erase Line.
      static byte TELNET_GA
      Command code: Go Ahead.
      static byte TELNET_IAC
      Command code: Interpret As Command.
      static byte TELNET_IP
      Command code: Interrupt Process.
      static byte TELNET_IS
      Command code: IS.
      static byte TELNET_NOP
      Command code: No-op.
      static byte TELNET_OPTION_ECHO
      Option code: Echo option.
      static byte TELNET_OPTION_NAWS
      Option code: Negotitate About Window Size (NAWS)
      static byte TELNET_OPTION_SUPPRESS_GA
      Option code: Suppress Go Ahead option.
      static byte TELNET_OPTION_TERMINAL_TYPE
      Option code: Terminal Type
      static byte TELNET_OPTION_TRANSMIT_BINARY
      Option code: Transmit Binary option.
      static byte TELNET_SB
      Command code: Subnegotiation Begin.
      static byte TELNET_SE
      Command code: Subnegotiation End.
      static byte TELNET_SEND
      Command code: SEND.
      static byte TELNET_WILL
      Command code: Will.
      static byte TELNET_WONT
      Command code: Won't.
      protected int telnetState
      Holds the current state of the TELNET protocol processor.
      protected int width
      This field holds the width of the Terminal screen in columns.
      • Fields inherited from class java.lang.Thread

        MAX_PRIORITY, MIN_PRIORITY, NORM_PRIORITY
    • Constructor Summary

      Constructors 
      Constructor Description
      TelnetProtocol​(java.net.Socket socket, TelnetCommandShell shell)
      This constructor just initializes some internal object state from its arguments.
    • Method Summary

      All Methods Instance Methods Concrete Methods 
      Modifier and Type Method Description
      java.io.OutputStream getOutputStream()  
      protected void initializeOptions()
      This method initializes the localOptions[] and remoteOptions[] arrays so that they contain references to TelnetOption objects representing our desired state for each option.
      boolean isConnected()
      Returns true if the TCP connection represented by this object is connected, false otherwise.
      boolean isRemoteTelnetServer()
      Returns true if the TCP connection represented by this object is connected and the remote endpoint is a TELNET server, false otherwise.
      boolean localEcho()
      Returns true if local echoing is enabled for this TCP connection, false otherwise.
      protected int processTelnetProtocol​(int count)
      Process TELNET protocol data contained in the first count bytes of rawBytes.
      void run()
      This method runs in its own thread.
      void setClientOutputStream​(java.io.OutputStream stream)  
      void setTerminalSize​(int newWidth, int newHeight)
      This method sets the terminal width and height to the supplied values.
      protected void telnetServerDetected()
      This method is called whenever we receive a valid TELNET protocol command from the remote endpoint.
      • Methods inherited from class java.lang.Thread

        activeCount, checkAccess, clone, countStackFrames, currentThread, dumpStack, enumerate, getAllStackTraces, getContextClassLoader, getDefaultUncaughtExceptionHandler, getId, getName, getPriority, getStackTrace, getState, getThreadGroup, getUncaughtExceptionHandler, holdsLock, interrupt, interrupted, isAlive, isDaemon, isInterrupted, join, join, join, onSpinWait, resume, setContextClassLoader, setDaemon, setDefaultUncaughtExceptionHandler, setName, setPriority, setUncaughtExceptionHandler, sleep, sleep, start, stop, suspend, toString, yield
      • Methods inherited from class java.lang.Object

        equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
    • Field Detail

      • STATE_INITIAL

        protected static final int STATE_INITIAL
        TELNET connection state: Initial state.
        See Also:
        Constant Field Values
      • STATE_IAC_RECEIVED

        protected static final int STATE_IAC_RECEIVED
        TELNET connection state: Last byte processed was IAC code. code.
        See Also:
        Constant Field Values
      • STATE_WILL_RECEIVED

        protected static final int STATE_WILL_RECEIVED
        TELNET connection state: Last byte processed was WILL code. code.
        See Also:
        Constant Field Values
      • STATE_WONT_RECEIVED

        protected static final int STATE_WONT_RECEIVED
        TELNET connection state: Last byte processed was WONT code.
        See Also:
        Constant Field Values
      • STATE_DO_RECEIVED

        protected static final int STATE_DO_RECEIVED
        TELNET connection state: Last byte processed was DO code.
        See Also:
        Constant Field Values
      • STATE_DONT_RECEIVED

        protected static final int STATE_DONT_RECEIVED
        TELNET connection state: Last byte processed was DONT code.
        See Also:
        Constant Field Values
      • STATE_SUBNEGOTIATION_STARTED

        protected static final int STATE_SUBNEGOTIATION_STARTED
        TELNET connection state: Last byte processed was SB.
        See Also:
        Constant Field Values
      • STATE_RECEIVING_SUBNEGOTIATION

        protected static final int STATE_RECEIVING_SUBNEGOTIATION
        TELNET connection state: Currently receiving sub-negotiation data.
        See Also:
        Constant Field Values
      • BUFFER_SIZE

        protected static final int BUFFER_SIZE
        Size of buffer for processing data received from remote endpoint.
        See Also:
        Constant Field Values
      • rawBytes

        protected java.nio.ByteBuffer rawBytes
        Holds raw bytes received from the remote endpoint, prior to any TELNET protocol processing.
      • processedBytes

        protected byte[] processedBytes
        Holds incoming network data after the TELNET protocol bytes have been processed and removed.
      • processedStringBuffer

        protected java.lang.StringBuffer processedStringBuffer
        This field holds a StringBuffer containing text recently received from the remote endpoint (after all TELNET protocol bytes have been processed and removed).
      • telnetState

        protected int telnetState
        Holds the current state of the TELNET protocol processor.
      • remoteIsTelnetServer

        protected boolean remoteIsTelnetServer
        This field is true if the remote endpoint is a TELNET server, false if not. We set this to true if and only if the remote endpoint sends recognizable TELNET protocol data. We do not assume that the remote endpoint is a TELNET server just because it is listening on port 23. This allows us to successfully connect to a TELNET server listening on a port other than 23.

        When this field first changes from false to true, we send all WILL or DO commands to the remote endpoint.

        See Also:
        telnetServerDetected()
      • localOptions

        protected org.eclipse.remote.telnet.core.TelnetOption[] localOptions
        An array of TelnetOption objects representing the local endpoint's TELNET options. The array is indexed by the numeric TELNET option code.
      • remoteOptions

        protected org.eclipse.remote.telnet.core.TelnetOption[] remoteOptions
        An array of TelnetOption objects representing the remote endpoint's TELNET options. The array is indexed by the numeric TELNET option code.
      • receivedSubnegotiation

        protected byte[] receivedSubnegotiation
        An array of bytes that holds the TELNET subnegotiation command most recently received from the remote endpoint. This array does _not_ include the leading IAC SB bytes, nor does it include the trailing IAC SE bytes. The first byte of this array is always a TELNET option code.
      • ignoreSubnegotiation

        protected boolean ignoreSubnegotiation
        This field is true if an error occurs while processing a subnegotiation command.
        See Also:
        processTelnetProtocol(int)
      • width

        protected int width
        This field holds the width of the Terminal screen in columns.
      • height

        protected int height
        This field holds the height of the Terminal screen in rows.
      • socket

        protected java.net.Socket socket
        This method holds the Socket object for the TELNET connection.
      • inputChannel

        protected java.nio.channels.ReadableByteChannel inputChannel
        This field holds a reference to an ReadableByteChannel object used to receive data from the remote endpoint.
      • serverOutputStream

        protected java.io.OutputStream serverOutputStream
        This field holds a reference to an OutputStream object used to send data to the remote endpoint.
      • clientOutputStream

        protected java.io.OutputStream clientOutputStream
        This field holds a reference to an OutputStream object used to send data to the client.
      • localEcho

        protected boolean localEcho
        UNDER CONSTRUCTION
      • TELNET_SE

        public static final byte TELNET_SE
        Command code: Subnegotiation End.
        See Also:
        Constant Field Values
      • TELNET_BREAK

        public static final byte TELNET_BREAK
        Command code: Break.
        See Also:
        Constant Field Values
      • TELNET_IP

        public static final byte TELNET_IP
        Command code: Interrupt Process.
        See Also:
        Constant Field Values
      • TELNET_AO

        public static final byte TELNET_AO
        Command code: Abort Output.
        See Also:
        Constant Field Values
      • TELNET_AYT

        public static final byte TELNET_AYT
        Command code: Are You There.
        See Also:
        Constant Field Values
      • TELNET_EC

        public static final byte TELNET_EC
        Command code: Erase Character.
        See Also:
        Constant Field Values
      • TELNET_EL

        public static final byte TELNET_EL
        Command code: Erase Line.
        See Also:
        Constant Field Values
      • TELNET_SB

        public static final byte TELNET_SB
        Command code: Subnegotiation Begin.
        See Also:
        Constant Field Values
      • TELNET_IAC

        public static final byte TELNET_IAC
        Command code: Interpret As Command.
        See Also:
        Constant Field Values
      • TELNET_OPTION_TRANSMIT_BINARY

        public static final byte TELNET_OPTION_TRANSMIT_BINARY
        Option code: Transmit Binary option.
        See Also:
        Constant Field Values
      • TELNET_OPTION_ECHO

        public static final byte TELNET_OPTION_ECHO
        Option code: Echo option.
        See Also:
        Constant Field Values
      • TELNET_OPTION_SUPPRESS_GA

        public static final byte TELNET_OPTION_SUPPRESS_GA
        Option code: Suppress Go Ahead option.
        See Also:
        Constant Field Values
      • TELNET_OPTION_TERMINAL_TYPE

        public static final byte TELNET_OPTION_TERMINAL_TYPE
        Option code: Terminal Type
        See Also:
        Constant Field Values
      • TELNET_OPTION_NAWS

        public static final byte TELNET_OPTION_NAWS
        Option code: Negotitate About Window Size (NAWS)
        See Also:
        Constant Field Values
    • Constructor Detail

      • TelnetProtocol

        public TelnetProtocol​(java.net.Socket socket,
                              TelnetCommandShell shell)
                       throws java.io.IOException
        This constructor just initializes some internal object state from its arguments.
        Throws:
        java.io.IOException
    • Method Detail

      • getOutputStream

        public java.io.OutputStream getOutputStream()
      • setClientOutputStream

        public void setClientOutputStream​(java.io.OutputStream stream)
      • isConnected

        public boolean isConnected()
        Returns true if the TCP connection represented by this object is connected, false otherwise.
      • isRemoteTelnetServer

        public boolean isRemoteTelnetServer()
        Returns true if the TCP connection represented by this object is connected and the remote endpoint is a TELNET server, false otherwise.
      • setTerminalSize

        public void setTerminalSize​(int newWidth,
                                    int newHeight)
        This method sets the terminal width and height to the supplied values. If either new value differs from the corresponding old value, we initiate a NAWS subnegotiation to inform the remote endpoint of the new terminal size.
      • localEcho

        public boolean localEcho()
        Returns true if local echoing is enabled for this TCP connection, false otherwise.
      • run

        public void run()
        This method runs in its own thread. It reads raw bytes from the TELNET connection socket, processes any TELNET protocol bytes (and removes them), and passes the remaining bytes to a TerminalDisplay object for display.
        Specified by:
        run in interface java.lang.Runnable
        Overrides:
        run in class java.lang.Thread
      • initializeOptions

        protected void initializeOptions()
        This method initializes the localOptions[] and remoteOptions[] arrays so that they contain references to TelnetOption objects representing our desired state for each option. The goal is to achieve server-side echoing, suppression of Go Aheads, and to send the local terminal type and size to the remote endpoint.
      • processTelnetProtocol

        protected int processTelnetProtocol​(int count)
        Process TELNET protocol data contained in the first count bytes of rawBytes. This function preserves its state between calls, because a multi-byte TELNET command might be split between two (or more) calls to this function. The state is preserved in field telnetState. This function implements an FSA that recognizes TELNET option codes. TELNET option sub-negotiation is delegated to instances of TelnetOption.
        Returns:
        The number of bytes remaining in the buffer after removing all TELNET protocol bytes.
      • telnetServerDetected

        protected void telnetServerDetected()
        This method is called whenever we receive a valid TELNET protocol command from the remote endpoint. When it is called for the first time for this connection, we negotiate all options that we desire to be enabled.

        This method does not negotiate options that we do not desire to be enabled, because all options are initially disabled.