mirror of
https://gitlab.com/yawning/obfs4.git
synced 2024-11-15 12:12:53 +00:00
fd4e3c7c74
This is done by maintaining a map keyed off the SipHash-2-4 digest of the MAC_C component of the handshake. Collisions, while possible are unlikely in the extreme and are thus treated as replays. In concept this is fairly similar to the ScrambleSuit `replay.py` code, with a few modifications: * There is a upper bound on how large the replay filter can grow. Currently this is set to 102400 entries, though it is unlikely that this limit will be hit. * A doubly linked list is also maintained parallel to the map, so the filter compaction process does not need to iterate over the entire filter.
93 lines
3.1 KiB
Go
93 lines
3.1 KiB
Go
/*
|
|
* Copyright (c) 2014, Yawning Angel <yawning at torproject dot org>
|
|
* All rights reserved.
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions are met:
|
|
*
|
|
* * Redistributions of source code must retain the above copyright notice,
|
|
* this list of conditions and the following disclaimer.
|
|
*
|
|
* * Redistributions in binary form must reproduce the above copyright notice,
|
|
* this list of conditions and the following disclaimer in the documentation
|
|
* and/or other materials provided with the distribution.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
|
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
* POSSIBILITY OF SUCH DAMAGE.
|
|
*/
|
|
|
|
package obfs4
|
|
|
|
import (
|
|
"testing"
|
|
)
|
|
|
|
func TestReplayFilter(t *testing.T) {
|
|
f, err := newReplayFilter()
|
|
if err != nil {
|
|
t.Fatal("newReplayFilter failed:", err)
|
|
}
|
|
|
|
buf := []byte("This is a test of the Emergency Broadcast System.")
|
|
var now int64 = 3600
|
|
|
|
// testAndSet into empty filter, returns false (not present).
|
|
set := f.testAndSet(now, buf)
|
|
if set {
|
|
t.Fatal("testAndSet empty filter returned true")
|
|
}
|
|
|
|
// testAndSet into filter containing entry, should return true(present).
|
|
set = f.testAndSet(now, buf)
|
|
if !set {
|
|
t.Fatal("testAndSet populated filter (replayed) returned false")
|
|
}
|
|
|
|
buf2 := []byte("This concludes this test of the Emergency Broadcast System.")
|
|
now += 3600 * 2
|
|
|
|
// testAndSet with time advanced.
|
|
set = f.testAndSet(now, buf2)
|
|
if set {
|
|
t.Fatal("testAndSet populated filter, 2nd entry returned true")
|
|
}
|
|
set = f.testAndSet(now, buf2)
|
|
if !set {
|
|
t.Fatal("testAndSet populated filter, 2nd entry (replayed) returned false")
|
|
}
|
|
|
|
// Ensure that the first entry has been removed by compact.
|
|
set = f.testAndSet(now, buf)
|
|
if set {
|
|
t.Fatal("testAndSet populated filter, compact check returned true")
|
|
}
|
|
|
|
// Ensure that the filter gets reaped if the clock jumps backwards.
|
|
now = 0
|
|
set = f.testAndSet(now, buf)
|
|
if set {
|
|
t.Fatal("testAndSet populated filter, backward time jump returned true")
|
|
}
|
|
if len(f.filter) != 1 {
|
|
t.Fatal("filter map has a unexpected number of entries:", len(f.filter))
|
|
}
|
|
if f.fifo.Len() != 1 {
|
|
t.Fatal("filter fifo has a unexpected number of entries:", f.fifo.Len())
|
|
}
|
|
|
|
// Ensure that the entry is properly added after reaping.
|
|
set = f.testAndSet(now, buf)
|
|
if !set {
|
|
t.Fatal("testAndSet populated filter, post-backward clock jump (replayed) returned false")
|
|
}
|
|
}
|