commit 808ac4a57123a3dbe8fe1dfebd2b2ec599219dd5 Author: David Fifield david@bamsoftware.com Date: Sat Oct 26 16:31:09 2013 -0700
Add dummy client example. --- src/pt/.gitignore | 1 + src/pt/examples/dummy-client/dummy-client.go | 127 ++++++++++++++++++++++++++ 2 files changed, 128 insertions(+)
diff --git a/src/pt/.gitignore b/src/pt/.gitignore new file mode 100644 index 0000000..bdcad5a --- /dev/null +++ b/src/pt/.gitignore @@ -0,0 +1 @@ +/examples/dummy-client diff --git a/src/pt/examples/dummy-client/dummy-client.go b/src/pt/examples/dummy-client/dummy-client.go new file mode 100644 index 0000000..7b69104 --- /dev/null +++ b/src/pt/examples/dummy-client/dummy-client.go @@ -0,0 +1,127 @@ +// Usage (in torrc): +// UseBridges 1 +// Bridge dummy X.X.X.X:YYYY +// ClientTransportPlugin dummy exec dummy-client +// Because this transport doesn't do anything to the traffic, you can use any +// ordinary relay's ORPort in the Bridge line. + +package main + +import ( + "io" + "net" + "os" + "os/signal" + "sync" + "syscall" +) + +import "git.torproject.org/pluggable-transports/websocket.git/src/pt" +import "git.torproject.org/pluggable-transports/websocket.git/src/pt/socks" + +// When a connection handler starts, +1 is written to this channel; when it +// ends, -1 is written. +var handlerChan = make(chan int) + +func copyLoop(a, b net.Conn) { + var wg sync.WaitGroup + wg.Add(2) + + go func() { + io.Copy(b, a) + wg.Done() + }() + go func() { + io.Copy(a, b) + wg.Done() + }() + + wg.Wait() +} + +func handleConnection(local net.Conn) error { + defer local.Close() + + handlerChan <- 1 + defer func() { + handlerChan <- -1 + }() + + var remote net.Conn + err := socks.AwaitSocks4aConnect(local.(*net.TCPConn), func(dest string) (*net.TCPAddr, error) { + var err error + // set remote in outer function environment + remote, err = net.Dial("tcp", dest) + if err != nil { + return nil, err + } + return remote.RemoteAddr().(*net.TCPAddr), nil + }) + if err != nil { + return err + } + defer remote.Close() + copyLoop(local, remote) + + return nil +} + +func acceptLoop(ln net.Listener) error { + for { + conn, err := ln.Accept() + if err != nil { + return err + } + go handleConnection(conn) + } + return nil +} + +func startListener(addr string) (net.Listener, error) { + ln, err := net.Listen("tcp", addr) + if err != nil { + return nil, err + } + go acceptLoop(ln) + return ln, nil +} + +func main() { + pt.ClientSetup([]string{"dummy"}) + ln, err := startListener("127.0.0.1:0") + if err != nil { + pt.CmethodError("dummy", err.Error()) + } + pt.Cmethod("dummy", "socks4", ln.Addr()) + pt.CmethodsDone() + + var numHandlers int = 0 + var sig os.Signal + sigChan := make(chan os.Signal, 1) + signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM) + + // wait for first signal + sig = nil + for sig == nil { + select { + case n := <-handlerChan: + numHandlers += n + case sig = <-sigChan: + } + } + ln.Close() + + if sig == syscall.SIGTERM { + return + } + + // wait for second signal or no more handlers + sig = nil + for sig == nil && numHandlers != 0 { + select { + case n := <-handlerChan: + numHandlers += n + case sig = <-sigChan: + } + } +}
tor-commits@lists.torproject.org