[tor-commits] [obfs4/master] Improve the performance of the obfs4 handshake test.

yawning at torproject.org yawning at torproject.org
Fri Oct 3 18:35:44 UTC 2014


commit 4932821bda4c19e51581dce295166d801fd138da
Author: Yawning Angel <yawning at torproject.org>
Date:   Fri Oct 3 18:27:38 2014 +0000

    Improve the performance of the obfs4 handshake test.
    
    Exhaustively testing padding combinations is really slow, and was
    causing timeouts during the Debian ARM package build process.  Attempt
    to improve the situation by:
    
     * Reusing the client and server keypair for all of the tests, to cut
       runtime down by  ~50%.
     * Splitting the client side and server side tests up, as it appears
       the timeout is per-test case.
    
    If this doesn't fix things, the next thing to try would be to reduce
    the actual number of padding lengths tested, but that is a last resort
    at the moment.
---
 ChangeLog                               |    3 ++
 transports/obfs4/handshake_ntor_test.go |   82 ++++++++++++++++++++-----------
 2 files changed, 57 insertions(+), 28 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 19b5f7f..e13e753 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,6 @@
+Changes in version 0.0.4 - UNRELEASED
+ - Improve the runtime performance of the obfs4 handshake tests.
+
 Changes in version 0.0.3 - 2014-10-01
  - Change the obfs4 bridge line format to use a "cert" argument instead of the
    previous "node-id" and "public-key" arguments.  The "cert" consists of the
diff --git a/transports/obfs4/handshake_ntor_test.go b/transports/obfs4/handshake_ntor_test.go
index fa03420..1903986 100644
--- a/transports/obfs4/handshake_ntor_test.go
+++ b/transports/obfs4/handshake_ntor_test.go
@@ -35,19 +35,23 @@ import (
 	"git.torproject.org/pluggable-transports/obfs4.git/common/replayfilter"
 )
 
