summaryrefslogtreecommitdiff
path: root/obfs4proxy/obfs4proxy.go
diff options
context:
space:
mode:
Diffstat (limited to 'obfs4proxy/obfs4proxy.go')
-rw-r--r--obfs4proxy/obfs4proxy.go51
1 files changed, 26 insertions, 25 deletions
diff --git a/obfs4proxy/obfs4proxy.go b/obfs4proxy/obfs4proxy.go
index 608dd55..33fbce7 100644
--- a/obfs4proxy/obfs4proxy.go
+++ b/obfs4proxy/obfs4proxy.go
@@ -45,6 +45,7 @@ import (
"git.torproject.org/pluggable-transports/goptlib.git"
"git.torproject.org/pluggable-transports/obfs4.git/common/log"
+ "git.torproject.org/pluggable-transports/obfs4.git/common/socks5"
"git.torproject.org/pluggable-transports/obfs4.git/transports"
"git.torproject.org/pluggable-transports/obfs4.git/transports/base"
)
@@ -58,10 +59,6 @@ const (
var stateDir string
var termMon *termMonitor
-// DialFn is a function pointer to a function that matches the net.Dialer.Dial
-// interface.
-type DialFn func(string, string) (net.Conn, error)
-
func clientSetup() (launched bool, listeners []net.Listener) {
ptClientInfo, err := pt.ClientSetup(transports.Transports())
if err != nil {
@@ -89,14 +86,14 @@ func clientSetup() (launched bool, listeners []net.Listener) {
continue
}
- ln, err := pt.ListenSocks("tcp", socksAddr)
+ ln, err := net.Listen("tcp", socksAddr)
if err != nil {
pt.CmethodError(name, err.Error())
continue
}
go clientAcceptLoop(f, ln, ptClientProxy)
- pt.Cmethod(name, ln.Version(), ln.Addr())
+ pt.Cmethod(name, socks5.Version(), ln.Addr())
log.Infof("%s - registered listener: %s", name, ln.Addr())
@@ -108,10 +105,10 @@ func clientSetup() (launched bool, listeners []net.Listener) {
return
}
-func clientAcceptLoop(f base.ClientFactory, ln *pt.SocksListener, proxyURI *url.URL) error {
+func clientAcceptLoop(f base.ClientFactory, ln net.Listener, proxyURI *url.URL) error {
defer ln.Close()
for {
- conn, err := ln.AcceptSocks()
+ conn, err := ln.Accept()
if err != nil {
if e, ok := err.(net.Error); ok && !e.Temporary() {
return err
@@ -122,42 +119,46 @@ func clientAcceptLoop(f base.ClientFactory, ln *pt.SocksListener, proxyURI *url.
}
}
-func clientHandler(f base.ClientFactory, conn *pt.SocksConn, proxyURI *url.URL) {
+func clientHandler(f base.ClientFactory, conn net.Conn, proxyURI *url.URL) {
defer conn.Close()
termMon.onHandlerStart()
defer termMon.onHandlerFinish()
name := f.Transport().Name()
- addrStr := log.ElideAddr(conn.Req.Target)
- log.Infof("%s(%s) - new connection", name, addrStr)
+
+ // Read the client's SOCKS handshake.
+ socksReq, err := socks5.Handshake(conn)
+ if err != nil {
+ log.Errorf("%s - client failed socks handshake: %s", name, err)
+ return
+ }
+ addrStr := log.ElideAddr(socksReq.Target)
// Deal with arguments.
- args, err := f.ParseArgs(&conn.Req.Args)
+ args, err := f.ParseArgs(&socksReq.Args)
if err != nil {
log.Errorf("%s(%s) - invalid arguments: %s", name, addrStr, err)
- conn.Reject()
+ socksReq.Reply(socks5.ReplyGeneralFailure)
return
}
// Obtain the proxy dialer if any, and create the outgoing TCP connection.
- var dialFn DialFn
- if proxyURI == nil {
- dialFn = proxy.Direct.Dial
- } else {
- // This is unlikely to happen as the proxy protocol is verified during
- // the configuration phase.
+ dialFn := proxy.Direct.Dial
+ if proxyURI != nil {
dialer, err := proxy.FromURL(proxyURI, proxy.Direct)
if err != nil {
+ // This should basically never happen, since config protocol
+ // verifies this.
log.Errorf("%s(%s) - failed to obtain proxy dialer: %s", name, addrStr, log.ElideError(err))
- conn.Reject()
+ socksReq.Reply(socks5.ReplyGeneralFailure)
return
}
dialFn = dialer.Dial
}
- remoteConn, err := dialFn("tcp", conn.Req.Target) // XXX: Allow UDP?
+ remoteConn, err := dialFn("tcp", socksReq.Target) // XXX: Allow UDP?
if err != nil {
log.Errorf("%s(%s) - outgoing connection failed: %s", name, addrStr, log.ElideError(err))
- conn.Reject()
+ socksReq.Reply(socks5.ErrorToReplyCode(err))
return
}
defer remoteConn.Close()
@@ -167,12 +168,12 @@ func clientHandler(f base.ClientFactory, conn *pt.SocksConn, proxyURI *url.URL)
remote, err := f.WrapConn(remoteConn, args)
if err != nil {
log.Errorf("%s(%s) - handshake failed: %s", name, addrStr, log.ElideError(err))
- conn.Reject()
+ socksReq.Reply(socks5.ReplyGeneralFailure)
return
}
- err = conn.Grant(remoteConn.RemoteAddr().(*net.TCPAddr))
+ err = socksReq.Reply(socks5.ReplySucceeded)
if err != nil {
- log.Errorf("%s(%s) - SOCKS grant failed: %s", name, addrStr, log.ElideError(err))
+ log.Errorf("%s(%s) - SOCKS reply failed: %s", name, addrStr, log.ElideError(err))
return
}