Skip to content

Commit

Permalink
Update address only for newest tls12_cid records.
Browse files Browse the repository at this point in the history
Fix updates with already deprecated addresses.

Signed-off-by: Achim Kraus <achim.kraus@bosch-si.com>
  • Loading branch information
Achim Kraus committed Jul 13, 2019
1 parent df92298 commit 8bba4a0
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 17 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -1239,13 +1239,15 @@ private void processApplicationDataRecord(final Record record, final Connection
record.setSession(session);
ApplicationMessage message = (ApplicationMessage) record.getFragment();
// the fragment could be de-crypted, mark it
session.markRecordAsRead(record.getEpoch(), record.getSequenceNumber());
boolean updateAddress = session.markRecordAsRead(record.getEpoch(), record.getSequenceNumber());
if (ongoingHandshake != null) {
// the handshake has been completed successfully
ongoingHandshake.handshakeCompleted();
}
connection.refreshAutoResumptionTime();
connectionStore.update(connection, record.getPeerAddress());
if (updateAddress) {
connectionStore.update(connection, record.getPeerAddress());
}

final RawDataChannel channel = messageHandler;
// finally, forward de-crypted message to application layer
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ public final class DTLSSession {
*/
private boolean parameterAvailable = false;

private volatile long receiveWindowUpperBoundary = RECEIVE_WINDOW_SIZE - 1;
private volatile long receiveWindowUpperCurrent = -1;
private volatile long receiveWindowLowerBoundary = 0;
private volatile long receivedRecordsVector = 0;
private long creationTime;
Expand Down Expand Up @@ -940,7 +940,7 @@ public boolean isRecordProcessable(long epoch, long sequenceNo, boolean useWindo
* @return <code>true</code> if the record has already been received
*/
boolean isDuplicate(long sequenceNo) {
if (sequenceNo > receiveWindowUpperBoundary) {
if (sequenceNo > receiveWindowUpperCurrent) {
return false;
} else {

Expand All @@ -959,31 +959,39 @@ boolean isDuplicate(long sequenceNo) {
}

/**
* Marks a record as having been received so that it can be detected
* as a duplicate if it is received again, e.g. if a client re-transmits
* the record because it runs into a timeout.
* Marks a record as having been received so that it can be detected as a
* duplicate if it is received again, e.g. if a client re-transmits the
* record because it runs into a timeout.
*
* The record is marked as received only if it belongs to this session's
* current read epoch as indicated by {@link #getReadEpoch()}.
*
* @param epoch the record's epoch
* @param sequenceNo the record's sequence number
* @return {@code true}, if the sequenceNo is higher than the current upper
* boundary. {@code false}, if not.
*/
public void markRecordAsRead(long epoch, long sequenceNo) {

public boolean markRecordAsRead(long epoch, long sequenceNo) {
if (epoch == getReadEpoch()) {
if (sequenceNo > receiveWindowUpperBoundary) {
long incr = sequenceNo - receiveWindowUpperBoundary;
receiveWindowUpperBoundary = sequenceNo;
// slide receive window to the right
receivedRecordsVector = receivedRecordsVector >>> incr;
receiveWindowLowerBoundary = Math.max(0, receiveWindowUpperBoundary - RECEIVE_WINDOW_SIZE + 1);
boolean newest = sequenceNo > receiveWindowUpperCurrent;
if (newest) {
receiveWindowUpperCurrent = sequenceNo;
long lowerBoundary = Math.max(0, sequenceNo - RECEIVE_WINDOW_SIZE + 1);
long incr = lowerBoundary - receiveWindowLowerBoundary;
if (incr > 0) {
// slide receive window to the right
receivedRecordsVector = receivedRecordsVector >>> incr;
receiveWindowLowerBoundary = lowerBoundary;
}
}
long bitMask = 1L << (sequenceNo - receiveWindowLowerBoundary);
// mark sequence number as "received" in receive window
receivedRecordsVector |= bitMask;
LOGGER.debug("Updated receive window with sequence number [{}]: new upper boundary [{}], new bit vector [{}]",
sequenceNo, receiveWindowUpperBoundary, Long.toBinaryString(receivedRecordsVector));
sequenceNo, receiveWindowUpperCurrent, Long.toBinaryString(receivedRecordsVector));
return newest;
} else {
return epoch > getReadEpoch();
}
}

Expand All @@ -995,7 +1003,7 @@ public void markRecordAsRead(long epoch, long sequenceNo) {
*/
private void resetReceiveWindow() {
receivedRecordsVector = 0;
receiveWindowUpperBoundary = RECEIVE_WINDOW_SIZE - 1;
receiveWindowUpperCurrent = -1;
receiveWindowLowerBoundary = 0;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,44 @@ public void testEpochSwitchResetsReceiveWindow() {
assertTrue(session.isRecordProcessable(session.getReadEpoch(), 2, false));
}

@Test
public void testHigherSequenceNumberIsNewer() {

int epoch = session.getReadEpoch();
session.markRecordAsRead(epoch, 0);
assertTrue(session.markRecordAsRead(epoch, 2));
}

@Test
public void testLowerSequenceNumberIsNotNewer() {

int epoch = session.getReadEpoch();
session.markRecordAsRead(epoch, 2);
assertFalse(session.markRecordAsRead(epoch, 0));
}

@Test
public void testSameSequenceNumberIsNotNewer() {

int epoch = session.getReadEpoch();
session.markRecordAsRead(epoch, 2);
assertFalse(session.markRecordAsRead(epoch, 2));
}

@Test
public void testHigherEpochIsNewer() {
int epoch = session.getReadEpoch();
session.markRecordAsRead(epoch, 2);
assertTrue(session.markRecordAsRead(epoch + 1, 0));
}

@Test
public void testLowerEpochIsNotNewer() {
int epoch = session.getReadEpoch();
session.markRecordAsRead(epoch, 0);
assertFalse(session.markRecordAsRead(epoch - 1, 2));
}

@Test
public void testConstructorEnforcesMaxSequenceNo() {
session = new DTLSSession(PEER_ADDRESS, DtlsTestTools.MAX_SEQUENCE_NO); // should succeed
Expand Down

0 comments on commit 8bba4a0

Please sign in to comment.