diff --git a/components/net/sf/briar/transport/FrameScheduler.java b/components/net/sf/briar/transport/FrameScheduler.java
deleted file mode 100644
index 1a3f02d06..000000000
--- a/components/net/sf/briar/transport/FrameScheduler.java
+++ /dev/null
@@ -1,44 +0,0 @@
-package net.sf.briar.transport;
-
-import static net.sf.briar.api.transport.TransportConstants.MAX_FRAME_LENGTH;
-
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-/**
- * A thread that calls the writeFullFrame() method of a PaddedConnectionWriter
- * at regular intervals. The interval between calls is determined by a target
- * output rate. If the underlying output stream cannot accept data at the
- * target rate, calls will be made as frequently as the output stream allows.
- */
-class FrameScheduler extends Thread {
-
- private static final Logger LOG =
- Logger.getLogger(FrameScheduler.class.getName());
-
- private final PaddedConnectionWriter writer;
- private final int millisPerFrame;
-
- FrameScheduler(PaddedConnectionWriter writer, int bytesPerSecond) {
- this.writer = writer;
- millisPerFrame = bytesPerSecond * 1000 / MAX_FRAME_LENGTH;
- }
-
- @Override
- public void run() {
- long lastCall = System.currentTimeMillis();
- try {
- while(true) {
- long now = System.currentTimeMillis();
- long nextCall = lastCall + millisPerFrame;
- if(nextCall > now) Thread.sleep(nextCall - now);
- lastCall = System.currentTimeMillis();
- if(!writer.writeFullFrame()) return;
- }
- } catch(InterruptedException e) {
- if(LOG.isLoggable(Level.INFO))
- LOG.info("Interrupted while waiting to write frame");
- Thread.currentThread().interrupt();
- }
- }
-}
\ No newline at end of file
diff --git a/components/net/sf/briar/transport/PaddedConnectionWriter.java b/components/net/sf/briar/transport/PaddedConnectionWriter.java
deleted file mode 100644
index 4bdbb5572..000000000
--- a/components/net/sf/briar/transport/PaddedConnectionWriter.java
+++ /dev/null
@@ -1,122 +0,0 @@
-package net.sf.briar.transport;
-
-import static net.sf.briar.util.ByteUtils.MAX_32_BIT_UNSIGNED;
-
-import java.io.IOException;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-import javax.crypto.Mac;
-
-import net.sf.briar.api.crypto.ErasableKey;
-import net.sf.briar.util.ByteUtils;
-
-/**
- * A ConnectionWriter that uses padding to hinder traffic analysis. A full-size
- * frame is written each time the writeFullFrame() method is called, with
- * padding inserted if necessary. Calls to the writer's write() methods will
- * block until there is space to buffer the data.
- */
-class PaddedConnectionWriter extends ConnectionWriterImpl {
-
- private static final Logger LOG =
- Logger.getLogger(PaddedConnectionWriter.class.getName());
-
- private final byte[] padding;
-
- private boolean closed = false;
- private IOException exception = null;
-
- PaddedConnectionWriter(ConnectionEncrypter encrypter, Mac mac,
- ErasableKey macKey) {
- super(encrypter, mac, macKey);
- padding = new byte[maxPayloadLength];
- }
-
- @Override
- public synchronized void close() throws IOException {
- if(exception != null) throw exception;
- if(buf.size() > 0) writeFrame(false);
- out.flush();
- out.close();
- closed = true;
- }
-
- @Override
- public void flush() throws IOException {
- // Na na na, I can't hear you
- }
-
- @Override
- public synchronized void write(int b) throws IOException {
- if(exception != null) throw exception;
- if(buf.size() == maxPayloadLength) waitForSpace();
- buf.write(b);
- }
-
- @Override
- public void write(byte[] b) throws IOException {
- write(b, 0, b.length);
- }
-
- @Override
- public synchronized void write(byte[] b, int off, int len)
- throws IOException {
- if(exception != null) throw exception;
- int available = maxPayloadLength - buf.size();
- while(available < len) {
- buf.write(b, off, available);
- off += available;
- len -= available;
- waitForSpace();
- available = maxPayloadLength;
- }
- buf.write(b, off, len);
- }
-
- /**
- * Attempts to write a full-size frame, inserting padding if necessary, and
- * returns true if the frame was written. If this method returns false it
- * should not be called again.
- */
- synchronized boolean writeFullFrame() {
- if(closed) return false;
- try {
- writeFrame(true);
- notify();
- return true;
- } catch(IOException e) {
- exception = e;
- return false;
- }
- }
-
- private synchronized void writeFrame(boolean pad) throws IOException {
- if(frame > MAX_32_BIT_UNSIGNED) throw new IllegalStateException();
- byte[] payload = buf.toByteArray();
- if(payload.length > maxPayloadLength) throw new IllegalStateException();
- int paddingLength = pad ? maxPayloadLength - payload.length : 0;
- ByteUtils.writeUint16(payload.length, header, 0);
- ByteUtils.writeUint16(paddingLength, header, 2);
- out.write(header);
- mac.update(header);
- out.write(payload);
- mac.update(payload);
- out.write(padding, 0, paddingLength);
- mac.update(padding, 0, paddingLength);
- encrypter.writeFinal(mac.doFinal());
- frame++;
- buf.reset();
- }
-
- private synchronized void waitForSpace() throws IOException {
- try {
- wait();
- } catch(InterruptedException e) {
- if(LOG.isLoggable(Level.INFO))
- LOG.info("Interrupted while waiting for space");
- Thread.currentThread().interrupt();
- }
- if(exception != null) throw exception;
- }
-}
diff --git a/test/build.xml b/test/build.xml
index a37b43c24..ddb7c805f 100644
--- a/test/build.xml
+++ b/test/build.xml
@@ -55,7 +55,6 @@
-
diff --git a/test/net/sf/briar/transport/PaddedConnectionWriterTest.java b/test/net/sf/briar/transport/PaddedConnectionWriterTest.java
deleted file mode 100644
index cb3552907..000000000
--- a/test/net/sf/briar/transport/PaddedConnectionWriterTest.java
+++ /dev/null
@@ -1,163 +0,0 @@
-package net.sf.briar.transport;
-
-import static net.sf.briar.api.transport.TransportConstants.MAX_FRAME_LENGTH;
-
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.OutputStream;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicBoolean;
-
-import net.sf.briar.api.transport.ConnectionWriter;
-import net.sf.briar.util.ByteUtils;
-
-import org.junit.Test;
-
-public class PaddedConnectionWriterTest extends TransportTest {
-
- public PaddedConnectionWriterTest() throws Exception {
- super();
- }
-
- @Test
- public void testWriteByteDoesNotBlockUntilBufferIsFull() throws Exception {
- ByteArrayOutputStream out = new ByteArrayOutputStream();
- ConnectionEncrypter e = new NullConnectionEncrypter(out, Long.MAX_VALUE);
- ConnectionWriter w = new PaddedConnectionWriter(e, mac, macKey);
- final OutputStream out1 = w.getOutputStream();
- final CountDownLatch latch = new CountDownLatch(1);
- final AtomicBoolean finished = new AtomicBoolean(false);
- final AtomicBoolean failed = new AtomicBoolean(false);
- new Thread() {
- @Override
- public void run() {
- try {
- for(int i = 0; i < maxPayloadLength; i++) out1.write(0);
- finished.set(true);
- } catch(IOException e) {
- failed.set(true);
- }
- latch.countDown();
- }
- }.start();
- // The wait should not time out
- assertTrue(latch.await(1, TimeUnit.SECONDS));
- assertTrue(finished.get());
- assertFalse(failed.get());
- // Nothing should have been written
- assertEquals(0, out.size());
- }
-
- @Test
- public void testWriteByteBlocksWhenBufferIsFull() throws Exception {
- ByteArrayOutputStream out = new ByteArrayOutputStream();
- ConnectionEncrypter e = new NullConnectionEncrypter(out, Long.MAX_VALUE);
- PaddedConnectionWriter w = new PaddedConnectionWriter(e, mac, macKey);
- final OutputStream out1 = w.getOutputStream();
- final CountDownLatch latch = new CountDownLatch(1);
- final AtomicBoolean finished = new AtomicBoolean(false);
- final AtomicBoolean failed = new AtomicBoolean(false);
- new Thread() {
- @Override
- public void run() {
- try {
- for(int i = 0; i < maxPayloadLength + 1; i++) out1.write(0);
- finished.set(true);
- } catch(IOException e) {
- failed.set(true);
- }
- latch.countDown();
- }
- }.start();
- // The wait should time out
- assertFalse(latch.await(1, TimeUnit.SECONDS));
- assertFalse(finished.get());
- assertFalse(failed.get());
- // Calling writeFullFrame() should allow the writer to proceed
- w.writeFullFrame();
- assertTrue(latch.await(1, TimeUnit.SECONDS));
- assertTrue(finished.get());
- assertFalse(failed.get());
- // A full frame should have been written
- assertEquals(MAX_FRAME_LENGTH, out.size());
- }
-
- @Test
- public void testWriteArrayDoesNotBlockUntilBufferIsFull() throws Exception {
- ByteArrayOutputStream out = new ByteArrayOutputStream();
- ConnectionEncrypter e = new NullConnectionEncrypter(out, Long.MAX_VALUE);
- ConnectionWriter w = new PaddedConnectionWriter(e, mac, macKey);
- final OutputStream out1 = w.getOutputStream();
- final CountDownLatch latch = new CountDownLatch(1);
- final AtomicBoolean finished = new AtomicBoolean(false);
- final AtomicBoolean failed = new AtomicBoolean(false);
- new Thread() {
- @Override
- public void run() {
- try {
- out1.write(new byte[maxPayloadLength]);
- finished.set(true);
- } catch(IOException e) {
- failed.set(true);
- }
- latch.countDown();
- }
- }.start();
- // The wait should not time out
- assertTrue(latch.await(1, TimeUnit.SECONDS));
- assertTrue(finished.get());
- assertFalse(failed.get());
- // Nothing should have been written
- assertEquals(0, out.size());
- }
-
- @Test
- public void testWriteArrayBlocksWhenBufferIsFull() throws Exception {
- ByteArrayOutputStream out = new ByteArrayOutputStream();
- ConnectionEncrypter e = new NullConnectionEncrypter(out, Long.MAX_VALUE);
- PaddedConnectionWriter w = new PaddedConnectionWriter(e, mac, macKey);
- final OutputStream out1 = w.getOutputStream();
- final CountDownLatch latch = new CountDownLatch(1);
- final AtomicBoolean finished = new AtomicBoolean(false);
- final AtomicBoolean failed = new AtomicBoolean(false);
- new Thread() {
- @Override
- public void run() {
- try {
- out1.write(new byte[maxPayloadLength + 1]);
- finished.set(true);
- } catch(IOException e) {
- failed.set(true);
- }
- latch.countDown();
- }
- }.start();
- // The wait should time out
- assertFalse(latch.await(1, TimeUnit.SECONDS));
- assertFalse(finished.get());
- assertFalse(failed.get());
- // Calling writeFullFrame() should allow the writer to proceed
- w.writeFullFrame();
- assertTrue(latch.await(1, TimeUnit.SECONDS));
- assertTrue(finished.get());
- assertFalse(failed.get());
- // A full frame should have been written
- assertEquals(MAX_FRAME_LENGTH, out.size());
- }
-
- @Test
- public void testWriteFullFrameInsertsPadding() throws Exception {
- ByteArrayOutputStream out = new ByteArrayOutputStream();
- ConnectionEncrypter e = new NullConnectionEncrypter(out, Long.MAX_VALUE);
- PaddedConnectionWriter w = new PaddedConnectionWriter(e, mac, macKey);
- w.getOutputStream().write(0);
- w.writeFullFrame();
- // A full frame should have been written
- assertEquals(MAX_FRAME_LENGTH, out.size());
- // The frame should have a payload length of 1 and padding for the rest
- byte[] frame = out.toByteArray();
- assertEquals(1, ByteUtils.readUint16(frame, 0)); // Payload length
- assertEquals(maxPayloadLength - 1, ByteUtils.readUint16(frame, 2));
- }
-}