[tor-commits] [websocket/master] Add dummy client example.
dcf at torproject.org
dcf at torproject.org
Sun Oct 27 00:20:48 UTC 2013
commit 808ac4a57123a3dbe8fe1dfebd2b2ec599219dd5
Author: David Fifield <david at 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:
+ }
+ }
+}
More information about the tor-commits
mailing list