[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

[tor-commits] [obfs4/master] Make establishing outgoing connections the transport's responsibility.



commit e52258edac55d82ff153755493d770bfbbc9a346
Author: Yawning Angel <yawning@xxxxxxxxxxxxxx>
Date:   Thu Oct 29 14:09:34 2015 +0000

    Make establishing outgoing connections the transport's responsibility.
    
    ClientFactories now have a Dial() method instead of a WrapConn()
    method, so that it is possible to write something like meek-client
    using the obfs4proxy framework.
    
    This breaks the external interface if anyone is using obfs4proxy as
    a library, but the new way of doing things is a trivial modification,
    to a single routine that shouldn't have been very large to begin with.
---
 obfs4proxy/obfs4proxy.go        |   13 ++-----------
 transports/base/base.go         |   10 ++++++----
 transports/obfs2/obfs2.go       |   12 ++++++++++--
 transports/obfs3/obfs3.go       |   12 ++++++++++--
 transports/obfs4/obfs4.go       |   14 +++++++++++---
 transports/scramblesuit/base.go |   14 ++++++++++++--
 6 files changed, 51 insertions(+), 24 deletions(-)

diff --git a/obfs4proxy/obfs4proxy.go b/obfs4proxy/obfs4proxy.go
index a817583..5c23ba2 100644
--- a/obfs4proxy/obfs4proxy.go
+++ b/obfs4proxy/obfs4proxy.go
@@ -155,22 +155,13 @@ func clientHandler(f base.ClientFactory, conn net.Conn, proxyURI *url.URL) {
 		}
 		dialFn = dialer.Dial
 	}
-	remoteConn, err := dialFn("tcp", socksReq.Target) // XXX: Allow UDP?
+	remote, err := f.Dial("tcp", socksReq.Target, dialFn, args)
 	if err != nil {
 		log.Errorf("%s(%s) - outgoing connection failed: %s", name, addrStr, log.ElideError(err))
 		socksReq.Reply(socks5.ErrorToReplyCode(err))
 		return
 	}
