SSU2: Pass source ip/port to path challenge/response callbacks

(more prep for connection migration)
This commit is contained in:
zzz
2022-08-02 09:38:11 -04:00
parent 146bbf67f8
commit 689016f48e
8 changed files with 45 additions and 34 deletions

View File

@@ -1,3 +1,21 @@
2022-08-02 zzz
* SSU2: More Path challenge WIP
2022-07-31 zzz
* SSU2: Add state lookup by conn ID
2022-07-29 zzz
* LogManager: Prevent hangs at shutdown on Mac after dock right-click-quit (Gitlab #363)
2022-07-27 zzz
* NetDB: Publish ff stats based on current caps, not previous
* Router: Log warning if no family keys loaded
* SSU: Decrease MTU only on retransmit of large packets
* SSU2: Stub out path challenge
2022-07-26 zzz
* SSU2: Send termination in response to termination
2022-07-25 zzz
* SSU2: Fix bitfield shifts of 256 or more

View File

@@ -18,7 +18,7 @@ public class RouterVersion {
/** deprecated */
public final static String ID = "Git";
public final static String VERSION = CoreVersion.VERSION;
public final static long BUILD = 13;
public final static long BUILD = 14;
/** for example "-test" */
public final static String EXTRA = "";

View File

@@ -1821,7 +1821,7 @@ class EstablishmentManager {
chacha.decryptWithAd(data, off, LONG_HEADER_SIZE,
data, off + LONG_HEADER_SIZE, data, off + LONG_HEADER_SIZE, len - LONG_HEADER_SIZE);
int payloadLen = len - (LONG_HEADER_SIZE + MAC_LEN);
SSU2Payload.processPayload(_context, cb, data, off + LONG_HEADER_SIZE, payloadLen, false);
SSU2Payload.processPayload(_context, cb, data, off + LONG_HEADER_SIZE, payloadLen, false, null);
if (cb._respCode != 0) {
if (_log.shouldWarn())
_log.warn("Bad HolePunch response: " + cb._respCode);
@@ -2826,11 +2826,11 @@ class EstablishmentManager {
throw new IllegalStateException("Bad block in HP");
}
public void gotPathChallenge(byte[] data) {
public void gotPathChallenge(RemoteHostId from, byte[] data) {
throw new IllegalStateException("Bad block in HP");
}
public void gotPathResponse(byte[] data) {
public void gotPathResponse(RemoteHostId from, byte[] data) {
throw new IllegalStateException("Bad block in HP");
}
}

View File

@@ -181,7 +181,7 @@ class InboundEstablishState2 extends InboundEstablishState implements SSU2Payloa
private void processPayload(byte[] payload, int offset, int length, boolean isHandshake) throws GeneralSecurityException {
try {
int blocks = SSU2Payload.processPayload(_context, this, payload, offset, length, isHandshake);
int blocks = SSU2Payload.processPayload(_context, this, payload, offset, length, isHandshake, null);
if (_log.shouldDebug())
_log.debug("Processed " + blocks + " blocks on " + this);
} catch (Exception e) {
@@ -420,11 +420,11 @@ class InboundEstablishState2 extends InboundEstablishState implements SSU2Payloa
_transport.getEstablisher().receiveSessionDestroy(_remoteHostId);
}
public void gotPathChallenge(byte[] data) {
public void gotPathChallenge(RemoteHostId from, byte[] data) {
throw new IllegalStateException("Bad block in handshake");
}
public void gotPathResponse(byte[] data) {
public void gotPathResponse(RemoteHostId from, byte[] data) {
throw new IllegalStateException("Bad block in handshake");
}

View File

@@ -258,7 +258,7 @@ class OutboundEstablishState2 extends OutboundEstablishState implements SSU2Payl
private void processPayload(byte[] payload, int offset, int length, boolean isHandshake) throws GeneralSecurityException {
try {
int blocks = SSU2Payload.processPayload(_context, this, payload, offset, length, isHandshake);
int blocks = SSU2Payload.processPayload(_context, this, payload, offset, length, isHandshake, null);
if (_log.shouldDebug())
_log.debug("Processed " + blocks + " blocks on " + this);
} catch (Exception e) {
@@ -348,11 +348,11 @@ class OutboundEstablishState2 extends OutboundEstablishState implements SSU2Payl
_transport.getEstablisher().receiveSessionDestroy(_remoteHostId, this);
}
public void gotPathChallenge(byte[] data) {
public void gotPathChallenge(RemoteHostId from, byte[] data) {
// won't be called, SSU2Payload will throw
}
public void gotPathResponse(byte[] data) {
public void gotPathResponse(RemoteHostId from, byte[] data) {
// won't be called, SSU2Payload will throw
}

View File

@@ -389,22 +389,11 @@ public class PeerState2 extends PeerState implements SSU2Payload.PayloadCallback
int payloadLen = len - (SHORT_HEADER_SIZE + MAC_LEN);
if (_log.shouldDebug())
_log.debug("New " + len + " byte pkt " + n + " rcvd on " + this);
processPayload(data, off + SHORT_HEADER_SIZE, payloadLen);
SSU2Payload.processPayload(_context, this, data, off + SHORT_HEADER_SIZE, payloadLen, false, from);
packetReceived(payloadLen);
} catch (GeneralSecurityException gse) {
if (_log.shouldWarn())
_log.warn("Bad encrypted packet on: " + this + '\n' + HexDump.dump(data, off, len), gse);
} catch (IndexOutOfBoundsException ioobe) {
if (_log.shouldWarn())
_log.warn("Bad encrypted packet on: " + this + '\n' + HexDump.dump(data, off, len), ioobe);
}
}
private void processPayload(byte[] payload, int offset, int length) throws GeneralSecurityException {
try {
int blocks = SSU2Payload.processPayload(_context, this, payload, offset, length, false);
} catch (Exception e) {
throw new GeneralSecurityException("Data payload error", e);
if (_log.shouldWarn())
_log.warn("Bad encrypted packet on: " + this + '\n' + HexDump.dump(data, off, len), e);
}
}
@@ -656,17 +645,18 @@ public class PeerState2 extends PeerState implements SSU2Payload.PayloadCallback
_transport.getEstablisher().receiveSessionDestroy(_remoteHostId, this);
}
public void gotPathChallenge(byte[] data) {
public void gotPathChallenge(RemoteHostId from, byte[] data) {
if (_log.shouldInfo())
_log.info("Got PATH CHALLENGE block, length: " + data.length + " on " + this);
SSU2Payload.Block block = new SSU2Payload.PathResponseBlock(data);
UDPPacket pkt = _transport.getBuilder2().buildPacket(Collections.emptyList(),
Collections.singletonList(block),
this);
// TODO send to from address?
_transport.send(pkt);
}
public void gotPathResponse(byte[] data) {
public void gotPathResponse(RemoteHostId from, byte[] data) {
if (_log.shouldInfo())
_log.info("Got PATH RESPONSE block, length: " + data.length + " on " + this);
// TODO

View File

@@ -810,7 +810,7 @@ class PeerTestManager {
data, off + LONG_HEADER_SIZE, data, off + LONG_HEADER_SIZE, len - LONG_HEADER_SIZE);
int payloadLen = len - (LONG_HEADER_SIZE + MAC_LEN);
SSU2Payload.PayloadCallback cb = new PTCallback(from);
SSU2Payload.processPayload(_context, cb, data, off + LONG_HEADER_SIZE, payloadLen, false);
SSU2Payload.processPayload(_context, cb, data, off + LONG_HEADER_SIZE, payloadLen, false, null);
} catch (Exception e) {
if (_log.shouldWarn())
_log.warn("Bad PeerTest packet:\n" + HexDump.dump(data, off, len), e);
@@ -1924,11 +1924,11 @@ class PeerTestManager {
throw new IllegalStateException("Bad block in PT");
}
public void gotPathChallenge(byte[] data) {
public void gotPathChallenge(RemoteHostId from, byte[] data) {
throw new IllegalStateException("Bad block in PT");
}
public void gotPathResponse(byte[] data) {
public void gotPathResponse(RemoteHostId from, byte[] data) {
throw new IllegalStateException("Bad block in PT");
}
}

View File

@@ -126,27 +126,30 @@ class SSU2Payload {
public void gotTermination(int reason, long lastReceived);
/**
* @param from null if unknown
* @since 0.9.55
*/
public void gotPathChallenge(byte[] data);
public void gotPathChallenge(RemoteHostId from, byte[] data);
/**
* @param from null if unknown
* @since 0.9.55
*/
public void gotPathResponse(byte[] data);
public void gotPathResponse(RemoteHostId from, byte[] data);
}
/**
* Incoming payload. Calls the callback for each received block.
*
* @param isHandshake true for Token Req, Retry, Sess Req, Sess Created; false for Sess Confirmed
* @param from for path challenge/response only, may be null
* @return number of blocks processed
* @throws IOException on major errors
* @throws DataFormatException on parsing of individual blocks
* @throws I2NPMessageException on parsing of I2NP block
*/
public static int processPayload(I2PAppContext ctx, PayloadCallback cb,
byte[] payload, int off, int length, boolean isHandshake)
byte[] payload, int off, int length, boolean isHandshake, RemoteHostId from)
throws IOException, DataFormatException, I2NPMessageException {
int blocks = 0;
boolean gotPadding = false;
@@ -367,7 +370,7 @@ class SSU2Payload {
throw new IOException("Illegal block in handshake: " + type);
byte[] cdata = new byte[len];
System.arraycopy(payload, i, cdata, 0, len);
cb.gotPathChallenge(cdata);
cb.gotPathChallenge(from, cdata);
break;
case BLOCK_PATHRESP:
@@ -375,7 +378,7 @@ class SSU2Payload {
throw new IOException("Illegal block in handshake: " + type);
byte[] rdata = new byte[len];
System.arraycopy(payload, i, rdata, 0, len);
cb.gotPathResponse(rdata);
cb.gotPathResponse(from, rdata);
break;
case BLOCK_PADDING: