[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