-	defer remoteConn.Close()
-
-	// Instantiate the client transport method, handshake, and start pushing
-	// bytes back and forth.
-	remote, err := f.WrapConn(remoteConn, args)
-	if err != nil {
-		log.Errorf("%s(%s) - handshake failed: %s", name, addrStr, log.ElideError(err))
-		socksReq.Reply(socks5.ReplyGeneralFailure)
-		return
-	}
+	defer remote.Close()
 	err = socksReq.Reply(socks5.ReplySucceeded)
 	if err != nil {
 		log.Errorf("%s(%s) - SOCKS reply failed: %s", name, addrStr, log.ElideError(err))
diff --git a/transports/base/base.go b/transports/base/base.go
index e81ea03..bb0902e 100644
--- a/transports/base/base.go
+++ b/transports/base/base.go
@@ -35,6 +35,8 @@ import (
 	"git.torproject.org/pluggable-transports/goptlib.git"
 )
 
+type DialFunc func(string, string) (net.Conn, error)
+
 // ClientFactory is the interface that defines the factory for creating
 // pluggable transport protocol client instances.
 type ClientFactory interface {
@@ -48,10 +50,10 @@ type ClientFactory interface {
 	// generation) to be hidden from third parties.
 	ParseArgs(args *pt.Args) (interface{}, error)
 
-	// WrapConn wraps the provided net.Conn with a transport protocol
-	// implementation, and does whatever is required (eg: handshaking) to get
-	// the connection to a point where it is ready to relay data.
-	WrapConn(conn net.Conn, args interface{}) (net.Conn, error)
+	// Dial creates an outbound net.Conn, and does whatever is required
+	// (eg: handshaking) to get the connection to the point where it is
+	// ready to relay data.
+	Dial(network, address string, dialFn DialFunc, args interface{}) (net.Conn, error)
 }
 
 // ServerFactory is the interface that defines the factory for creating
diff --git a/transports/obfs2/obfs2.go b/transports/obfs2/obfs2.go
index bc2532b..a926141 100644
--- a/transports/obfs2/obfs2.go
+++ b/transports/obfs2/obfs2.go
@@ -108,8 +108,16 @@ func (cf *obfs2ClientFactory) ParseArgs(args *pt.Args) (interface{}, error) {
 	return nil, validateArgs(args)
 }
 
-func (cf *obfs2ClientFactory) WrapConn(conn net.Conn, args interface{}) (net.Conn, error) {
-	return newObfs2ClientConn(conn)
+func (cf *obfs2ClientFactory) Dial(network, addr string, dialFn base.DialFunc, args interface{}) (net.Conn, error) {
+	conn, err := dialFn(network, addr)
+	if err != nil {
+		return nil, err
+	}
+	if conn, err = newObfs2ClientConn(conn); err != nil {
+		conn.Close()
+		return nil, err
+	}
+	return conn, nil
 }
 
 type obfs2ServerFactory struct {
diff --git a/transports/obfs3/obfs3.go b/transports/obfs3/obfs3.go
index d215c49..e4c3ba6 100644
--- a/transports/obfs3/obfs3.go
+++ b/transports/obfs3/obfs3.go
@@ -92,8 +92,16 @@ func (cf *obfs3ClientFactory) ParseArgs(args *pt.Args) (interface{}, error) {
 	return nil, nil
 }
 
-func (cf *obfs3ClientFactory) WrapConn(conn net.Conn, args interface{}) (net.Conn, error) {
-	return newObfs3ClientConn(conn)
+func (cf *obfs3ClientFactory) Dial(network, addr string, dialFn base.DialFunc, args interface{}) (net.Conn, error) {
+	conn, err := dialFn(network, addr)
+	if err != nil {
+		return nil, err
+	}
+	if conn, err = newObfs3ClientConn(conn); err != nil {
+		conn.Close()
+		return nil, err
+	}
+	return conn, nil
 }
 
 type obfs3ServerFactory struct {
diff --git a/transports/obfs4/obfs4.go b/transports/obfs4/obfs4.go
index 07af9ab..5701535 100644
--- a/transports/obfs4/obfs4.go
+++ b/transports/obfs4/obfs4.go
@@ -204,13 +204,21 @@ func (cf *obfs4ClientFactory) ParseArgs(args *pt.Args) (interface{}, error) {
 	return &obfs4ClientArgs{nodeID, publicKey, sessionKey, iatMode}, nil
 }
 
-func (cf *obfs4ClientFactory) WrapConn(conn net.Conn, args interface{}) (net.Conn, error) {
+func (cf *obfs4ClientFactory) Dial(network, addr string, dialFn base.DialFunc, args interface{}) (net.Conn, error) {
+	// Validate args before bothering to open connection.
 	ca, ok := args.(*obfs4ClientArgs)
 	if !ok {
 		return nil, fmt.Errorf("invalid argument type for args")
 	}
-
-	return newObfs4ClientConn(conn, ca)
+	conn, err := dialFn(network, addr)
+	if err != nil {
+		return nil, err
+	}
+	if conn, err = newObfs4ClientConn(conn, ca); err != nil {
+		conn.Close()
+		return nil, err
+	}
+	return conn, nil
 }
 
 type obfs4ServerFactory struct {
diff --git a/transports/scramblesuit/base.go b/transports/scramblesuit/base.go
index 711c046..223d085 100644
--- a/transports/scramblesuit/base.go
+++ b/transports/scramblesuit/base.go
@@ -76,12 +76,22 @@ func (cf *ssClientFactory) ParseArgs(args *pt.Args) (interface{}, error) {
 	return newClientArgs(args)
 }
 
-func (cf *ssClientFactory) WrapConn(conn net.Conn, args interface{}) (net.Conn, error) {
+func (cf *ssClientFactory) Dial(network, addr string, dialFn base.DialFunc, args interface{}) (net.Conn, error) {
+	// Validate args before opening outgoing connection.
 	ca, ok := args.(*ssClientArgs)
 	if !ok {
 		return nil, fmt.Errorf("invalid argument type for args")
 	}
-	return newScrambleSuitClientConn(conn, cf.ticketStore, ca)
+
+	conn, err := dialFn(network, addr)
+	if err != nil {
+		return nil, err
+	}
+	if conn, err = newScrambleSuitClientConn(conn, cf.ticketStore, ca); err != nil {
+		conn.Close()
+		return nil, err
+	}
+	return conn, nil
 }
 
 var _ base.ClientFactory = (*ssClientFactory)(nil)

_______________________________________________
tor-commits mailing list
tor-commits@xxxxxxxxxxxxxxxxxxxx
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits