## net.i2p.router.transport.ntcp
Class NTCPConnection

    java.lang.Object
      net.i2p.router.transport.ntcp.NTCPConnection

All Implemented Interfaces:
  FIFOBandwidthLimiter.CompleteListener

     class NTCPConnection

extends Object
implements FIFOBandwidthLimiter.CompleteListener

Coordinate the connection to a single peer. The NTCP transport sends individual I2NP messages AES/256/CBC encrypted with a simple checksum. The unencrypted message is encoded as follows:

      +-------+-------+--//--+---//----+-------+-------+-------+-------+
      | sizeof(data)  | data | padding | adler checksum of sz+data+pad |
      +-------+-------+--//--+---//----+-------+-------+-------+-------+

That message is then encrypted with the DH/2048 negotiated session key (station to station authenticated per the EstablishState class) using the last 16 bytes of the previous encrypted message as the IV. One special case is a metadata message where the sizeof(data) is 0. In that case, the unencrypted message is encoded as:

      +-------+-------+-------+-------+-------+-------+-------+-------+
      |       0       |      timestamp in seconds     | uninterpreted
      +-------+-------+-------+-------+-------+-------+-------+-------+
              uninterpreted           | adler checksum of sz+data+pad |
      +-------+-------+-------+-------+-------+-------+-------+-------+

Field Summary
`static int` `BUFFER_SIZE` Why this is 16K, and where it is documented, good question? We claim we can do 32K datagrams so this is a problem.
`static int` `MAX_MSG_SIZE` 2 bytes for length and 4 for CRC

Constructor Summary
`NTCPConnection(RouterContext ctx, NTCPTransport transport, RouterIdentity remotePeer, NTCPAddress remAddr)` Create an outbound unconnected NTCP connection
`NTCPConnection(RouterContext ctx, NTCPTransport transport, SocketChannel chan, SelectionKey key)` Create an inbound connected (though not established) NTCP connection

Method Summary
`void` `close()`
`void` `close(boolean allowRequeue)`
`void` `complete(FIFOBandwidthLimiter.Request req)`
`void` `enqueueInfoMessage()`
`void` `finishInboundEstablishment(SessionKey key, long clockSkew, byte[] prevWriteEnd, byte[] prevReadEnd)`
`void` `finishOutboundEstablishment(SessionKey key, long clockSkew, byte[] prevWriteEnd, byte[] prevReadEnd)`
`SocketChannel` `getChannel()`
`long` `getClockSkew()`
`int` `getConsecutiveBacklog()`
`EstablishState` `getEstablishState()`
`SelectionKey` `getKey()`
`long` `getMessagesReceived()`
`long` `getMessagesSent()`
`ByteBuffer` `getNextReadBuf()`
`ByteBuffer` `getNextWriteBuf()`
`long` `getOutboundQueueSize()`
`long` `getReadTime()`
`float` `getRecvRate()`
`NTCPAddress` `getRemoteAddress()`
`RouterIdentity` `getRemotePeer()`
`float` `getSendRate()`
`long` `getTimeSinceCreated()`
`long` `getTimeSinceReceive()`
`long` `getTimeSinceSend()`
`long` `getUptime()`
`int` `getWriteBufCount()`
`boolean` `isClosed()`
`boolean` `isEstablished()`
`boolean` `isInbound()`
`void` `outboundConnected()` async callback after the outbound connection was completed (this should NOT block, as it occurs in the selector thread)
`(package private) void` `prepareNextWrite()` prepare the next i2np message for transmission.
`(package private) void` `prepareNextWriteFast()` prepare the next i2np message for transmission.
`void` `queuedRecv(ByteBuffer buf, FIFOBandwidthLimiter.Request req)` We have read the data in the buffer, but we can't process it locally yet, because we're choked by the bandwidth limiter.
`void` `queuedWrite(ByteBuffer buf, FIFOBandwidthLimiter.Request req)` ditto for writes
`void` `recv(ByteBuffer buf)` The contents of the buffer have been read and can be processed asap.
`(package private) void` `recvEncryptedI2NP(ByteBuffer buf)` the contents of the buffer include some fraction of one or more encrypted and encoded I2NP messages.
`void` `removeReadBuf(ByteBuffer buf)` since getNextReadBuf() removes, this should not be necessary
`void` `removeWriteBuf(ByteBuffer buf)`
`void` `send(OutNetMessage msg)` toss the message onto the connection's send queue
`void` `setChannel(SocketChannel chan)`
`void` `setKey(SelectionKey key)`
`void` `setRemotePeer(RouterIdentity ident)`
`boolean` `tooBacklogged()`
`String` `toString()`
`void` `write(ByteBuffer buf)` The contents of the buffer have been encrypted / padded / etc and have been fully allocated for the bandwidth limiter.

Methods inherited from class java.lang.Object
`clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait`

Field Detail

### BUFFER_SIZE

    public static final int BUFFER_SIZE

  Why this is 16K, and where it is documented, good question? We claim we can do 32K datagrams so this is a problem. Needs to be fixed. But SSU can handle it? In the meantime, don't let the transport bid on big messages.

  See Also:
    Constant Field Values

### MAX_MSG_SIZE

    public static final int MAX_MSG_SIZE

  2 bytes for length and 4 for CRC

  See Also:
    Constant Field Values

