gost_software/pkg/goptlib-v1.3.0/examples/dummy-server/dummy-server.go

118 lines
2.1 KiB
Go

// 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 "git.torproject.org/pluggable-transports/goptlib.git"
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)
}
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()
}
}