diff --git a/components/net/sf/briar/transport/ConnectionWindowImpl.java b/components/net/sf/briar/transport/ConnectionWindowImpl.java index 25910776f..fe0c1735a 100644 --- a/components/net/sf/briar/transport/ConnectionWindowImpl.java +++ b/components/net/sf/briar/transport/ConnectionWindowImpl.java @@ -31,6 +31,7 @@ class ConnectionWindowImpl implements ConnectionWindow { public void setSeen(long connectionNumber) { int offset = getOffset(connectionNumber); int mask = 0x80000000 >>> offset; + if((bitmap & mask) != 0) throw new IllegalArgumentException(); bitmap |= mask; // If the new connection number is above the centre, slide the window if(connectionNumber >= centre) { diff --git a/components/net/sf/briar/transport/TransportModule.java b/components/net/sf/briar/transport/TransportModule.java index a2a6807cb..e1dd260a0 100644 --- a/components/net/sf/briar/transport/TransportModule.java +++ b/components/net/sf/briar/transport/TransportModule.java @@ -1,7 +1,6 @@ package net.sf.briar.transport; import net.sf.briar.api.transport.ConnectionWindowFactory; -import net.sf.briar.api.transport.PacketWriter; import com.google.inject.AbstractModule; diff --git a/test/build.xml b/test/build.xml index a7b466eef..f034b76f4 100644 --- a/test/build.xml +++ b/test/build.xml @@ -32,6 +32,7 @@ + diff --git a/test/net/sf/briar/transport/ConnectionWindowImplTest.java b/test/net/sf/briar/transport/ConnectionWindowImplTest.java new file mode 100644 index 000000000..32a32ff6a --- /dev/null +++ b/test/net/sf/briar/transport/ConnectionWindowImplTest.java @@ -0,0 +1,82 @@ +package net.sf.briar.transport; + +import junit.framework.TestCase; + +import org.junit.Test; + +public class ConnectionWindowImplTest extends TestCase { + + @Test + public void testWindowSliding() { + ConnectionWindowImpl w = new ConnectionWindowImpl(0L, 0); + for(int i = 0; i < 100; i++) { + assertFalse(w.isSeen(i)); + w.setSeen(i); + assertTrue(w.isSeen(i)); + } + } + + @Test + public void testWindowJumping() { + ConnectionWindowImpl w = new ConnectionWindowImpl(0L, 0); + for(int i = 0; i < 100; i += 13) { + assertFalse(w.isSeen(i)); + w.setSeen(i); + assertTrue(w.isSeen(i)); + } + } + + @Test + public void testWindowUpperLimit() { + ConnectionWindowImpl w = new ConnectionWindowImpl(0L, 0); + // Centre is 0, highest value in window is 15 + w.setSeen(15); + // Centre is 16, highest value in window is 31 + w.setSeen(31); + try { + // Centre is 32, highest value in window is 47 + w.setSeen(48); + fail(); + } catch(IllegalArgumentException expected) {} + } + + @Test + public void testWindowLowerLimit() { + ConnectionWindowImpl w = new ConnectionWindowImpl(0L, 0); + // Centre is 0, negative values should never be allowed + try { + w.setSeen(-1); + fail(); + } catch(IllegalArgumentException expected) {} + // Slide the window + w.setSeen(15); + // Centre is 16, lowest value in window is 0 + w.setSeen(0); + // Slide the window + w.setSeen(16); + // Centre is 17, lowest value in window is 1 + w.setSeen(1); + try { + w.setSeen(0); + fail(); + } catch(IllegalArgumentException expected) {} + // Slide the window + w.setSeen(25); + // Centre is 26, lowest value in window is 10 + w.setSeen(10); + try { + w.setSeen(9); + fail(); + } catch(IllegalArgumentException expected) {} + } + + @Test + public void testCannotSetSameValueTwice() { + ConnectionWindowImpl w = new ConnectionWindowImpl(0L, 0); + w.setSeen(15); + try { + w.setSeen(15); + fail(); + } catch(IllegalArgumentException expected) {} + } +}