summaryrefslogtreecommitdiff
path: root/obfs4-client/obfs4-client.go
diff options
context:
space:
mode:
Diffstat (limited to 'obfs4-client/obfs4-client.go')
-rw-r--r--obfs4-client/obfs4-client.go183
1 files changed, 0 insertions, 183 deletions
diff --git a/obfs4-client/obfs4-client.go b/obfs4-client/obfs4-client.go
deleted file mode 100644
index 077fb85..0000000
--- a/obfs4-client/obfs4-client.go
+++ /dev/null
@@ -1,183 +0,0 @@
-/*
- * Copyright (c) 2014, Yawning Angel <yawning at torproject dot org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * * Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- *
- * * Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- *
- * This file is based off goptlib's dummy-client.go file.
- */
-
-// obfs4 pluggable transport client. Works only as a managed proxy.
-//
-// Usage (in torrc):
-// UseBridges 1
-// Bridge obfs4 X.X.X.X:YYYY public-key=<Base64 Bridge public key> node-id=<Base64 Node ID>
-// ClientTransportPlugin obfs4 exec obfs4-client
-//
-// Becuase the pluggable transport requires arguments, using obfs4-client
-// requires tor 0.2.5.x.
-package main
-
-import (
- "io"
- "net"
- "os"
- "os/signal"
- "sync"
- "syscall"
-
- "github.com/yawning/obfs4"
-)
-
-import "git.torproject.org/pluggable-transports/goptlib.git"
-
-var ptInfo pt.ClientInfo
-
-// 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)
-
- // TODO: Log errors.
- go func() {
- io.Copy(b, a)
- wg.Done()
- }()
- go func() {
- io.Copy(a, b)
- wg.Done()
- }()
-
- wg.Wait()
-}
-
-func handler(conn *pt.SocksConn) error {
- // Extract the peer's node ID and public key.
- nodeID, ok := conn.Req.Args.Get("node-id")
- if !ok {
- // TODO: Log something here.
- conn.Reject()
- }
- publicKey, ok := conn.Req.Args.Get("public-key")
- if !ok {
- // TODO: Log something here.
- conn.Reject()
- }
-
- handlerChan <- 1
- defer func() {
- handlerChan <- -1
- }()
-
- defer conn.Close()
- remote, err := obfs4.Dial("tcp", conn.Req.Target, nodeID, publicKey)
- if err != nil {
- conn.Reject()
- return err
- }
- defer remote.Close()
- err = conn.Grant(remote.RemoteAddr().(*net.TCPAddr))
- if err != nil {
- return err
- }
-
- copyLoop(conn, remote)
-
- return nil
-}
-
-func acceptLoop(ln *pt.SocksListener) error {
- defer ln.Close()
- for {
- conn, err := ln.AcceptSocks()
- if err != nil {
- if e, ok := err.(net.Error); ok && !e.Temporary() {
- return err
- }
- continue
- }
- go handler(conn)
- }
-}
-
-func main() {
- var err error
-
- ptInfo, err = pt.ClientSetup([]string{"obfs4"})
- if err != nil {
- os.Exit(1)
- }
-
- listeners := make([]net.Listener, 0)
- for _, methodName := range ptInfo.MethodNames {
- switch methodName {
- case "obfs4":
- ln, err := pt.ListenSocks("tcp", "127.0.0.1:0")
- if err != nil {
- pt.CmethodError(methodName, err.Error())
- break
- }
- go acceptLoop(ln)
- pt.Cmethod(methodName, ln.Version(), ln.Addr())
- listeners = append(listeners, ln)
- default:
- pt.CmethodError(methodName, "no such method")
- }
- }
- 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:
- }
- }
- for _, ln := range listeners {
- 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:
- }
- }
-}