public class NTCPConnection extends Object implements Closeable
+-------+-------+--//--+---//----+-------+-------+-------+-------+ | 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 | +-------+-------+-------+-------+-------+-------+-------+-------+
Modifier and Type | Class and Description |
---|---|
(package private) static class |
NTCPConnection.PrepBuffer |
Modifier and Type | Field and Description |
---|---|
(package private) 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.
|
(package private) static int |
DELAY_DEFAULT |
(package private) static int |
DUMMY_DEFAULT |
(package private) static int |
NTCP1_MAX_MSG_SIZE
2 bytes for length and 4 for CRC
|
(package private) static int |
NTCP2_MAX_MSG_SIZE
See spec.
|
(package private) static int |
PADDING_MAX_DEFAULT_INT |
(package private) static int |
PADDING_MIN_DEFAULT_INT |
(package private) static int |
REASON_AEAD |
(package private) static int |
REASON_BANNED |
(package private) static int |
REASON_FRAME_TIMEOUT |
(package private) static int |
REASON_FRAMING |
(package private) static int |
REASON_MSG1 |
(package private) static int |
REASON_MSG2 |
(package private) static int |
REASON_MSG3 |
(package private) static int |
REASON_OPTIONS |
(package private) static int |
REASON_PADDING |
(package private) static int |
REASON_PAYLOAD |
(package private) static int |
REASON_S_MISMATCH |
(package private) static int |
REASON_SIGFAIL |
(package private) static int |
REASON_SIGTYPE |
(package private) static int |
REASON_SKEW |
(package private) static int |
REASON_TERMINATION |
(package private) static int |
REASON_TIMEOUT |
(package private) static int |
REASON_UNSPEC |
Constructor and Description |
---|
NTCPConnection(RouterContext ctx,
NTCPTransport transport,
RouterIdentity remotePeer,
RouterAddress remAddr,
int version)
Create an outbound unconnected NTCP connection.
|
NTCPConnection(RouterContext ctx,
NTCPTransport transport,
SocketChannel chan,
SelectionKey key)
Create an inbound connected (though not established) NTCP connection.
|
Modifier and Type | Method and Description |
---|---|
(package private) void |
clearZeroRead()
workaround for EventPumper
|
void |
close() |
void |
close(boolean allowRequeue) |
(package private) void |
closeOnTimeout(String cause,
Exception e)
Close and release EstablishState resources.
|
(package private) void |
enqueueInfoMessage()
Inject a DatabaseStoreMessage with our RouterInfo.
|
(package private) void |
failInboundEstablishment(CipherState sender,
byte[] sip_ba,
int reason)
We are Bob.
|
(package private) void |
finishInboundEstablishment(CipherState sender,
CipherState receiver,
byte[] sip_ba,
byte[] sip_ab,
long clockSkew,
NTCP2Options hisPadding)
We are Bob.
|
(package private) void |
finishInboundEstablishment(SessionKey key,
long clockSkew,
byte[] prevWriteEnd,
byte[] prevReadEnd)
We are Bob.
|
(package private) void |
finishOutboundEstablishment(CipherState sender,
CipherState receiver,
byte[] sip_ab,
byte[] sip_ba,
long clockSkew)
We are Alice.
|
(package private) void |
finishOutboundEstablishment(SessionKey key,
long clockSkew,
byte[] prevWriteEnd,
byte[] prevReadEnd)
We are Alice.
|
SocketChannel |
getChannel()
Valid for inbound; valid for outbound shortly after creation
|
long |
getClockSkew()
A positive number means our clock is ahead of theirs.
|
long |
getCreated() |
(package private) EstablishState |
getEstablishState()
Only valid during establishment;
replaced with EstablishState.VERIFIED or FAILED afterward
|
SelectionKey |
getKey()
Valid for inbound; valid for outbound shortly after creation
|
boolean |
getMayDisconnect() |
int |
getMessagesReceived() |
int |
getMessagesSent() |
(package private) ByteBuffer |
getNextReadBuf() |
(package private) ByteBuffer |
getNextWriteBuf() |
int |
getOutboundQueueSize() |
float |
getRecvRate() |
RouterAddress |
getRemoteAddress()
Only valid for outbound; null for inbound
|
RouterIdentity |
getRemotePeer()
Valid for outbound; valid for inbound after handshake
|
float |
getSendRate() |
long |
getTimeSinceCreated() |
long |
getTimeSinceCreated(long now) |
long |
getTimeSinceReceive() |
long |
getTimeSinceReceive(long now) |
long |
getTimeSinceSend() |
long |
getTimeSinceSend(long now) |
long |
getUptime() |
int |
getVersion()
The NTCP2 version, for the console.
|
(package private) int |
gotZeroRead()
workaround for EventPumper
|
boolean |
isBacklogged() |
boolean |
isClosed() |
boolean |
isEstablished() |
boolean |
isInbound() |
boolean |
isIPv6() |
(package private) boolean |
isWriteBufEmpty()
Replaces getWriteBufCount()
|
(package private) 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(NTCPConnection.PrepBuffer prep)
Prepare the next I2NP message for transmission.
|
(package private) 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.
|
(package private) void |
queuedWrite(ByteBuffer buf,
FIFOBandwidthLimiter.Request req)
ditto for writes
|
(package private) void |
recv(ByteBuffer buf)
The contents of the buffer have been read and can be processed asap.
|
(package private) void |
recvEncryptedI2NP(ByteBuffer buf)
Connection must be established!
The contents of the buffer include some fraction of one or more
encrypted and encoded I2NP messages.
|
(package private) static void |
releaseResources()
Call at transport shutdown
|
(package private) void |
removeWriteBuf(ByteBuffer buf)
Remove the buffer, which _should_ be the one at the head of _writeBufs
|
void |
send(OutNetMessage msg)
toss the message onto the connection's send queue
|
(package private) void |
sendTerminationAndClose()
NTCP 1 or 2.
|
void |
setChannel(SocketChannel chan) |
void |
setKey(SelectionKey key) |
void |
setMayDisconnect()
Sets to true.
|
void |
setRemotePeer(RouterIdentity ident)
Valid for outbound; valid for inbound after handshake
|
void |
setVersion(int ver)
Set version 2 from InboundEstablishState.
|
boolean |
tooBacklogged() |
String |
toString() |
(package private) void |
write(ByteBuffer buf)
The contents of the buffer have been encrypted / padded / etc and have
been fully allocated for the bandwidth limiter.
|
static final int BUFFER_SIZE
static final int NTCP1_MAX_MSG_SIZE
static final int NTCP2_MAX_MSG_SIZE
static final int REASON_UNSPEC
static final int REASON_TERMINATION
static final int REASON_TIMEOUT
static final int REASON_AEAD
static final int REASON_OPTIONS
static final int REASON_SIGTYPE
static final int REASON_SKEW
static final int REASON_PADDING
static final int REASON_FRAMING
static final int REASON_PAYLOAD
static final int REASON_MSG1
static final int REASON_MSG2
static final int REASON_MSG3
static final int REASON_FRAME_TIMEOUT
static final int REASON_SIGFAIL
static final int REASON_S_MISMATCH
static final int REASON_BANNED
static final int PADDING_MIN_DEFAULT_INT
static final int PADDING_MAX_DEFAULT_INT
static final int DUMMY_DEFAULT
static final int DELAY_DEFAULT
public NTCPConnection(RouterContext ctx, NTCPTransport transport, SocketChannel chan, SelectionKey key)
public NTCPConnection(RouterContext ctx, NTCPTransport transport, RouterIdentity remotePeer, RouterAddress remAddr, int version) throws DataFormatException
version
- must be 1 or 2DataFormatException
- if there's a problem with the addresspublic SocketChannel getChannel()
public SelectionKey getKey()
public void setChannel(SocketChannel chan)
public void setKey(SelectionKey key)
public boolean isInbound()
public boolean isEstablished()
public boolean isIPv6()
EstablishState getEstablishState()
public RouterAddress getRemoteAddress()
public RouterIdentity getRemotePeer()
public void setRemotePeer(RouterIdentity ident)
void finishInboundEstablishment(SessionKey key, long clockSkew, byte[] prevWriteEnd, byte[] prevReadEnd)
clockSkew
- OUR clock minus ALICE's clock in seconds (may be negative, obviously, but |val| should
be under 1 minute)prevWriteEnd
- exactly 16 bytes, not copied, do not corrupt, the write AES IVprevReadEnd
- 16 or more bytes, last 16 bytes copied as the read AES IVpublic long getClockSkew()
public long getUptime()
public int getMessagesSent()
public int getMessagesReceived()
public int getOutboundQueueSize()
public long getTimeSinceSend()
public long getTimeSinceSend(long now)
public long getTimeSinceReceive()
public long getTimeSinceReceive(long now)
public long getTimeSinceCreated()
public long getTimeSinceCreated(long now)
public long getCreated()
public int getVersion()
public void setVersion(int ver)
public void setMayDisconnect()
public boolean getMayDisconnect()
void clearZeroRead()
int gotZeroRead()
public boolean isClosed()
public void close()
close
in interface Closeable
close
in interface AutoCloseable
public void close(boolean allowRequeue)
void closeOnTimeout(String cause, Exception e)
e
- may be nullpublic void send(OutNetMessage msg)
public boolean isBacklogged()
public boolean tooBacklogged()
void enqueueInfoMessage()
void finishOutboundEstablishment(SessionKey key, long clockSkew, byte[] prevWriteEnd, byte[] prevReadEnd)
clockSkew
- OUR clock minus BOB's clock in seconds (may be negative, obviously, but |val| should
be under 1 minute)prevWriteEnd
- exactly 16 bytes, not copied, do not corruptprevReadEnd
- 16 or more bytes, last 16 bytes copiedvoid prepareNextWrite(NTCPConnection.PrepBuffer prep)
prep
- an instance of PrepBuffer to use as scratch spacevoid sendTerminationAndClose()
void outboundConnected()
void queuedRecv(ByteBuffer buf, FIFOBandwidthLimiter.Request req)
void queuedWrite(ByteBuffer buf, FIFOBandwidthLimiter.Request req)
void recv(ByteBuffer buf)
void write(ByteBuffer buf)
ByteBuffer getNextReadBuf()
boolean isWriteBufEmpty()
ByteBuffer getNextWriteBuf()
void removeWriteBuf(ByteBuffer buf)
public float getSendRate()
public float getRecvRate()
void recvEncryptedI2NP(ByteBuffer buf)
static void releaseResources()
void finishOutboundEstablishment(CipherState sender, CipherState receiver, byte[] sip_ab, byte[] sip_ba, long clockSkew)
clockSkew
- OUR clock minus BOB's clock in seconds (may be negative, obviously, but |val| should
be under 1 minute)sender
- use to send to Bobreceiver
- use to receive from Bobsip_ab
- 24 bytes to init SipHash to Bobsip_ba
- 24 bytes to init SipHash from Bobvoid finishInboundEstablishment(CipherState sender, CipherState receiver, byte[] sip_ba, byte[] sip_ab, long clockSkew, NTCP2Options hisPadding)
clockSkew
- OUR clock minus ALICE's clock in seconds (may be negative, obviously, but |val| should
be under 1 minute)sender
- use to send to Alicereceiver
- use to receive from Alicesip_ba
- 24 bytes to init SipHash to Alicesip_ab
- 24 bytes to init SipHash from AlicehisPadding
- may be nullvoid failInboundEstablishment(CipherState sender, byte[] sip_ba, int reason)
sender
- use to send to Alicesip_ba
- 24 bytes to init SipHash to Alice