commit 1854f66a59942347b5d3c66bbe2d6260d37bb075 Author: David Fifield david@bamsoftware.com Date: Sun Nov 25 19:04:01 2012 -0800
Add server pluggable transports functions. --- websocket-transport/pt.go | 116 +++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 116 insertions(+), 0 deletions(-)
diff --git a/websocket-transport/pt.go b/websocket-transport/pt.go index 686cc76..e63dd6a 100644 --- a/websocket-transport/pt.go +++ b/websocket-transport/pt.go @@ -110,3 +110,119 @@ func ptClientSetup(methodNames []string) []string {
return methods } + +func ptSmethodError(methodName, msg string) { + ptLine("SMETHOD-ERROR", methodName, msg) + os.Exit(1) +} + +func ptSmethod(name string, addr net.Addr) { + ptLine("SMETHOD", name, addr.String()) +} + +func ptSmethodsDone() { + ptLine("SMETHODS", "DONE") +} + +func resolveBindAddr(bindAddr string) (*net.TCPAddr, error) { + addr, err := net.ResolveTCPAddr("tcp", bindAddr) + if err == nil { + return addr, nil + } + // Before the fixing of bug #7011, tor doesn't put brackets around IPv6 + // addresses. Split after the last colon, assuming it is a port + // separator, and try adding the brackets. + parts := strings.Split(bindAddr, ":") + if len(parts) <= 2 { + return nil, err + } + bindAddr = "[" + strings.Join(parts[:len(parts)-1], ":") + "]:" + parts[len(parts)-1] + return net.ResolveTCPAddr("tcp", bindAddr) +} + +type ptBindAddr struct { + MethodName string + Addr *net.TCPAddr +} + +func filterBindAddrs(addrs []ptBindAddr, supported []string) []ptBindAddr { + var result []ptBindAddr + + for _, ba := range addrs { + for _, methodName := range supported { + if ba.MethodName == methodName { + result = append(result, ba) + break + } + } + } + + return result +} + +// Return a map from method names to bind addresses. The map is the contents of +// TOR_PT_SERVER_BINDADDR, with keys filtered by TOR_PT_SERVER_TRANSPORTS, and +// further filtered by methods that we know. +func ptGetServerBindAddrs(supported []string) []ptBindAddr { + var result []ptBindAddr + + // Get the list of all requested bindaddrs. + var serverBindAddr = getenvRequired("TOR_PT_SERVER_BINDADDR") + for _, spec := range strings.Split(serverBindAddr, ",") { + var bindAddr ptBindAddr + + parts := strings.SplitN(spec, "-", 2) + if len(parts) != 2 { + ptEnvError(fmt.Sprintf("TOR_PT_SERVER_BINDADDR: %q: doesn't contain "-"", spec)) + } + bindAddr.MethodName = parts[0] + addr, err := resolveBindAddr(parts[1]) + if err != nil { + ptEnvError(fmt.Sprintf("TOR_PT_SERVER_BINDADDR: %q: %s", spec, err.Error())) + } + bindAddr.Addr = addr + result = append(result, bindAddr) + } + + // Filter by TOR_PT_SERVER_TRANSPORTS. + serverTransports := getenvRequired("TOR_PT_SERVER_TRANSPORTS") + if serverTransports != "*" { + result = filterBindAddrs(result, strings.Split(serverTransports, ",")) + } + + // Finally filter by what we understand. + result = filterBindAddrs(result, supported) + + return result +} + +type ptServerInfo struct { + BindAddrs []ptBindAddr + OrAddr *net.TCPAddr +} + +func ptServerSetup(methodNames []string) ptServerInfo { + var info ptServerInfo + var err error + + ver := ptGetManagedTransportVer() + if ver == "" { + ptVersionError("no-version") + } else { + ptLine("VERSION", ver) + } + + var orPort = getenvRequired("TOR_PT_ORPORT") + info.OrAddr, err = net.ResolveTCPAddr("tcp", orPort) + if err != nil { + ptEnvError(fmt.Sprintf("cannot resolve TOR_PT_ORPORT %q: %s", orPort, err.Error())) + } + + info.BindAddrs = ptGetServerBindAddrs(methodNames) + if len(info.BindAddrs) == 0 { + ptSmethodsDone() + os.Exit(1) + } + + return info +}
tor-commits@lists.torproject.org