diff --git a/router/java/src/net/i2p/router/transport/udp/EstablishmentManager.java b/router/java/src/net/i2p/router/transport/udp/EstablishmentManager.java index af500fd91..7dacfe6bf 100644 --- a/router/java/src/net/i2p/router/transport/udp/EstablishmentManager.java +++ b/router/java/src/net/i2p/router/transport/udp/EstablishmentManager.java @@ -561,10 +561,10 @@ class EstablishmentManager { } else { // we got an IB even though we were firewalled, hidden, not high cap, etc. } - if (_log.shouldLog(Log.INFO)) - _log.info("Received NEW session request " + state); + if (_log.shouldDebug()) + _log.debug("Received NEW session request " + state); } else { - if (_log.shouldLog(Log.DEBUG)) + if (_log.shouldDebug()) _log.debug("Receive DUP session request from: " + state); } @@ -639,11 +639,10 @@ class EstablishmentManager { } } - if (isNew) { - if (_log.shouldInfo()) - _log.info("Received NEW session/token request " + state); - } else { - if (_log.shouldDebug()) + if (_log.shouldDebug()) { + if (isNew) + _log.debug("Received NEW session/token request " + state); + else _log.debug("Receive DUP session/token request from: " + state); } // call for both Session and Token request, why not @@ -1275,8 +1274,8 @@ class EstablishmentManager { long nonce = reader.getRelayResponseReader().readNonce(); OutboundEstablishState state = _liveIntroductions.remove(Long.valueOf(nonce)); if (state == null) { - if (_log.shouldLog(Log.INFO)) - _log.info("Dup or unknown RelayResponse: " + nonce); + if (_log.shouldDebug()) + _log.debug("Dup or unknown RelayResponse: " + nonce); return; // already established } @@ -1301,8 +1300,8 @@ class EstablishmentManager { return; } _context.statManager().addRateData("udp.receiveIntroRelayResponse", state.getLifetime()); - if (_log.shouldLog(Log.INFO)) - _log.info("Received RelayResponse for " + state.getRemoteIdentity().calculateHash() + " - they are on " + if (_log.shouldDebug()) + _log.debug("Received RelayResponse for " + state.getRemoteIdentity().calculateHash() + " - they are on " + addr.toString() + ":" + port + " (according to " + bob + ") nonce=" + nonce); synchronized (state) { RemoteHostId oldId = state.getRemoteHostId(); @@ -1339,8 +1338,8 @@ class EstablishmentManager { if (state != null) { boolean sendNow = state.receiveHolePunch(); if (sendNow) { - if (_log.shouldLog(Log.INFO)) - _log.info("Hole punch from " + state + ", sending SessionRequest now"); + if (_log.shouldDebug()) + _log.debug("Hole punch from " + state + ", sending SessionRequest now"); notifyActivity(); } else { if (_log.shouldLog(Log.INFO)) @@ -1759,8 +1758,8 @@ class EstablishmentManager { // remove only if value == state _outboundStates.remove(outboundState.getRemoteHostId(), outboundState); if (outboundState.getState() != OB_STATE_CONFIRMED_COMPLETELY) { - if (_log.shouldLog(Log.INFO)) - _log.info("Expired: " + outboundState + " Lifetime: " + outboundState.getLifetime()); + if (_log.shouldDebug()) + _log.debug("Expired: " + outboundState + " Lifetime: " + outboundState.getLifetime()); OutNetMessage msg; while ((msg = outboundState.getNextQueuedMessage()) != null) { _transport.failed(msg, "Expired during failed establish"); diff --git a/router/java/src/net/i2p/router/transport/udp/InboundEstablishState2.java b/router/java/src/net/i2p/router/transport/udp/InboundEstablishState2.java index a45a43da1..de6f77c00 100644 --- a/router/java/src/net/i2p/router/transport/udp/InboundEstablishState2.java +++ b/router/java/src/net/i2p/router/transport/udp/InboundEstablishState2.java @@ -65,6 +65,12 @@ class InboundEstablishState2 extends InboundEstablishState implements SSU2Payloa /** + * Start a new handshake with the given incoming packet, + * which must be a Session Request or Token Request. + * + * Caller must then check getState() and build a + * Retry or Session Created in response. + * * @param packet with all header encryption removed, * either a SessionRequest OR a TokenRequest. */ @@ -136,7 +142,6 @@ class InboundEstablishState2 extends InboundEstablishState implements SSU2Payloa if (_log.shouldDebug()) _log.debug("State after mixHash 1: " + _handshakeState); - byte[] payload = new byte[len - 80]; // 32 hdr, 32 eph. key, 16 MAC // decrypt in-place try { _handshakeState.readMessage(data, off + LONG_HEADER_SIZE, len - LONG_HEADER_SIZE, data, off + LONG_HEADER_SIZE); diff --git a/router/java/src/net/i2p/router/transport/udp/OutboundEstablishState2.java b/router/java/src/net/i2p/router/transport/udp/OutboundEstablishState2.java index 6edd9176a..16196027c 100644 --- a/router/java/src/net/i2p/router/transport/udp/OutboundEstablishState2.java +++ b/router/java/src/net/i2p/router/transport/udp/OutboundEstablishState2.java @@ -61,6 +61,11 @@ class OutboundEstablishState2 extends OutboundEstablishState implements SSU2Payl private static final long MAX_SKEW = 2*60*1000L; /** + * Prepare to start a new handshake with the given peer. + * + * Caller must then check getState() and build a + * Token Request or Session Request to send to the peer. + * * @param claimedAddress an IP/port based RemoteHostId, or null if unknown * @param remoteHostId non-null, == claimedAddress if direct, or a hash-based one if indirect * @param remotePeer must have supported sig type diff --git a/router/java/src/net/i2p/router/transport/udp/PacketHandler.java b/router/java/src/net/i2p/router/transport/udp/PacketHandler.java index 1aab6dc66..38f6c90e2 100644 --- a/router/java/src/net/i2p/router/transport/udp/PacketHandler.java +++ b/router/java/src/net/i2p/router/transport/udp/PacketHandler.java @@ -359,7 +359,8 @@ class PacketHandler { // For now, try SSU2 Session/Token Request processing here. // After we've migrated the majority of the network over to SSU2, // we can try SSU2 first. - if (_enableSSU2 && peerType == PeerType.NEW_PEER) { + if (_enableSSU2 && peerType == PeerType.NEW_PEER && + packet.getPacket().getLength() >= SSU2Util.MIN_TOKEN_REQUEST_LEN) { boolean handled = receiveSSU2Packet(remoteHost, packet, (InboundEstablishState2) null); if (handled) return; @@ -773,6 +774,8 @@ class PacketHandler { * Packet is decrypted in-place, no fallback * processing is possible. * + * Min packet data size: 40 + * * @param packet any in-session message * @param state must be version 2, non-null * @since 0.9.54 @@ -792,7 +795,9 @@ class PacketHandler { * Possible messages here are Session Request, Token Request, Session Confirmed, or Peer Test. * Data messages out-of-order from Session Confirmed, or following a * Session Confirmed that was lost, or in-order but before the Session Confirmed was processed, - * will not be successfully decrypted and will be dropped. + * will handed to the state to be queued for deferred handling. + * + * Min packet data size: 56 (token request) if state is null; 40 (data) if state is non-null * * @param state must be version 2, but will be null for session request unless retransmitted * @return true if the header was validated as a SSU2 packet, cannot fallback to SSU 1 @@ -925,6 +930,8 @@ class PacketHandler { * * Possible messages here are Session Created or Retry * + * Min packet data size: 56 (retry) + * * @param state must be version 2, non-null * @return true if the header was validated as a SSU2 packet, cannot fallback to SSU 1 * @since 0.9.54 diff --git a/router/java/src/net/i2p/router/transport/udp/PeerState2.java b/router/java/src/net/i2p/router/transport/udp/PeerState2.java index d416810e4..53e03fff8 100644 --- a/router/java/src/net/i2p/router/transport/udp/PeerState2.java +++ b/router/java/src/net/i2p/router/transport/udp/PeerState2.java @@ -630,7 +630,7 @@ public class PeerState2 extends PeerState implements SSU2Payload.PayloadCallback /** * @return null if not sent or already got the ack */ - public synchronized UDPPacket[] getRetransmitSessionConfirmedPackets() { + private synchronized UDPPacket[] getRetransmitSessionConfirmedPackets() { if (_sessConfForReTX == null) return null; UDPPacket packet = UDPPacket.acquire(_context, false); diff --git a/router/java/src/net/i2p/router/transport/udp/SSU2Util.java b/router/java/src/net/i2p/router/transport/udp/SSU2Util.java index 51c6e78ea..a5b565785 100644 --- a/router/java/src/net/i2p/router/transport/udp/SSU2Util.java +++ b/router/java/src/net/i2p/router/transport/udp/SSU2Util.java @@ -58,13 +58,29 @@ final class SSU2Util { public static final int PADDING_MAX = 32; + // data size minimums, not including IP/UDP headers + /** 40 */ public static final int MIN_DATA_LEN = SHORT_HEADER_SIZE + TOTAL_PROT_SAMPLE_LEN; /** 56 */ public static final int MIN_LONG_DATA_LEN = LONG_HEADER_SIZE + TOTAL_PROT_SAMPLE_LEN; /** 88 */ public static final int MIN_HANDSHAKE_DATA_LEN = SESSION_HEADER_SIZE + TOTAL_PROT_SAMPLE_LEN; - + /** 56 */ + public static final int MIN_TOKEN_REQUEST_LEN = MIN_LONG_DATA_LEN; + /** 56 */ + public static final int MIN_RETRY_LEN = MIN_LONG_DATA_LEN; + /** 88 */ + public static final int MIN_SESSION_REQUEST_LEN = MIN_HANDSHAKE_DATA_LEN; + /** 88 */ + public static final int MIN_SESSION_CREATED_LEN = MIN_HANDSHAKE_DATA_LEN; + /** + * 380 + * Any RI, even compressed, will be at least 400 bytes. + * It has a minimum 387 byte ident and 40 byte sig, neither is compressible. + * Use 300 just to be safe for compression. + */ + public static final int MIN_SESSION_CONFIRMED_LEN = SHORT_HEADER_SIZE + KEY_LEN + MAC_LEN + 300 + MAC_LEN; /** 3 byte block header */ public static final int FIRST_FRAGMENT_HEADER_SIZE = SSU2Payload.BLOCK_HEADER_SIZE;