commit cf6b22666c1b4e47a3ac8d8cfce1f2fed5206e8a Author: David Fifield david@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) + } + } +}
tor-commits@lists.torproject.org