1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119
|
// Dummy no-op pluggable transport server. Works only as a managed proxy.
//
// Usage (in torrc):
// BridgeRelay 1
// ORPort 9001
// ExtORPort 6669
// ServerTransportPlugin dummy exec dummy-server
//
// Because the dummy transport doesn't do anything to the traffic, you can
// connect to it with any ordinary Tor client; you don't have to use
// dummy-client.
package main
import (
"io"
"io/ioutil"
"net"
"os"
"os/signal"
"sync"
"syscall"
)
import "gitlab.torproject.org/tpo/anti-censorship/pluggable-transports/goptlib"
var ptInfo pt.ServerInfo
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 handler(conn net.Conn) error {
defer conn.Close()
or, err := pt.DialOr(&ptInfo, conn.RemoteAddr().String(), "dummy")
if err != nil {
return err
}
defer or.Close()
copyLoop(conn, or)
return nil
}
func acceptLoop(ln net.Listener) error {
defer ln.Close()
for {
conn, err := ln.Accept()
if err != nil {
if e, ok := err.(net.Error); ok && e.Temporary() {
continue
}
return err
}
go handler(conn)
}
}
func main() {
var err error
ptInfo, err = pt.ServerSetup(nil)
if err != nil {
os.Exit(1)
}
pt.ReportVersion("dummy-server", "0.1")
listeners := make([]net.Listener, 0)
for _, bindaddr := range ptInfo.Bindaddrs {
switch bindaddr.MethodName {
case "dummy":
ln, err := net.ListenTCP("tcp", bindaddr.Addr)
if err != nil {
pt.SmethodError(bindaddr.MethodName, err.Error())
break
}
go acceptLoop(ln)
pt.Smethod(bindaddr.MethodName, ln.Addr())
listeners = append(listeners, ln)
default:
pt.SmethodError(bindaddr.MethodName, "no such method")
}
}
pt.SmethodsDone()
sigChan := make(chan os.Signal, 1)
signal.Notify(sigChan, syscall.SIGTERM)
if os.Getenv("TOR_PT_EXIT_ON_STDIN_CLOSE") == "1" {
// This environment variable means we should treat EOF on stdin
// just like SIGTERM: https://bugs.torproject.org/15435.
go func() {
io.Copy(ioutil.Discard, os.Stdin)
sigChan <- syscall.SIGTERM
}()
}
// wait for a signal
<-sigChan
// signal received, shut down
for _, ln := range listeners {
ln.Close()
}
}
|