[tor-commits] [obfs-flash/master] Add a function to encode a ServerTransportOptions string.

dcf at torproject.org dcf at torproject.org
Tue Dec 17 00:50:35 UTC 2013


commit cf6b22666c1b4e47a3ac8d8cfce1f2fed5206e8a
Author: David Fifield <david at bamsoftware.com>
Date:   Mon Dec 16 16:26:04 2013 -0800

    Add a function to encode a ServerTransportOptions string.
---
 obfs-flash-server.go |   28 ++++++++++++++++++++++++++++
 pt_test.go           |   39 +++++++++++++++++++++++++++++++++++++++
 2 files changed, 67 insertions(+)

diff --git a/obfs-flash-server.go b/obfs-flash-server.go
index d407547..f6cc7af 100644
--- a/obfs-flash-server.go
+++ b/obfs-flash-server.go
@@ -13,6 +13,7 @@ import (
 	"strings"
 	"sync"
 	"syscall"
+	"sort"
 	"time"
 )
 
@@ -148,6 +149,30 @@ func findBindAddr(r io.Reader, methodName string) (*net.TCPAddr, error) {
 	return nil, errors.New(fmt.Sprintf("no SMETHOD %s found before SMETHODS DONE", methodName))
 }
 
+// Escape a string for a ServerTransportOptions serialization.
+func escape(s string) string {
+	repl := strings.NewReplacer(":", "\\:", ";", "\\;", "=", "\\=", "\\", "\\\\")
+	return repl.Replace(s)
+}
+
+func encodeServerTransportOptions(methodName string, opts pt.Args) string {
+	if opts == nil {
+		return ""
+	}
+	keys := make([]string, 0, len(opts))
+	for key, _ := range opts {
+		keys = append(keys, key)
+	}
+	sort.Strings(keys)
+	parts := make([]string, 0, len(keys))
+	for _, key := range keys {
+		for _, value := range opts[key] {
+			parts = append(parts, escape(methodName) + ":" + escape(key) + "=" + escape(value))
+		}
+	}
+	return strings.Join(parts, ";")
+}
+
 // Represents a server transport plugin configuration like:
 // 	ServerTransportPlugin MethodName exec Command
 type ServerTransportPlugin struct {
@@ -365,6 +390,8 @@ func startChain(methodName string, bindaddr *net.TCPAddr, plugins []ServerTransp
 type Configuration struct {
 	// Map from method names to command strings.
 	Transports map[string][]string
+	// Map from method names to ServerTransportOptions.
+	Options map[string]pt.Args
 	// Map from tor-friendly names like "obfs3_websocket" to systematic
 	// names like "obfs3|websocket".
 	Aliases map[string]string
@@ -409,6 +436,7 @@ func getConfiguration() (conf *Configuration) {
 	conf = new(Configuration)
 	conf.Transports = make(map[string][]string)
 	conf.Aliases = make(map[string]string)
+	conf.Options = make(map[string]pt.Args)
 	conf.Transports["obfs3"] = []string{"obfsproxy", "managed"}
 	conf.Transports["websocket"] = []string{"websocket-server"}
 	conf.Aliases["obfs3_websocket"] = "obfs3|websocket"
diff --git a/pt_test.go b/pt_test.go
new file mode 100644
index 0000000..35d3aab
--- /dev/null
+++ b/pt_test.go
@@ -0,0 +1,39 @@
+package main
+
+import "testing"
+
+import "git.torproject.org/pluggable-transports/goptlib.git"
+
+func TestEncodeServerTransportOptions(t *testing.T) {
+	tests := [...]struct {
+		methodName string
+		opts       pt.Args
+		expected   string
+	}{
+		{
+			"foo",
+			pt.Args{},
+			"",
+		},
+		{
+			"foo",
+			pt.Args{
+				"key": []string{"value1", "value2"},
+				"something": []string{"value1", "value2"},
+			},
+			"foo:key=value1;foo:key=value2;foo:something=value1;foo:something=value2",
+		},
+		{
+			"m:m",
+			pt.Args{"k;k": []string{"v=v", "b\\b"}},
+			"m\\:m:k\\;k=v\\=v;m\\:m:k\\;k=b\\\\b",
+		},
+	}
+
+	for _, test := range tests {
+		output := encodeServerTransportOptions(test.methodName, test.opts)
+		if output != test.expected {
+			t.Errorf("%q %q → %q (expected %q)", test.methodName, test.opts, output, test.expected)
+		}
+	}
+}





More information about the tor-commits mailing list