SSU2: Minor cleanups

Add min packet size constants and notes
Don't attempt to decrypt a packet as a new inbound session if too small
Remove unused payload[] in IES2, now decrypted in-place
Log level tweaks in Establisher
This commit is contained in:
zzz
2022-03-16 07:28:22 -04:00
parent de27cb1a46
commit 8961009292
6 changed files with 53 additions and 21 deletions

View File

@@ -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");

View File

@@ -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);

View File

@@ -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

View File

@@ -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

View File

@@ -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);

View File

@@ -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;