From 1886609befb14d8f34320afab04277b031655c72 Mon Sep 17 00:00:00 2001
From: akwizgran <akwizgran@users.sourceforge.net>
Date: Thu, 8 Dec 2011 14:35:52 +0000
Subject: [PATCH] Removed frame padding code (soon to be obsolete).

---
 .../sf/briar/transport/FrameScheduler.java    |  44 -----
 .../transport/PaddedConnectionWriter.java     | 122 -------------
 test/build.xml                                |   1 -
 .../transport/PaddedConnectionWriterTest.java | 163 ------------------
 4 files changed, 330 deletions(-)
 delete mode 100644 components/net/sf/briar/transport/FrameScheduler.java
 delete mode 100644 components/net/sf/briar/transport/PaddedConnectionWriter.java
 delete mode 100644 test/net/sf/briar/transport/PaddedConnectionWriterTest.java

diff --git a/components/net/sf/briar/transport/FrameScheduler.java b/components/net/sf/briar/transport/FrameScheduler.java
deleted file mode 100644
index 1a3f02d065..0000000000
--- 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 4bdbb5572e..0000000000
--- 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 a37b43c243..ddb7c805fb 100644
--- a/test/build.xml
+++ b/test/build.xml
@@ -55,7 +55,6 @@
 			<test name='net.sf.briar.transport.ConnectionWriterImplTest'/>
 			<test name='net.sf.briar.transport.ConnectionWriterTest'/>
 			<test name='net.sf.briar.transport.FrameReadWriteTest'/>
-			<test name='net.sf.briar.transport.PaddedConnectionWriterTest'/>
 			<test name='net.sf.briar.transport.batch.BatchConnectionReadWriteTest'/>
 			<test name='net.sf.briar.util.ByteUtilsTest'/>
 			<test name='net.sf.briar.util.FileUtilsTest'/>
diff --git a/test/net/sf/briar/transport/PaddedConnectionWriterTest.java b/test/net/sf/briar/transport/PaddedConnectionWriterTest.java
deleted file mode 100644
index cb35529079..0000000000
--- 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));
-	}
-}
-- 
GitLab