mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-13 11:19:04 +01:00
Outgoing error correction layer (untested).
This commit is contained in:
@@ -67,7 +67,7 @@ class ConnectionReaderFactoryImpl implements ConnectionReaderFactory {
|
||||
|
||||
public ConnectionReader createConnectionReader(SegmentSource in,
|
||||
byte[] secret) {
|
||||
return createConnectionReader(in, secret, new SegmentImpl(), false);
|
||||
return createConnectionReader(in, secret, null, false);
|
||||
}
|
||||
|
||||
private ConnectionReader createConnectionReader(SegmentSource in,
|
||||
|
||||
9
components/net/sf/briar/transport/ErasureEncoder.java
Normal file
9
components/net/sf/briar/transport/ErasureEncoder.java
Normal file
@@ -0,0 +1,9 @@
|
||||
package net.sf.briar.transport;
|
||||
|
||||
import net.sf.briar.api.transport.Segment;
|
||||
|
||||
interface ErasureEncoder {
|
||||
|
||||
/** Encodes the given frame as a set of segments. */
|
||||
Segment[] encodeFrame(Frame f);
|
||||
}
|
||||
@@ -34,7 +34,7 @@ class IncomingErrorCorrectionLayerImpl implements IncomingErrorCorrectionLayer {
|
||||
// Free any discard counts that are no longer too high for the window
|
||||
Iterator<Long> it1 = discardCounts.keySet().iterator();
|
||||
while(it1.hasNext()) if(!window.isTooHigh(it1.next())) it1.remove();
|
||||
// Allocate a segment
|
||||
// FIXME: Unnecessary allocation
|
||||
Segment s = new SegmentImpl();
|
||||
// Read segments until a frame can be decoded
|
||||
while(true) {
|
||||
@@ -51,9 +51,8 @@ class IncomingErrorCorrectionLayerImpl implements IncomingErrorCorrectionLayer {
|
||||
if(set == null) {
|
||||
set = new Segment[n];
|
||||
segmentSets.put(frameNumber, set);
|
||||
} else {
|
||||
set[(int) (frameNumber % n)] = s;
|
||||
}
|
||||
set[(int) (frameNumber % n)] = s;
|
||||
// Try to decode the frame
|
||||
if(decoder.decodeFrame(f, set)) return true;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
package net.sf.briar.transport;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import net.sf.briar.api.transport.Segment;
|
||||
|
||||
class OutgoingErrorCorrectionLayerImpl implements OutgoingErrorCorrectionLayer {
|
||||
|
||||
private final OutgoingEncryptionLayer out;
|
||||
private final ErasureEncoder encoder;
|
||||
private final int n;
|
||||
|
||||
OutgoingErrorCorrectionLayerImpl(OutgoingEncryptionLayer out,
|
||||
ErasureEncoder encoder, int n) {
|
||||
this.out = out;
|
||||
this.encoder = encoder;
|
||||
this.n = n;
|
||||
}
|
||||
|
||||
public void writeFrame(Frame f) throws IOException {
|
||||
for(Segment s : encoder.encodeFrame(f)) out.writeSegment(s);
|
||||
}
|
||||
|
||||
public void flush() throws IOException {
|
||||
out.flush();
|
||||
}
|
||||
|
||||
public long getRemainingCapacity() {
|
||||
return out.getRemainingCapacity() / n;
|
||||
}
|
||||
}
|
||||
@@ -1,16 +1,24 @@
|
||||
package net.sf.briar.transport;
|
||||
|
||||
import static net.sf.briar.api.transport.TransportConstants.MAX_SEGMENT_LENGTH;
|
||||
import static net.sf.briar.util.ByteUtils.MAX_32_BIT_UNSIGNED;
|
||||
import net.sf.briar.api.transport.Segment;
|
||||
import net.sf.briar.util.ByteUtils;
|
||||
|
||||
class SegmentImpl implements Segment {
|
||||
|
||||
private final byte[] buf = new byte[MAX_SEGMENT_LENGTH];
|
||||
private final byte[] buf;
|
||||
|
||||
private int length = -1;
|
||||
private long segmentNumber = -1;
|
||||
|
||||
SegmentImpl() {
|
||||
this(MAX_SEGMENT_LENGTH);
|
||||
}
|
||||
|
||||
SegmentImpl(int length) {
|
||||
buf = new byte[length];
|
||||
}
|
||||
|
||||
public byte[] getBuffer() {
|
||||
return buf;
|
||||
}
|
||||
@@ -32,7 +40,7 @@ class SegmentImpl implements Segment {
|
||||
}
|
||||
|
||||
public void setSegmentNumber(long segmentNumber) {
|
||||
if(segmentNumber < 0 || segmentNumber > ByteUtils.MAX_32_BIT_UNSIGNED)
|
||||
if(segmentNumber < 0 || segmentNumber > MAX_32_BIT_UNSIGNED)
|
||||
throw new IllegalArgumentException();
|
||||
this.segmentNumber = segmentNumber;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package net.sf.briar.transport;
|
||||
|
||||
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;
|
||||
import net.sf.briar.api.FormatException;
|
||||
import net.sf.briar.api.transport.Segment;
|
||||
@@ -54,7 +56,13 @@ class XorErasureDecoder implements ErasureDecoder {
|
||||
assert missingOffset != -1;
|
||||
System.arraycopy(parity, 0, dest, missingOffset, length);
|
||||
}
|
||||
f.setLength(offset);
|
||||
assert offset == length * (n - 1);
|
||||
// The frame length may 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;
|
||||
if(frameLength > MAX_FRAME_LENGTH) throw new FormatException();
|
||||
f.setLength(frameLength);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
30
components/net/sf/briar/transport/XorErasureEncoder.java
Normal file
30
components/net/sf/briar/transport/XorErasureEncoder.java
Normal file
@@ -0,0 +1,30 @@
|
||||
package net.sf.briar.transport;
|
||||
|
||||
import net.sf.briar.api.transport.Segment;
|
||||
|
||||
/** An erasure encoder than uses k data segments and one parity segment. */
|
||||
class XorErasureEncoder implements ErasureEncoder {
|
||||
|
||||
private final int n;
|
||||
|
||||
XorErasureEncoder(int n) {
|
||||
this.n = n;
|
||||
}
|
||||
|
||||
public Segment[] encodeFrame(Frame f) {
|
||||
Segment[] set = new Segment[n];
|
||||
int length = (int) Math.ceil((float) f.getLength() / (n - 1));
|
||||
for(int i = 0; i < n; i++) {
|
||||
set[i] = new SegmentImpl(length);
|
||||
set[i].setLength(length);
|
||||
}
|
||||
byte[] src = f.getBuffer(), parity = set[n - 1].getBuffer();
|
||||
int offset = 0;
|
||||
for(int i = 0; i < n - 1; i++) {
|
||||
System.arraycopy(src, 0, set[i].getBuffer(), offset, length);
|
||||
for(int j = 0; j < length; j++) parity[j] ^= src[j];
|
||||
offset += length;
|
||||
}
|
||||
return set;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user