forked from I2P_Developers/i2p.i2p
SSU2: Send retry with termination block on clock skew
This commit is contained in:
@@ -1246,7 +1246,7 @@ class EstablishmentManager {
|
||||
case IB_STATE_REQUEST_BAD_TOKEN_RECEIVED:
|
||||
if (_log.shouldDebug())
|
||||
_log.debug("Send retry to: " + state);
|
||||
pkt = _builder2.buildRetryPacket(state2);
|
||||
pkt = _builder2.buildRetryPacket(state2, 0);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
@@ -166,7 +166,9 @@ class InboundEstablishState2 extends InboundEstablishState implements SSU2Payloa
|
||||
throw new GeneralSecurityException("No DateTime block in Session/Token Request");
|
||||
_skew = _establishBegin - _timeReceived;
|
||||
if (_skew > MAX_SKEW || _skew < 0 - MAX_SKEW) {
|
||||
// TODO send retry with termination
|
||||
// send retry with termination
|
||||
UDPPacket retry = _transport.getBuilder2().buildRetryPacket(this, SSU2Util.REASON_SKEW);
|
||||
_transport.send(retry);
|
||||
throw new GeneralSecurityException("Skew exceeded in Session/Token Request: " + _skew);
|
||||
}
|
||||
packetReceived();
|
||||
@@ -519,8 +521,12 @@ class InboundEstablishState2 extends InboundEstablishState implements SSU2Payloa
|
||||
throw new GeneralSecurityException("No DateTime block in Session Request");
|
||||
// _nextSend is now(), from packetReceived()
|
||||
_skew = _nextSend - _timeReceived;
|
||||
if (_skew > MAX_SKEW || _skew < 0 - MAX_SKEW)
|
||||
if (_skew > MAX_SKEW || _skew < 0 - MAX_SKEW) {
|
||||
// send another retry with termination
|
||||
UDPPacket retry = _transport.getBuilder2().buildRetryPacket(this, SSU2Util.REASON_SKEW);
|
||||
_transport.send(retry);
|
||||
throw new GeneralSecurityException("Skew exceeded in Session Request: " + _skew);
|
||||
}
|
||||
_sendHeaderEncryptKey2 = SSU2Util.hkdf(_context, _handshakeState.getChainingKey(), "SessCreateHeader");
|
||||
_currentState = InboundState.IB_STATE_REQUEST_RECEIVED;
|
||||
_rtt = (int) (_nextSend - _lastSend);
|
||||
@@ -531,6 +537,8 @@ class InboundEstablishState2 extends InboundEstablishState implements SSU2Payloa
|
||||
* If the message is fragmented, store the data for reassembly and return,
|
||||
* unless this was the last one.
|
||||
*
|
||||
* Exceptions thrown from here are fatal.
|
||||
*
|
||||
* @return the new PeerState2 if are done, may also be retrieved from getPeerState(),
|
||||
* or null if more fragments to go
|
||||
*/
|
||||
|
||||
@@ -433,12 +433,14 @@ class PacketBuilder2 {
|
||||
* 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
|
||||
*/
|
||||
public UDPPacket buildRetryPacket(InboundEstablishState2 state) {
|
||||
public UDPPacket buildRetryPacket(InboundEstablishState2 state, int terminationCode) {
|
||||
long n = _context.random().signedNextInt() & 0xFFFFFFFFL;
|
||||
long token = terminationCode == 0 ? state.getToken() : 0;
|
||||
UDPPacket packet = buildLongPacketHeader(state.getSendConnID(), n, RETRY_FLAG_BYTE,
|
||||
state.getRcvConnID(), state.getToken());
|
||||
state.getRcvConnID(), token);
|
||||
DatagramPacket pkt = packet.getPacket();
|
||||
|
||||
byte sentIP[] = state.getSentIP();
|
||||
@@ -446,7 +448,7 @@ class PacketBuilder2 {
|
||||
int port = state.getSentPort();
|
||||
encryptRetry(packet, state.getSendHeaderEncryptKey1(), n, state.getSendHeaderEncryptKey1(),
|
||||
state.getSendHeaderEncryptKey2(),
|
||||
sentIP, port);
|
||||
sentIP, port, terminationCode);
|
||||
pkt.setSocketAddress(state.getSentAddress());
|
||||
packet.setMessageType(TYPE_CREAT);
|
||||
packet.setPriority(PRIORITY_HIGH);
|
||||
@@ -945,10 +947,18 @@ class PacketBuilder2 {
|
||||
|
||||
/**
|
||||
* @param packet containing only 32 byte header
|
||||
* @param terminationCode 0 normally, nonzero to send termination block
|
||||
*/
|
||||
private void encryptRetry(UDPPacket packet, byte[] chachaKey, long n,
|
||||
byte[] hdrKey1, byte[] hdrKey2, byte[] ip, int port) {
|
||||
encryptPeerTest(packet, chachaKey, n, hdrKey1, hdrKey2, ip, port, null);
|
||||
byte[] hdrKey1, byte[] hdrKey2, byte[] ip, int port,
|
||||
int terminationCode) {
|
||||
Block block;
|
||||
if (terminationCode != 0) {
|
||||
block = new SSU2Payload.TerminationBlock(terminationCode, 0);
|
||||
} else {
|
||||
block = null;
|
||||
}
|
||||
encryptPeerTest(packet, chachaKey, n, hdrKey1, hdrKey2, ip, port, block);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user