mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-13 11:19:04 +01:00
Make room for the ack header.
This commit is contained in:
@@ -14,6 +14,9 @@ public interface TransportConstants {
|
||||
/** The length of the frame header in bytes. */
|
||||
static final int FRAME_HEADER_LENGTH = 8;
|
||||
|
||||
/** The length of the ack header in bytes. */
|
||||
static final int ACK_HEADER_LENGTH = 5;
|
||||
|
||||
/** The length of the MAC in bytes. */
|
||||
static final int MAC_LENGTH = 32;
|
||||
|
||||
|
||||
@@ -45,19 +45,20 @@ class ConnectionReaderFactoryImpl implements ConnectionReaderFactory {
|
||||
Cipher tagCipher = crypto.getTagCipher();
|
||||
Cipher segCipher = crypto.getSegmentCipher();
|
||||
IncomingEncryptionLayer encryption = new IncomingEncryptionLayerImpl(in,
|
||||
tagCipher, segCipher, tagKey, segKey, false, bufferedTag);
|
||||
tagCipher, segCipher, tagKey, segKey, false, false,
|
||||
bufferedTag);
|
||||
// No error correction
|
||||
IncomingErrorCorrectionLayer correction =
|
||||
new NullIncomingErrorCorrectionLayer(encryption);
|
||||
// Create the authenticator
|
||||
Mac mac = crypto.getMac();
|
||||
IncomingAuthenticationLayer authentication =
|
||||
new IncomingAuthenticationLayerImpl(correction, mac, macKey);
|
||||
new IncomingAuthenticationLayerImpl(correction, mac, macKey, false);
|
||||
// No reordering or retransmission
|
||||
IncomingReliabilityLayer reliability =
|
||||
new NullIncomingReliabilityLayer(authentication);
|
||||
// Create the reader - don't tolerate errors
|
||||
return new ConnectionReaderImpl(reliability, false);
|
||||
return new ConnectionReaderImpl(reliability, false, false);
|
||||
}
|
||||
|
||||
public ConnectionReader createConnectionReader(SegmentSource in,
|
||||
@@ -82,18 +83,18 @@ class ConnectionReaderFactoryImpl implements ConnectionReaderFactory {
|
||||
Cipher segCipher = crypto.getSegmentCipher();
|
||||
IncomingEncryptionLayer encryption =
|
||||
new SegmentedIncomingEncryptionLayer(in, tagCipher, segCipher,
|
||||
tagKey, segKey, false, bufferedSegment);
|
||||
tagKey, segKey, false, false, bufferedSegment);
|
||||
// No error correction
|
||||
IncomingErrorCorrectionLayer correction =
|
||||
new NullIncomingErrorCorrectionLayer(encryption);
|
||||
// Create the authenticator
|
||||
Mac mac = crypto.getMac();
|
||||
IncomingAuthenticationLayer authentication =
|
||||
new IncomingAuthenticationLayerImpl(correction, mac, macKey);
|
||||
new IncomingAuthenticationLayerImpl(correction, mac, macKey, false);
|
||||
// No reordering or retransmission
|
||||
IncomingReliabilityLayer reliability =
|
||||
new NullIncomingReliabilityLayer(authentication);
|
||||
// Create the reader - don't tolerate errors
|
||||
return new ConnectionReaderImpl(reliability, false);
|
||||
return new ConnectionReaderImpl(reliability, false, false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package net.sf.briar.transport;
|
||||
|
||||
import static net.sf.briar.api.transport.TransportConstants.ACK_HEADER_LENGTH;
|
||||
import static net.sf.briar.api.transport.TransportConstants.FRAME_HEADER_LENGTH;
|
||||
|
||||
import java.io.IOException;
|
||||
@@ -12,13 +13,17 @@ class ConnectionReaderImpl extends InputStream implements ConnectionReader {
|
||||
|
||||
private final IncomingReliabilityLayer in;
|
||||
private final boolean tolerateErrors;
|
||||
private final int headerLength;
|
||||
|
||||
private Frame frame;
|
||||
private int offset = 0, length = 0;
|
||||
|
||||
ConnectionReaderImpl(IncomingReliabilityLayer in, boolean tolerateErrors) {
|
||||
ConnectionReaderImpl(IncomingReliabilityLayer in, boolean tolerateErrors,
|
||||
boolean ackHeader) {
|
||||
this.in = in;
|
||||
this.tolerateErrors = tolerateErrors;
|
||||
if(ackHeader) headerLength = FRAME_HEADER_LENGTH + ACK_HEADER_LENGTH;
|
||||
else headerLength = FRAME_HEADER_LENGTH;
|
||||
frame = new Frame(in.getMaxFrameLength());
|
||||
}
|
||||
|
||||
@@ -61,7 +66,7 @@ class ConnectionReaderImpl extends InputStream implements ConnectionReader {
|
||||
length = -1;
|
||||
return false;
|
||||
}
|
||||
offset = FRAME_HEADER_LENGTH;
|
||||
offset = headerLength;
|
||||
length = HeaderEncoder.getPayloadLength(frame.getBuffer());
|
||||
return true;
|
||||
} catch(InvalidDataException e) {
|
||||
|
||||
@@ -46,7 +46,7 @@ class ConnectionWriterFactoryImpl implements ConnectionWriterFactory {
|
||||
OutgoingReliabilityLayer reliability =
|
||||
new NullOutgoingReliabilityLayer(authentication);
|
||||
// Create the writer
|
||||
return new ConnectionWriterImpl(reliability);
|
||||
return new ConnectionWriterImpl(reliability, false);
|
||||
}
|
||||
|
||||
public ConnectionWriter createConnectionWriter(SegmentSink out,
|
||||
@@ -61,7 +61,7 @@ class ConnectionWriterFactoryImpl implements ConnectionWriterFactory {
|
||||
Cipher segCipher = crypto.getSegmentCipher();
|
||||
OutgoingEncryptionLayer encryption =
|
||||
new SegmentedOutgoingEncryptionLayer(out, capacity, tagCipher,
|
||||
segCipher, tagKey, segKey, false);
|
||||
segCipher, tagKey, segKey, false, false);
|
||||
// No error correction
|
||||
OutgoingErrorCorrectionLayer correction =
|
||||
new NullOutgoingErrorCorrectionLayer(encryption);
|
||||
@@ -73,6 +73,6 @@ class ConnectionWriterFactoryImpl implements ConnectionWriterFactory {
|
||||
OutgoingReliabilityLayer reliability =
|
||||
new NullOutgoingReliabilityLayer(authentication);
|
||||
// Create the writer
|
||||
return new ConnectionWriterImpl(reliability);
|
||||
return new ConnectionWriterImpl(reliability, false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package net.sf.briar.transport;
|
||||
|
||||
import static net.sf.briar.api.transport.TransportConstants.ACK_HEADER_LENGTH;
|
||||
import static net.sf.briar.api.transport.TransportConstants.FRAME_HEADER_LENGTH;
|
||||
import static net.sf.briar.api.transport.TransportConstants.MAC_LENGTH;
|
||||
import static net.sf.briar.util.ByteUtils.MAX_32_BIT_UNSIGNED;
|
||||
@@ -18,16 +19,20 @@ import net.sf.briar.api.transport.ConnectionWriter;
|
||||
class ConnectionWriterImpl extends OutputStream implements ConnectionWriter {
|
||||
|
||||
private final OutgoingReliabilityLayer out;
|
||||
private final int maxFrameLength;
|
||||
private final int headerLength, maxFrameLength;
|
||||
private final Frame frame;
|
||||
|
||||
private int offset = FRAME_HEADER_LENGTH;
|
||||
private long frameNumber = 0L;
|
||||
private int offset;
|
||||
private long frameNumber;
|
||||
|
||||
ConnectionWriterImpl(OutgoingReliabilityLayer out) {
|
||||
ConnectionWriterImpl(OutgoingReliabilityLayer out, boolean ackHeader) {
|
||||
this.out = out;
|
||||
if(ackHeader) headerLength = FRAME_HEADER_LENGTH + ACK_HEADER_LENGTH;
|
||||
else headerLength = FRAME_HEADER_LENGTH;
|
||||
maxFrameLength = out.getMaxFrameLength();
|
||||
frame = new Frame(maxFrameLength);
|
||||
offset = headerLength;
|
||||
frameNumber = 0L;
|
||||
}
|
||||
|
||||
public OutputStream getOutputStream() {
|
||||
@@ -37,17 +42,16 @@ class ConnectionWriterImpl extends OutputStream implements ConnectionWriter {
|
||||
public long getRemainingCapacity() {
|
||||
long capacity = out.getRemainingCapacity();
|
||||
// If there's any data buffered, subtract it and its overhead
|
||||
if(offset > FRAME_HEADER_LENGTH)
|
||||
capacity -= offset + MAC_LENGTH;
|
||||
if(offset > headerLength) capacity -= offset + MAC_LENGTH;
|
||||
// Subtract the overhead from the remaining capacity
|
||||
long frames = (long) Math.ceil((double) capacity / maxFrameLength);
|
||||
int overheadPerFrame = FRAME_HEADER_LENGTH + MAC_LENGTH;
|
||||
int overheadPerFrame = headerLength + MAC_LENGTH;
|
||||
return Math.max(0L, capacity - frames * overheadPerFrame);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void flush() throws IOException {
|
||||
if(offset > FRAME_HEADER_LENGTH) writeFrame();
|
||||
if(offset > headerLength) writeFrame();
|
||||
out.flush();
|
||||
}
|
||||
|
||||
@@ -80,12 +84,12 @@ class ConnectionWriterImpl extends OutputStream implements ConnectionWriter {
|
||||
|
||||
private void writeFrame() throws IOException {
|
||||
if(frameNumber > MAX_32_BIT_UNSIGNED) throw new IllegalStateException();
|
||||
int payload = offset - FRAME_HEADER_LENGTH;
|
||||
int payload = offset - headerLength;
|
||||
assert payload > 0;
|
||||
HeaderEncoder.encodeHeader(frame.getBuffer(), frameNumber, payload, 0);
|
||||
frame.setLength(offset + MAC_LENGTH);
|
||||
out.writeFrame(frame);
|
||||
offset = FRAME_HEADER_LENGTH;
|
||||
offset = headerLength;
|
||||
frameNumber++;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@ class Frame {
|
||||
}
|
||||
|
||||
public void setLength(int length) {
|
||||
if(length < 0 || length > buf.length)
|
||||
if(length < FRAME_HEADER_LENGTH + MAC_LENGTH || length > buf.length)
|
||||
throw new IllegalArgumentException();
|
||||
this.length = length;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package net.sf.briar.transport;
|
||||
|
||||
import static net.sf.briar.api.transport.TransportConstants.ACK_HEADER_LENGTH;
|
||||
import static net.sf.briar.api.transport.TransportConstants.FRAME_HEADER_LENGTH;
|
||||
import static net.sf.briar.api.transport.TransportConstants.MAC_LENGTH;
|
||||
|
||||
@@ -13,11 +14,11 @@ import net.sf.briar.api.crypto.ErasableKey;
|
||||
class IncomingAuthenticationLayerImpl implements IncomingAuthenticationLayer {
|
||||
|
||||
private final IncomingErrorCorrectionLayer in;
|
||||
private final int maxFrameLength;
|
||||
private final Mac mac;
|
||||
private final int headerLength, maxFrameLength;
|
||||
|
||||
IncomingAuthenticationLayerImpl(IncomingErrorCorrectionLayer in, Mac mac,
|
||||
ErasableKey macKey) {
|
||||
ErasableKey macKey, boolean ackHeader) {
|
||||
this.in = in;
|
||||
this.mac = mac;
|
||||
try {
|
||||
@@ -28,6 +29,8 @@ class IncomingAuthenticationLayerImpl implements IncomingAuthenticationLayer {
|
||||
macKey.erase();
|
||||
if(mac.getMacLength() != MAC_LENGTH)
|
||||
throw new IllegalArgumentException();
|
||||
if(ackHeader) headerLength = FRAME_HEADER_LENGTH + ACK_HEADER_LENGTH;
|
||||
else headerLength = FRAME_HEADER_LENGTH;
|
||||
maxFrameLength = in.getMaxFrameLength();
|
||||
}
|
||||
|
||||
@@ -37,22 +40,22 @@ class IncomingAuthenticationLayerImpl implements IncomingAuthenticationLayer {
|
||||
if(!in.readFrame(f, window)) return false;
|
||||
// Check that the length is legal
|
||||
int length = f.getLength();
|
||||
if(length < FRAME_HEADER_LENGTH + MAC_LENGTH)
|
||||
if(length < headerLength + MAC_LENGTH)
|
||||
throw new InvalidDataException();
|
||||
if(length > maxFrameLength) throw new InvalidDataException();
|
||||
// Check that the payload and padding lengths are correct
|
||||
byte[] buf = f.getBuffer();
|
||||
int payload = HeaderEncoder.getPayloadLength(buf);
|
||||
int padding = HeaderEncoder.getPaddingLength(buf);
|
||||
if(length != FRAME_HEADER_LENGTH + payload + padding + MAC_LENGTH)
|
||||
if(length != headerLength + payload + padding + MAC_LENGTH)
|
||||
throw new InvalidDataException();
|
||||
// Check that the padding is all zeroes
|
||||
int paddingStart = FRAME_HEADER_LENGTH + payload;
|
||||
int paddingStart = headerLength + payload;
|
||||
for(int i = paddingStart; i < paddingStart + padding; i++) {
|
||||
if(buf[i] != 0) throw new InvalidDataException();
|
||||
}
|
||||
// Verify the MAC
|
||||
int macStart = FRAME_HEADER_LENGTH + payload + padding;
|
||||
int macStart = headerLength + payload + padding;
|
||||
mac.update(buf, 0, macStart);
|
||||
byte[] expectedMac = mac.doFinal();
|
||||
for(int i = 0; i < expectedMac.length; i++) {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package net.sf.briar.transport;
|
||||
|
||||
import static net.sf.briar.api.transport.TransportConstants.ACK_HEADER_LENGTH;
|
||||
import static net.sf.briar.api.transport.TransportConstants.FRAME_HEADER_LENGTH;
|
||||
import static net.sf.briar.api.transport.TransportConstants.MAC_LENGTH;
|
||||
import static net.sf.briar.api.transport.TransportConstants.MAX_FRAME_LENGTH;
|
||||
@@ -24,7 +25,7 @@ class IncomingEncryptionLayerImpl implements IncomingEncryptionLayer {
|
||||
private final Cipher tagCipher, segCipher;
|
||||
private final ErasableKey tagKey, segKey;
|
||||
private final boolean tagEverySegment;
|
||||
private final int blockSize;
|
||||
private final int headerLength, blockSize;
|
||||
private final byte[] iv, ciphertext;
|
||||
|
||||
private byte[] bufferedTag;
|
||||
@@ -33,7 +34,7 @@ class IncomingEncryptionLayerImpl implements IncomingEncryptionLayer {
|
||||
|
||||
IncomingEncryptionLayerImpl(InputStream in, Cipher tagCipher,
|
||||
Cipher segCipher, ErasableKey tagKey, ErasableKey segKey,
|
||||
boolean tagEverySegment, byte[] bufferedTag) {
|
||||
boolean tagEverySegment, boolean ackHeader, byte[] bufferedTag) {
|
||||
this.in = in;
|
||||
this.tagCipher = tagCipher;
|
||||
this.segCipher = segCipher;
|
||||
@@ -41,6 +42,8 @@ class IncomingEncryptionLayerImpl implements IncomingEncryptionLayer {
|
||||
this.segKey = segKey;
|
||||
this.tagEverySegment = tagEverySegment;
|
||||
this.bufferedTag = bufferedTag;
|
||||
if(ackHeader) headerLength = FRAME_HEADER_LENGTH + ACK_HEADER_LENGTH;
|
||||
else headerLength = FRAME_HEADER_LENGTH;
|
||||
blockSize = segCipher.getBlockSize();
|
||||
if(blockSize < FRAME_HEADER_LENGTH)
|
||||
throw new IllegalArgumentException();
|
||||
@@ -102,7 +105,7 @@ class IncomingEncryptionLayerImpl implements IncomingEncryptionLayer {
|
||||
// Parse the frame header
|
||||
int payload = HeaderEncoder.getPayloadLength(plaintext);
|
||||
int padding = HeaderEncoder.getPaddingLength(plaintext);
|
||||
int length = FRAME_HEADER_LENGTH + payload + padding + MAC_LENGTH;
|
||||
int length = headerLength + payload + padding + MAC_LENGTH;
|
||||
if(length > MAX_FRAME_LENGTH) throw new FormatException();
|
||||
// Read the remainder of the frame
|
||||
while(offset < length) {
|
||||
|
||||
@@ -39,7 +39,7 @@ class SegmentImpl implements Segment {
|
||||
}
|
||||
|
||||
public void setLength(int length) {
|
||||
if(length < 0 || length > buf.length)
|
||||
if(length < FRAME_HEADER_LENGTH + MAC_LENGTH || length > buf.length)
|
||||
throw new IllegalArgumentException();
|
||||
this.length = length;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package net.sf.briar.transport;
|
||||
|
||||
import static net.sf.briar.api.transport.TransportConstants.ACK_HEADER_LENGTH;
|
||||
import static net.sf.briar.api.transport.TransportConstants.FRAME_HEADER_LENGTH;
|
||||
import static net.sf.briar.api.transport.TransportConstants.MAC_LENGTH;
|
||||
import static net.sf.briar.api.transport.TransportConstants.MAX_SEGMENT_LENGTH;
|
||||
@@ -21,7 +22,7 @@ class SegmentedIncomingEncryptionLayer implements IncomingEncryptionLayer {
|
||||
private final Cipher tagCipher, segCipher;
|
||||
private final ErasableKey tagKey, segKey;
|
||||
private final boolean tagEverySegment;
|
||||
private final int blockSize, maxSegmentLength;
|
||||
private final int blockSize, headerLength, maxSegmentLength;
|
||||
private final Segment segment;
|
||||
private final byte[] iv;
|
||||
|
||||
@@ -31,7 +32,8 @@ class SegmentedIncomingEncryptionLayer implements IncomingEncryptionLayer {
|
||||
|
||||
SegmentedIncomingEncryptionLayer(SegmentSource in, Cipher tagCipher,
|
||||
Cipher segCipher, ErasableKey tagKey, ErasableKey segKey,
|
||||
boolean tagEverySegment, Segment bufferedSegment) {
|
||||
boolean tagEverySegment, boolean ackHeader,
|
||||
Segment bufferedSegment) {
|
||||
this.in = in;
|
||||
this.tagCipher = tagCipher;
|
||||
this.segCipher = segCipher;
|
||||
@@ -42,8 +44,10 @@ class SegmentedIncomingEncryptionLayer implements IncomingEncryptionLayer {
|
||||
blockSize = segCipher.getBlockSize();
|
||||
if(blockSize < FRAME_HEADER_LENGTH)
|
||||
throw new IllegalArgumentException();
|
||||
if(ackHeader) headerLength = FRAME_HEADER_LENGTH + ACK_HEADER_LENGTH;
|
||||
else headerLength = FRAME_HEADER_LENGTH;
|
||||
int length = in.getMaxSegmentLength();
|
||||
if(length < TAG_LENGTH + FRAME_HEADER_LENGTH + 1 + MAC_LENGTH)
|
||||
if(length < TAG_LENGTH + headerLength + 1 + MAC_LENGTH)
|
||||
throw new IllegalArgumentException();
|
||||
if(length > MAX_SEGMENT_LENGTH) throw new IllegalArgumentException();
|
||||
maxSegmentLength = length - TAG_LENGTH;
|
||||
@@ -67,7 +71,7 @@ class SegmentedIncomingEncryptionLayer implements IncomingEncryptionLayer {
|
||||
}
|
||||
int offset = expectTag ? TAG_LENGTH : 0;
|
||||
int length = segment.getLength();
|
||||
if(length < offset + FRAME_HEADER_LENGTH + MAC_LENGTH)
|
||||
if(length < offset + headerLength + MAC_LENGTH)
|
||||
throw new InvalidDataException();
|
||||
if(length > offset + maxSegmentLength)
|
||||
throw new InvalidDataException();
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package net.sf.briar.transport;
|
||||
|
||||
import static net.sf.briar.api.transport.TransportConstants.ACK_HEADER_LENGTH;
|
||||
import static net.sf.briar.api.transport.TransportConstants.FRAME_HEADER_LENGTH;
|
||||
import static net.sf.briar.api.transport.TransportConstants.MAC_LENGTH;
|
||||
import static net.sf.briar.api.transport.TransportConstants.MAX_SEGMENT_LENGTH;
|
||||
@@ -21,7 +22,7 @@ class SegmentedOutgoingEncryptionLayer implements OutgoingEncryptionLayer {
|
||||
private final Cipher tagCipher, segCipher;
|
||||
private final ErasableKey tagKey, segKey;
|
||||
private final boolean tagEverySegment;
|
||||
private final int maxSegmentLength;
|
||||
private final int headerLength, maxSegmentLength;
|
||||
private final Segment segment;
|
||||
private final byte[] iv;
|
||||
|
||||
@@ -29,7 +30,7 @@ class SegmentedOutgoingEncryptionLayer implements OutgoingEncryptionLayer {
|
||||
|
||||
SegmentedOutgoingEncryptionLayer(SegmentSink out, long capacity,
|
||||
Cipher tagCipher, Cipher segCipher, ErasableKey tagKey,
|
||||
ErasableKey segKey, boolean tagEverySegment) {
|
||||
ErasableKey segKey, boolean tagEverySegment, boolean ackHeader) {
|
||||
this.out = out;
|
||||
this.capacity = capacity;
|
||||
this.tagCipher = tagCipher;
|
||||
@@ -37,10 +38,12 @@ class SegmentedOutgoingEncryptionLayer implements OutgoingEncryptionLayer {
|
||||
this.tagKey = tagKey;
|
||||
this.segKey = segKey;
|
||||
this.tagEverySegment = tagEverySegment;
|
||||
if(ackHeader) headerLength = FRAME_HEADER_LENGTH + ACK_HEADER_LENGTH;
|
||||
else headerLength = FRAME_HEADER_LENGTH;
|
||||
int length = out.getMaxSegmentLength();
|
||||
if(length < TAG_LENGTH + FRAME_HEADER_LENGTH + 1 + MAC_LENGTH)
|
||||
throw new RuntimeException();
|
||||
if(length > MAX_SEGMENT_LENGTH) throw new RuntimeException();
|
||||
if(length < TAG_LENGTH + headerLength + 1 + MAC_LENGTH)
|
||||
throw new IllegalArgumentException();
|
||||
if(length > MAX_SEGMENT_LENGTH) throw new IllegalArgumentException();
|
||||
maxSegmentLength = length - MAC_LENGTH;
|
||||
segment = new SegmentImpl(length);
|
||||
iv = IvEncoder.encodeIv(0L, segCipher.getBlockSize());
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package net.sf.briar.transport;
|
||||
|
||||
import static net.sf.briar.api.transport.TransportConstants.ACK_HEADER_LENGTH;
|
||||
import static net.sf.briar.api.transport.TransportConstants.FRAME_HEADER_LENGTH;
|
||||
import static net.sf.briar.api.transport.TransportConstants.MAC_LENGTH;
|
||||
import static net.sf.briar.api.transport.TransportConstants.MAX_FRAME_LENGTH;
|
||||
@@ -9,10 +10,12 @@ import net.sf.briar.api.transport.Segment;
|
||||
/** An erasure decoder that uses k data segments and one parity segment. */
|
||||
class XorErasureDecoder implements ErasureDecoder {
|
||||
|
||||
private final int n;
|
||||
private final int n, headerLength;
|
||||
|
||||
XorErasureDecoder(int n) {
|
||||
XorErasureDecoder(int n, boolean ackHeader) {
|
||||
this.n = n;
|
||||
if(ackHeader) headerLength = FRAME_HEADER_LENGTH + ACK_HEADER_LENGTH;
|
||||
else headerLength = FRAME_HEADER_LENGTH;
|
||||
}
|
||||
|
||||
public boolean decodeFrame(Frame f, Segment[] set) throws FormatException {
|
||||
@@ -61,10 +64,10 @@ class XorErasureDecoder implements ErasureDecoder {
|
||||
int copyLength = Math.min(length, dest.length - missingOffset);
|
||||
System.arraycopy(parity, 0, dest, missingOffset, copyLength);
|
||||
}
|
||||
// The frame length may not be an exact multiple of the segment length
|
||||
// The frame length might not be an exact multiple of the segment length
|
||||
int payload = HeaderEncoder.getPayloadLength(dest);
|
||||
int padding = HeaderEncoder.getPaddingLength(dest);
|
||||
int frameLength = FRAME_HEADER_LENGTH + payload + padding + MAC_LENGTH;
|
||||
int frameLength = headerLength + payload + padding + MAC_LENGTH;
|
||||
if(frameLength > MAX_FRAME_LENGTH) throw new FormatException();
|
||||
f.setLength(frameLength);
|
||||
return true;
|
||||
|
||||
@@ -222,9 +222,9 @@ public class ConnectionReaderImplTest extends TransportTest {
|
||||
IncomingErrorCorrectionLayer correction =
|
||||
new NullIncomingErrorCorrectionLayer(encryption);
|
||||
IncomingAuthenticationLayer authentication =
|
||||
new IncomingAuthenticationLayerImpl(correction, mac, macKey);
|
||||
new IncomingAuthenticationLayerImpl(correction, mac, macKey, false);
|
||||
IncomingReliabilityLayer reliability =
|
||||
new NullIncomingReliabilityLayer(authentication);
|
||||
return new ConnectionReaderImpl(reliability, false);
|
||||
return new ConnectionReaderImpl(reliability, false, false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -115,6 +115,6 @@ public class ConnectionWriterImplTest extends TransportTest {
|
||||
new OutgoingAuthenticationLayerImpl(correction, mac, macKey);
|
||||
OutgoingReliabilityLayer reliability =
|
||||
new NullOutgoingReliabilityLayer(authentication);
|
||||
return new ConnectionWriterImpl(reliability);
|
||||
return new ConnectionWriterImpl(reliability, false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -83,7 +83,8 @@ public class FrameReadWriteTest extends BriarTestCase {
|
||||
new OutgoingAuthenticationLayerImpl(correctionOut, mac, macCopy);
|
||||
OutgoingReliabilityLayer reliabilityOut =
|
||||
new NullOutgoingReliabilityLayer(authenticationOut);
|
||||
ConnectionWriter writer = new ConnectionWriterImpl(reliabilityOut);
|
||||
ConnectionWriter writer = new ConnectionWriterImpl(reliabilityOut,
|
||||
false);
|
||||
OutputStream out1 = writer.getOutputStream();
|
||||
out1.write(frame);
|
||||
out1.flush();
|
||||
@@ -97,14 +98,16 @@ public class FrameReadWriteTest extends BriarTestCase {
|
||||
assertEquals(0L, TagEncoder.decodeTag(tag, tagCipher, tagKey));
|
||||
// Read the frames back
|
||||
IncomingEncryptionLayer encryptionIn = new IncomingEncryptionLayerImpl(
|
||||
in, tagCipher, segCipher, tagKey, segKey, false, recoveredTag);
|
||||
in, tagCipher, segCipher, tagKey, segKey, false, false,
|
||||
recoveredTag);
|
||||
IncomingErrorCorrectionLayer correctionIn =
|
||||
new NullIncomingErrorCorrectionLayer(encryptionIn);
|
||||
IncomingAuthenticationLayer authenticationIn =
|
||||
new IncomingAuthenticationLayerImpl(correctionIn, mac, macKey);
|
||||
new IncomingAuthenticationLayerImpl(correctionIn, mac, macKey,
|
||||
false);
|
||||
IncomingReliabilityLayer reliabilityIn =
|
||||
new NullIncomingReliabilityLayer(authenticationIn);
|
||||
ConnectionReader reader = new ConnectionReaderImpl(reliabilityIn,
|
||||
ConnectionReader reader = new ConnectionReaderImpl(reliabilityIn, false,
|
||||
false);
|
||||
InputStream in1 = reader.getInputStream();
|
||||
byte[] recovered = new byte[frame.length];
|
||||
|
||||
@@ -63,7 +63,7 @@ public class IncomingEncryptionLayerImplTest extends BriarTestCase {
|
||||
ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());
|
||||
// Use the encryption layer to decrypt the ciphertext
|
||||
IncomingEncryptionLayer decrypter = new IncomingEncryptionLayerImpl(in,
|
||||
tagCipher, segCipher, tagKey, segKey, false, tag);
|
||||
tagCipher, segCipher, tagKey, segKey, false, false, tag);
|
||||
// First segment
|
||||
Segment s = new SegmentImpl();
|
||||
assertTrue(decrypter.readSegment(s));
|
||||
@@ -114,7 +114,7 @@ public class IncomingEncryptionLayerImplTest extends BriarTestCase {
|
||||
ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());
|
||||
// Use the encryption layer to decrypt the ciphertext
|
||||
IncomingEncryptionLayer decrypter = new IncomingEncryptionLayerImpl(in,
|
||||
tagCipher, segCipher, tagKey, segKey, true, tag);
|
||||
tagCipher, segCipher, tagKey, segKey, true, false, tag);
|
||||
// First segment
|
||||
Segment s = new SegmentImpl();
|
||||
assertTrue(decrypter.readSegment(s));
|
||||
|
||||
@@ -25,7 +25,8 @@ public class IncomingReliabilityLayerImplTest extends BriarTestCase {
|
||||
new TestIncomingAuthenticationLayer(frameNumbers);
|
||||
IncomingReliabilityLayerImpl reliability =
|
||||
new IncomingReliabilityLayerImpl(authentication);
|
||||
ConnectionReader reader = new ConnectionReaderImpl(reliability, false);
|
||||
ConnectionReader reader = new ConnectionReaderImpl(reliability, false,
|
||||
false);
|
||||
InputStream in = reader.getInputStream();
|
||||
for(int i = 0; i < FRAME_WINDOW_SIZE * 2; i++) {
|
||||
for(int j = 0; j < 100; j++) assertEquals(i, in.read());
|
||||
@@ -50,7 +51,8 @@ public class IncomingReliabilityLayerImplTest extends BriarTestCase {
|
||||
new TestIncomingAuthenticationLayer(frameNumbers);
|
||||
IncomingReliabilityLayerImpl reliability =
|
||||
new IncomingReliabilityLayerImpl(authentication);
|
||||
ConnectionReader reader = new ConnectionReaderImpl(reliability, false);
|
||||
ConnectionReader reader = new ConnectionReaderImpl(reliability, false,
|
||||
false);
|
||||
InputStream in = reader.getInputStream();
|
||||
for(int i = 0; i < FRAME_WINDOW_SIZE * 2; i++) {
|
||||
for(int j = 0; j < 100; j++) assertEquals(i, in.read());
|
||||
|
||||
@@ -66,7 +66,7 @@ public class SegmentedIncomingEncryptionLayerTest extends BriarTestCase {
|
||||
// Use the encryption layer to decrypt the ciphertext
|
||||
IncomingEncryptionLayer decrypter =
|
||||
new SegmentedIncomingEncryptionLayer(in, tagCipher, segCipher,
|
||||
tagKey, segKey, false, buffered);
|
||||
tagKey, segKey, false, false, buffered);
|
||||
// First segment
|
||||
Segment s = new SegmentImpl();
|
||||
assertTrue(decrypter.readSegment(s));
|
||||
@@ -117,7 +117,7 @@ public class SegmentedIncomingEncryptionLayerTest extends BriarTestCase {
|
||||
// Use the encryption layer to decrypt the ciphertext
|
||||
IncomingEncryptionLayer decrypter =
|
||||
new SegmentedIncomingEncryptionLayer(in, tagCipher, segCipher,
|
||||
tagKey, segKey, true, buffered);
|
||||
tagKey, segKey, true, false, buffered);
|
||||
// First segment
|
||||
Segment s = new SegmentImpl();
|
||||
assertTrue(decrypter.readSegment(s));
|
||||
|
||||
@@ -66,7 +66,7 @@ public class SegmentedOutgoingEncryptionLayerTest extends BriarTestCase {
|
||||
ByteArraySegmentSink sink = new ByteArraySegmentSink();
|
||||
OutgoingEncryptionLayer encrypter =
|
||||
new SegmentedOutgoingEncryptionLayer(sink, Long.MAX_VALUE,
|
||||
tagCipher, segCipher, tagKey, segKey, false);
|
||||
tagCipher, segCipher, tagKey, segKey, false, false);
|
||||
Segment s = new SegmentImpl();
|
||||
System.arraycopy(plaintext, 0, s.getBuffer(), 0, plaintext.length);
|
||||
s.setLength(plaintext.length);
|
||||
@@ -114,7 +114,7 @@ public class SegmentedOutgoingEncryptionLayerTest extends BriarTestCase {
|
||||
SegmentSink sink = new ByteArraySegmentSink();
|
||||
OutgoingEncryptionLayer encrypter =
|
||||
new SegmentedOutgoingEncryptionLayer(sink, Long.MAX_VALUE,
|
||||
tagCipher, segCipher, tagKey, segKey, true);
|
||||
tagCipher, segCipher, tagKey, segKey, true, false);
|
||||
Segment s = new SegmentImpl();
|
||||
System.arraycopy(plaintext, 0, s.getBuffer(), 0, plaintext.length);
|
||||
s.setLength(plaintext.length);
|
||||
|
||||
@@ -16,7 +16,7 @@ public class XorErasureCodeTest extends BriarTestCase {
|
||||
@Test
|
||||
public void testEncodingAndDecodingWithAllSegments() throws Exception {
|
||||
XorErasureEncoder e = new XorErasureEncoder(5);
|
||||
XorErasureDecoder d = new XorErasureDecoder(5);
|
||||
XorErasureDecoder d = new XorErasureDecoder(5, false);
|
||||
Frame f = new Frame(1234);
|
||||
new Random().nextBytes(f.getBuffer());
|
||||
int payload = 1234 - FRAME_HEADER_LENGTH - MAC_LENGTH;
|
||||
@@ -32,7 +32,7 @@ public class XorErasureCodeTest extends BriarTestCase {
|
||||
@Test
|
||||
public void testEncodingAndDecodingWithMissingSegment() throws Exception {
|
||||
XorErasureEncoder e = new XorErasureEncoder(5);
|
||||
XorErasureDecoder d = new XorErasureDecoder(5);
|
||||
XorErasureDecoder d = new XorErasureDecoder(5, false);
|
||||
Frame f = new Frame(1234);
|
||||
new Random().nextBytes(f.getBuffer());
|
||||
int payload = 1234 - FRAME_HEADER_LENGTH - MAC_LENGTH;
|
||||
|
||||
@@ -14,7 +14,7 @@ public class XorErasureDecoderTest extends BriarTestCase {
|
||||
|
||||
@Test
|
||||
public void testMaximumLength() throws Exception {
|
||||
XorErasureDecoder d = new XorErasureDecoder(5);
|
||||
XorErasureDecoder d = new XorErasureDecoder(5, false);
|
||||
// A frame of the maximum length should be decoded successfully
|
||||
Segment[] set = encodeEmptyFrame(MAX_FRAME_LENGTH / 4, 5);
|
||||
Frame f = new Frame();
|
||||
@@ -37,7 +37,7 @@ public class XorErasureDecoderTest extends BriarTestCase {
|
||||
set[1] = new SegmentImpl(251);
|
||||
set[1].setLength(251);
|
||||
// The frame should be decoded successfully
|
||||
XorErasureDecoder d = new XorErasureDecoder(4);
|
||||
XorErasureDecoder d = new XorErasureDecoder(4, false);
|
||||
Frame f = new Frame(750);
|
||||
assertTrue(d.decodeFrame(f, set));
|
||||
// The minimum of the segments' lengths should have been used
|
||||
@@ -46,7 +46,7 @@ public class XorErasureDecoderTest extends BriarTestCase {
|
||||
|
||||
@Test
|
||||
public void testDecodingWithMissingSegment() throws Exception {
|
||||
XorErasureDecoder d = new XorErasureDecoder(4);
|
||||
XorErasureDecoder d = new XorErasureDecoder(4, false);
|
||||
for(int i = 0; i < 4; i++) {
|
||||
Segment[] set = encodeEmptyFrame(250, 4);
|
||||
set[i] = null;
|
||||
@@ -59,7 +59,7 @@ public class XorErasureDecoderTest extends BriarTestCase {
|
||||
|
||||
@Test
|
||||
public void testDecodingWithTwoMissingSegments() throws Exception {
|
||||
XorErasureDecoder d = new XorErasureDecoder(4);
|
||||
XorErasureDecoder d = new XorErasureDecoder(4, false);
|
||||
Segment[] set = encodeEmptyFrame(250, 4);
|
||||
set[0] = null;
|
||||
set[1] = null;
|
||||
|
||||
Reference in New Issue
Block a user