Constructor Detail

### NTCPConnection

    public NTCPConnection(RouterContext ctx,
                          NTCPTransport transport,
                          SocketChannel chan,
                          SelectionKey key)

  Create an inbound connected (though not established) NTCP connection

### NTCPConnection

    public NTCPConnection(RouterContext ctx,
                          NTCPTransport transport,
                          RouterIdentity remotePeer,
                          NTCPAddress remAddr)

  Create an outbound unconnected NTCP connection

Method Detail

### getChannel

    public SocketChannel getChannel()

### getKey

    public SelectionKey getKey()

### setChannel

    public void setChannel(SocketChannel chan)

### setKey

    public void setKey(SelectionKey key)

### isInbound

    public boolean isInbound()

### isEstablished

    public boolean isEstablished()

### getEstablishState

    public EstablishState getEstablishState()

### getRemoteAddress

    public NTCPAddress getRemoteAddress()

### getRemotePeer

    public RouterIdentity getRemotePeer()

### setRemotePeer

    public void setRemotePeer(RouterIdentity ident)

### finishInboundEstablishment

    public void finishInboundEstablishment(SessionKey key,
                                           long clockSkew,
                                           byte[] prevWriteEnd,
                                           byte[] prevReadEnd)

  Parameters:
    `clockSkew` - alice's clock minus bob's clock in seconds (may be negative, obviously, but |val| should be under 1 minute)

### getClockSkew

    public long getClockSkew()

  Returns:
    seconds

### getUptime

    public long getUptime()

  Returns:
    milliseconds

### getMessagesSent

    public long getMessagesSent()

### getMessagesReceived

    public long getMessagesReceived()

### getOutboundQueueSize

    public long getOutboundQueueSize()

### getTimeSinceSend

    public long getTimeSinceSend()

  Returns:
    milliseconds

### getTimeSinceReceive

    public long getTimeSinceReceive()

  Returns:
    milliseconds

### getTimeSinceCreated

    public long getTimeSinceCreated()

  Returns:
    milliseconds

### getConsecutiveBacklog

    public int getConsecutiveBacklog()

### isClosed

    public boolean isClosed()

### close

    public void close()

### close

    public void close(boolean allowRequeue)

### send

    public void send(OutNetMessage msg)

  toss the message onto the connection's send queue

### tooBacklogged

    public boolean tooBacklogged()

### enqueueInfoMessage

    public void enqueueInfoMessage()

### finishOutboundEstablishment

    public void finishOutboundEstablishment(SessionKey key,
                                            long clockSkew,
                                            byte[] prevWriteEnd,
                                            byte[] prevReadEnd)

  Parameters:
    `clockSkew` - alice's clock minus bob's clock in seconds (may be negative, obviously, but |val| should be under 1 minute)

### prepareNextWrite

    void prepareNextWrite()

  prepare the next i2np message for transmission. this should be run from the Writer thread pool. Todo: remove synchronization?

### prepareNextWriteFast

    void prepareNextWriteFast()

  prepare the next i2np message for transmission. this should be run from the Writer thread pool. Todo: remove synchronization?

### outboundConnected

    public void outboundConnected()

  async callback after the outbound connection was completed (this should NOT block, as it occurs in the selector thread)

### complete

    public void complete(FIFOBandwidthLimiter.Request req)

  Specified by:
    `complete` in interface `FIFOBandwidthLimiter.CompleteListener`

### queuedRecv

    public void queuedRecv(ByteBuffer buf,
                           FIFOBandwidthLimiter.Request req)

  We have read the data in the buffer, but we can't process it locally yet, because we're choked by the bandwidth limiter. Cache the contents of the buffer (not copy) and register ourselves to be notified when the contents have been fully allocated

### queuedWrite

    public void queuedWrite(ByteBuffer buf,
                            FIFOBandwidthLimiter.Request req)

  ditto for writes

### recv

    public void recv(ByteBuffer buf)

  The contents of the buffer have been read and can be processed asap. This should not block, and the NTCP connection now owns the buffer to do with as it pleases.

### write

    public void write(ByteBuffer buf)

  The contents of the buffer have been encrypted / padded / etc and have been fully allocated for the bandwidth limiter.

### getNextReadBuf

    public ByteBuffer getNextReadBuf()

  Returns:
    null if none available

### removeReadBuf

    public void removeReadBuf(ByteBuffer buf)

  since getNextReadBuf() removes, this should not be necessary

### getWriteBufCount

    public int getWriteBufCount()

### getNextWriteBuf

    public ByteBuffer getNextWriteBuf()

  Returns:
    null if none available

### removeWriteBuf

    public void removeWriteBuf(ByteBuffer buf)

### getSendRate

    public float getSendRate()

### getRecvRate

    public float getRecvRate()

### recvEncryptedI2NP

    void recvEncryptedI2NP(ByteBuffer buf)

  the contents of the buffer include some fraction of one or more encrypted and encoded I2NP messages. individual i2np messages are encoded as "sizeof(data)+data+pad+crc", and those are encrypted with the session key and the last 16 bytes of the previous encrypted i2np message. the contents of the buffer is owned by the EventPumper, so data should be copied out

### getReadTime

    public long getReadTime()

### toString

    public String toString()

  Overrides:
    `toString` in class `Object`