|
|
|
@ -41,7 +41,7 @@ class PacketBuilder2 {
|
|
|
|
|
private final RouterContext _context;
|
|
|
|
|
private final Log _log;
|
|
|
|
|
private final UDPTransport _transport;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* For debugging and stats only - does not go out on the wire.
|
|
|
|
|
* These are chosen to be higher than the highest I2NP message type,
|
|
|
|
@ -81,7 +81,7 @@ class PacketBuilder2 {
|
|
|
|
|
*/
|
|
|
|
|
static final int PRIORITY_HIGH = 550;
|
|
|
|
|
private static final int PRIORITY_LOW = OutNetMessage.PRIORITY_LOWEST;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// every this many packets
|
|
|
|
|
private static final int DATETIME_SEND_FREQUENCY = 256;
|
|
|
|
|
|
|
|
|
@ -216,7 +216,7 @@ class PacketBuilder2 {
|
|
|
|
|
} else if (_log.shouldDebug()) {
|
|
|
|
|
_log.debug("No room for acks, MTU: " + currentMTU + " data: " + dataSize + " available: " + availableForAcks);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// now write each fragment
|
|
|
|
|
for (int i = 0; i < numFragments; i++) {
|
|
|
|
|
Fragment frag = fragments.get(i);
|
|
|
|
@ -279,7 +279,7 @@ class PacketBuilder2 {
|
|
|
|
|
setTo(packet, peer.getRemoteIPAddress(), peer.getRemotePort());
|
|
|
|
|
//if (_log.shouldDebug())
|
|
|
|
|
// _log.debug("Packet " + pktNum + " after encryption:\n" + HexDump.dump(data, 0, pkt.getLength()));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// FIXME ticket #2675
|
|
|
|
|
// the packet could have been built before the current mtu got lowered, so
|
|
|
|
|
// compare to LARGE_MTU
|
|
|
|
@ -295,7 +295,7 @@ class PacketBuilder2 {
|
|
|
|
|
" Fragments: " + DataHelper.toString(fragments) /* , new Exception() */ );
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
packet.setPriority(priority);
|
|
|
|
|
if (fragments.isEmpty()) {
|
|
|
|
|
peer.getAckedMessages().set(pktNum); // not ack-eliciting
|
|
|
|
@ -312,7 +312,7 @@ class PacketBuilder2 {
|
|
|
|
|
}
|
|
|
|
|
return packet;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* A DATA packet with padding only.
|
|
|
|
|
* We use this for keepalive purposes.
|
|
|
|
@ -343,7 +343,7 @@ class PacketBuilder2 {
|
|
|
|
|
*
|
|
|
|
|
*/
|
|
|
|
|
public UDPPacket buildACK(PeerState2 peer) {
|
|
|
|
|
return buildPacket(Collections.emptyList(), peer);
|
|
|
|
|
return buildPacket(Collections.<Fragment>emptyList(), peer);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
@ -363,15 +363,15 @@ class PacketBuilder2 {
|
|
|
|
|
}
|
|
|
|
|
Block block = new SSU2Payload.TerminationBlock(reason, peer.getReceivedMessages().getHighestSet());
|
|
|
|
|
blocks.add(block);
|
|
|
|
|
UDPPacket packet = buildPacket(Collections.emptyList(), blocks, peer);
|
|
|
|
|
UDPPacket packet = buildPacket(Collections.<Fragment>emptyList(), blocks, peer);
|
|
|
|
|
packet.setMessageType(TYPE_DESTROY);
|
|
|
|
|
return packet;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Build a new SessionRequest packet for the given peer, encrypting it
|
|
|
|
|
* Build a new SessionRequest packet for the given peer, encrypting it
|
|
|
|
|
* as necessary.
|
|
|
|
|
*
|
|
|
|
|
*
|
|
|
|
|
* @return ready to send packet, or null if there was a problem
|
|
|
|
|
*/
|
|
|
|
|
public UDPPacket buildTokenRequestPacket(OutboundEstablishState2 state) {
|
|
|
|
@ -388,11 +388,11 @@ class PacketBuilder2 {
|
|
|
|
|
state.tokenRequestSent(pkt);
|
|
|
|
|
return packet;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Build a new SessionRequest packet for the given peer, encrypting it
|
|
|
|
|
* Build a new SessionRequest packet for the given peer, encrypting it
|
|
|
|
|
* as necessary.
|
|
|
|
|
*
|
|
|
|
|
*
|
|
|
|
|
* @return ready to send packet, or null if there was a problem
|
|
|
|
|
*/
|
|
|
|
|
public UDPPacket buildSessionRequestPacket(OutboundEstablishState2 state) {
|
|
|
|
@ -409,11 +409,11 @@ class PacketBuilder2 {
|
|
|
|
|
state.requestSent(pkt);
|
|
|
|
|
return packet;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Build a new SessionCreated packet for the given peer, encrypting it
|
|
|
|
|
* Build a new SessionCreated packet for the given peer, encrypting it
|
|
|
|
|
* as necessary.
|
|
|
|
|
*
|
|
|
|
|
*
|
|
|
|
|
* @return ready to send packet, or null if there was a problem
|
|
|
|
|
*/
|
|
|
|
|
public UDPPacket buildSessionCreatedPacket(InboundEstablishState2 state) {
|
|
|
|
@ -421,7 +421,7 @@ class PacketBuilder2 {
|
|
|
|
|
UDPPacket packet = buildLongPacketHeader(state.getSendConnID(), n, SESSION_CREATED_FLAG_BYTE,
|
|
|
|
|
state.getRcvConnID(), 0);
|
|
|
|
|
DatagramPacket pkt = packet.getPacket();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
byte sentIP[] = state.getSentIP();
|
|
|
|
|
pkt.setLength(LONG_HEADER_SIZE);
|
|
|
|
|
int port = state.getSentPort();
|
|
|
|
@ -434,11 +434,11 @@ class PacketBuilder2 {
|
|
|
|
|
state.createdPacketSent(pkt);
|
|
|
|
|
return packet;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Build a new Retry packet for the given peer, encrypting it
|
|
|
|
|
* Build a new Retry packet for the given peer, encrypting it
|
|
|
|
|
* as necessary.
|
|
|
|
|
*
|
|
|
|
|
*
|
|
|
|
|
* @param terminationCode 0 normally, nonzero to send termination block
|
|
|
|
|
* @return ready to send packet, or null if there was a problem
|
|
|
|
|
*/
|
|
|
|
@ -448,7 +448,7 @@ class PacketBuilder2 {
|
|
|
|
|
UDPPacket packet = buildLongPacketHeader(state.getSendConnID(), n, RETRY_FLAG_BYTE,
|
|
|
|
|
state.getRcvConnID(), token);
|
|
|
|
|
DatagramPacket pkt = packet.getPacket();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
byte sentIP[] = state.getSentIP();
|
|
|
|
|
pkt.setLength(LONG_HEADER_SIZE);
|
|
|
|
|
int port = state.getSentPort();
|
|
|
|
@ -461,16 +461,16 @@ class PacketBuilder2 {
|
|
|
|
|
state.retryPacketSent();
|
|
|
|
|
return packet;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Build a new series of SessionConfirmed packets for the given peer,
|
|
|
|
|
* Build a new series of SessionConfirmed packets for the given peer,
|
|
|
|
|
* encrypting it as necessary.
|
|
|
|
|
*
|
|
|
|
|
* If the RI is large enough that it is fragmented, this will still only return
|
|
|
|
|
* a single Session Confirmed message. The remaining RI blocks will be passed to
|
|
|
|
|
* the establish state via confirmedPacketsSent(), and the state will
|
|
|
|
|
* transmit them via the new PeerState2.
|
|
|
|
|
*
|
|
|
|
|
*
|
|
|
|
|
* @return ready to send packets, or null if there was a problem
|
|
|
|
|
*/
|
|
|
|
|
public UDPPacket[] buildSessionConfirmedPackets(OutboundEstablishState2 state, RouterInfo ourInfo) {
|
|
|
|
@ -531,7 +531,7 @@ class PacketBuilder2 {
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Build a single new SessionConfirmed packet for the given peer, unfragmented.
|
|
|
|
|
*
|
|
|
|
|
*
|
|
|
|
|
* @return ready to send packet, or null if there was a problem
|
|
|
|
|
*/
|
|
|
|
|
private UDPPacket buildSessionConfirmedPacket(OutboundEstablishState2 state, SSU2Payload.RIBlock block) {
|
|
|
|
@ -549,7 +549,7 @@ class PacketBuilder2 {
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Build all the fragmented SessionConfirmed packets
|
|
|
|
|
*
|
|
|
|
|
*
|
|
|
|
|
*/
|
|
|
|
|
private UDPPacket[] buildSessionConfirmedPackets(OutboundEstablishState2 state, SSU2Payload.RIBlock block) {
|
|
|
|
|
UDPPacket packet0 = buildShortPacketHeader(state.getSendConnID(), 0, SESSION_CONFIRMED_FLAG_BYTE);
|
|
|
|
@ -647,12 +647,12 @@ class PacketBuilder2 {
|
|
|
|
|
/**
|
|
|
|
|
* Build a packet as Alice, to Bob to begin a peer test.
|
|
|
|
|
* In-session, message 1.
|
|
|
|
|
*
|
|
|
|
|
*
|
|
|
|
|
* @return ready to send packet, or null if there was a problem
|
|
|
|
|
*/
|
|
|
|
|
public UDPPacket buildPeerTestFromAlice(byte[] signedData, PeerState2 bob) {
|
|
|
|
|
Block block = new SSU2Payload.PeerTestBlock(1, 0, null, signedData);
|
|
|
|
|
UDPPacket rv = buildPacket(Collections.emptyList(), Collections.singletonList(block), bob);
|
|
|
|
|
UDPPacket rv = buildPacket(Collections.<Fragment>emptyList(), Collections.singletonList(block), bob);
|
|
|
|
|
rv.setMessageType(TYPE_TFA);
|
|
|
|
|
return rv;
|
|
|
|
|
}
|
|
|
|
@ -660,7 +660,7 @@ class PacketBuilder2 {
|
|
|
|
|
/**
|
|
|
|
|
* Build a packet as Alice to Charlie.
|
|
|
|
|
* Out-of-session, message 6.
|
|
|
|
|
*
|
|
|
|
|
*
|
|
|
|
|
* @return ready to send packet, or null if there was a problem
|
|
|
|
|
*/
|
|
|
|
|
public UDPPacket buildPeerTestFromAlice(InetAddress toIP, int toPort, SessionKey introKey,
|
|
|
|
@ -688,7 +688,7 @@ class PacketBuilder2 {
|
|
|
|
|
*/
|
|
|
|
|
public UDPPacket buildPeerTestToAlice(int code, Hash charlieHash, byte[] signedData, PeerState2 alice) {
|
|
|
|
|
Block block = new SSU2Payload.PeerTestBlock(4, code, charlieHash, signedData);
|
|
|
|
|
UDPPacket rv = buildPacket(Collections.emptyList(), Collections.singletonList(block), alice);
|
|
|
|
|
UDPPacket rv = buildPacket(Collections.<Fragment>emptyList(), Collections.singletonList(block), alice);
|
|
|
|
|
rv.setMessageType(TYPE_TTA);
|
|
|
|
|
return rv;
|
|
|
|
|
}
|
|
|
|
@ -696,7 +696,7 @@ class PacketBuilder2 {
|
|
|
|
|
/**
|
|
|
|
|
* Build a packet as Charlie to Alice.
|
|
|
|
|
* Out-of-session, messages 5 and 7.
|
|
|
|
|
*
|
|
|
|
|
*
|
|
|
|
|
* @return ready to send packet, or null if there was a problem
|
|
|
|
|
*/
|
|
|
|
|
public UDPPacket buildPeerTestToAlice(InetAddress aliceIP, int alicePort, SessionKey introKey,
|
|
|
|
@ -719,25 +719,25 @@ class PacketBuilder2 {
|
|
|
|
|
/**
|
|
|
|
|
* Build a packet as Bob to Charlie to help test Alice.
|
|
|
|
|
* In-session, message 2.
|
|
|
|
|
*
|
|
|
|
|
*
|
|
|
|
|
* @return ready to send packet, or null if there was a problem
|
|
|
|
|
*/
|
|
|
|
|
public UDPPacket buildPeerTestToCharlie(Hash aliceHash, byte[] signedData, PeerState2 charlie) {
|
|
|
|
|
Block block = new SSU2Payload.PeerTestBlock(2, 0, aliceHash, signedData);
|
|
|
|
|
UDPPacket rv = buildPacket(Collections.emptyList(), Collections.singletonList(block), charlie);
|
|
|
|
|
UDPPacket rv = buildPacket(Collections.<Fragment>emptyList(), Collections.singletonList(block), charlie);
|
|
|
|
|
rv.setMessageType(TYPE_TBC);
|
|
|
|
|
return rv;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Build a packet as Charlie to Bob verifying that we will help test Alice.
|
|
|
|
|
* In-session, message 3.
|
|
|
|
|
*
|
|
|
|
|
*
|
|
|
|
|
* @return ready to send packet, or null if there was a problem
|
|
|
|
|
*/
|
|
|
|
|
public UDPPacket buildPeerTestToBob(int code, byte[] signedData, PeerState2 bob) {
|
|
|
|
|
Block block = new SSU2Payload.PeerTestBlock(3, code, null, signedData);
|
|
|
|
|
UDPPacket rv = buildPacket(Collections.emptyList(), Collections.singletonList(block), bob);
|
|
|
|
|
UDPPacket rv = buildPacket(Collections.<Fragment>emptyList(), Collections.singletonList(block), bob);
|
|
|
|
|
rv.setMessageType(TYPE_TCB);
|
|
|
|
|
return rv;
|
|
|
|
|
}
|
|
|
|
@ -751,7 +751,7 @@ class PacketBuilder2 {
|
|
|
|
|
*/
|
|
|
|
|
UDPPacket buildRelayRequest(byte[] signedData, PeerState2 bob) {
|
|
|
|
|
Block block = new SSU2Payload.RelayRequestBlock(signedData);
|
|
|
|
|
UDPPacket rv = buildPacket(Collections.emptyList(), Collections.singletonList(block), bob);
|
|
|
|
|
UDPPacket rv = buildPacket(Collections.<Fragment>emptyList(), Collections.singletonList(block), bob);
|
|
|
|
|
rv.setMessageType(TYPE_RREQ);
|
|
|
|
|
rv.setPriority(PRIORITY_HIGH);
|
|
|
|
|
return rv;
|
|
|
|
@ -766,7 +766,7 @@ class PacketBuilder2 {
|
|
|
|
|
*/
|
|
|
|
|
UDPPacket buildRelayIntro(byte[] signedData, PeerState2 charlie) {
|
|
|
|
|
Block block = new SSU2Payload.RelayIntroBlock(signedData);
|
|
|
|
|
UDPPacket rv = buildPacket(Collections.emptyList(), Collections.singletonList(block), charlie);
|
|
|
|
|
UDPPacket rv = buildPacket(Collections.<Fragment>emptyList(), Collections.singletonList(block), charlie);
|
|
|
|
|
rv.setMessageType(TYPE_INTRO);
|
|
|
|
|
return rv;
|
|
|
|
|
}
|
|
|
|
@ -781,7 +781,7 @@ class PacketBuilder2 {
|
|
|
|
|
*/
|
|
|
|
|
UDPPacket buildRelayResponse(byte[] signedData, PeerState2 state) {
|
|
|
|
|
Block block = new SSU2Payload.RelayResponseBlock(signedData);
|
|
|
|
|
UDPPacket rv = buildPacket(Collections.emptyList(), Collections.singletonList(block), state);
|
|
|
|
|
UDPPacket rv = buildPacket(Collections.<Fragment>emptyList(), Collections.singletonList(block), state);
|
|
|
|
|
rv.setMessageType(TYPE_RESP);
|
|
|
|
|
return rv;
|
|
|
|
|
}
|
|
|
|
@ -807,7 +807,7 @@ class PacketBuilder2 {
|
|
|
|
|
packet.setPriority(PRIORITY_HIGH);
|
|
|
|
|
return packet;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @param pktNum 0 - 0xFFFFFFFF
|
|
|
|
|
* @return a packet with the first 32 bytes filled in
|
|
|
|
@ -823,7 +823,7 @@ class PacketBuilder2 {
|
|
|
|
|
DataHelper.toLong8(data, 24, token);
|
|
|
|
|
return packet;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @param pktNum 0 - 0xFFFFFFFF
|
|
|
|
|
* @return a packet with the first 16 bytes filled in
|
|
|
|
|