-func TestHandshakeNtor(t *testing.T) {
-	// Generate the server node id and id keypair.
+func TestHandshakeNtorClient(t *testing.T) {
+	// Generate the server node id and id keypair, and ephemeral session keys.
 	nodeID, _ := ntor.NewNodeID([]byte("\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13"))
 	idKeypair, _ := ntor.NewKeypair(false)
 	serverFilter, _ := replayfilter.New(replayTTL)
+	clientKeypair, err := ntor.NewKeypair(true)
+	if err != nil {
+		t.Fatalf("client: ntor.NewKeypair failed: %s", err)
+	}
+	serverKeypair, err := ntor.NewKeypair(true)
+	if err != nil {
+		t.Fatalf("server: ntor.NewKeypair failed: %s", err)
+	}
 
 	// Test client handshake padding.
 	for l := clientMinPadLength; l <= clientMaxPadLength; l++ {
 		// Generate the client state and override the pad length.
-		clientKeypair, err := ntor.NewKeypair(true)
-		if err != nil {
-			t.Fatalf("[%d:0] ntor.NewKeypair failed: %s", l, err)
-		}
 		clientHs := newClientHandshake(nodeID, idKeypair.Public(), clientKeypair)
 		clientHs.padLen = l
 
@@ -67,10 +71,6 @@ func TestHandshakeNtor(t *testing.T) {
 		}
 
 		// Generate the server state and override the pad length.
-		serverKeypair, err := ntor.NewKeypair(true)
-		if err != nil {
-			t.Fatalf("[%d:0] ntor.NewKeypair failed: %s", l, err)
-		}
 		serverHs := newServerHandshake(nodeID, idKeypair, serverKeypair)
 		serverHs.padLen = serverMinPadLength
 
@@ -102,13 +102,52 @@ func TestHandshakeNtor(t *testing.T) {
 		}
 	}
 
+	// Test oversized client padding.
+	clientHs := newClientHandshake(nodeID, idKeypair.Public(), clientKeypair)
+	if err != nil {
+		t.Fatalf("newClientHandshake failed: %s", err)
+	}
+	clientHs.padLen = clientMaxPadLength + 1
+	clientBlob, err := clientHs.generateHandshake()
+	if err != nil {
+		t.Fatalf("clientHandshake.generateHandshake() (forced oversize) failed: %s", err)
+	}
+	serverHs := newServerHandshake(nodeID, idKeypair, serverKeypair)
+	_, err = serverHs.parseClientHandshake(serverFilter, clientBlob)
+	if err == nil {
+		t.Fatalf("serverHandshake.parseClientHandshake() succeded (oversized)")
+	}
+
+	// Test undersized client padding.
+	clientHs.padLen = clientMinPadLength - 1
+	clientBlob, err = clientHs.generateHandshake()
+	if err != nil {
+		t.Fatalf("clientHandshake.generateHandshake() (forced undersize) failed: %s", err)
+	}
+	serverHs = newServerHandshake(nodeID, idKeypair, serverKeypair)
+	_, err = serverHs.parseClientHandshake(serverFilter, clientBlob)
+	if err == nil {
+		t.Fatalf("serverHandshake.parseClientHandshake() succeded (undersized)")
+	}
+}
+
+func TestHandshakeNtorServer(t *testing.T) {
+	// Generate the server node id and id keypair, and ephemeral session keys.
+	nodeID, _ := ntor.NewNodeID([]byte("\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13"))
+	idKeypair, _ := ntor.NewKeypair(false)
+	serverFilter, _ := replayfilter.New(replayTTL)
+	clientKeypair, err := ntor.NewKeypair(true)
+	if err != nil {
+		t.Fatalf("client: ntor.NewKeypair failed: %s", err)
+	}
+	serverKeypair, err := ntor.NewKeypair(true)
+	if err != nil {
+		t.Fatalf("server: ntor.NewKeypair failed: %s", err)
+	}
+
 	// Test server handshake padding.
 	for l := serverMinPadLength; l <= serverMaxPadLength+inlineSeedFrameLength; l++ {
 		// Generate the client state and override the pad length.
-		clientKeypair, err := ntor.NewKeypair(true)
-		if err != nil {
-			t.Fatalf("[%d:0] ntor.NewKeypair failed: %s", l, err)
-		}
 		clientHs := newClientHandshake(nodeID, idKeypair.Public(), clientKeypair)
 		clientHs.padLen = clientMinPadLength
 
@@ -122,10 +161,6 @@ func TestHandshakeNtor(t *testing.T) {
 		}
 
 		// Generate the server state and override the pad length.
-		serverKeypair, err := ntor.NewKeypair(true)
-		if err != nil {
-			t.Fatalf("[%d:0] ntor.NewKeypair failed: %s", l, err)
-		}
 		serverHs := newServerHandshake(nodeID, idKeypair, serverKeypair)
 		serverHs.padLen = l
 
@@ -157,24 +192,15 @@ func TestHandshakeNtor(t *testing.T) {
 	}
 
 	// Test oversized client padding.
-	clientKeypair, err := ntor.NewKeypair(true)
-	if err != nil {
-		t.Fatalf("ntor.NewKeypair failed: %s", err)
-	}
 	clientHs := newClientHandshake(nodeID, idKeypair.Public(), clientKeypair)
 	if err != nil {
 		t.Fatalf("newClientHandshake failed: %s", err)
 	}
-
 	clientHs.padLen = clientMaxPadLength + 1
 	clientBlob, err := clientHs.generateHandshake()
 	if err != nil {
 		t.Fatalf("clientHandshake.generateHandshake() (forced oversize) failed: %s", err)
 	}
-	serverKeypair, err := ntor.NewKeypair(true)
-	if err != nil {
-		t.Fatalf("ntor.NewKeypair failed: %s", err)
-	}
 	serverHs := newServerHandshake(nodeID, idKeypair, serverKeypair)
 	_, err = serverHs.parseClientHandshake(serverFilter, clientBlob)
 	if err == nil {
@@ -197,7 +223,7 @@ func TestHandshakeNtor(t *testing.T) {
 	//
 	// NB: serverMaxPadLength isn't the real maxPadLength that triggers client
 	// rejection, because the implementation is written with the asusmption
-	// that/ the PRNG_SEED is also inlined with the response.  Thus the client
+	// that the PRNG_SEED is also inlined with the response.  Thus the client
 	// actually accepts longer padding.  The server handshake test and this
 	// test adjust around that.
 	clientHs.padLen = clientMinPadLength



More information about the tor-commits mailing list