Miro 1 год назад
Родитель
Сommit
a13d795e41
4 измененных файлов с 28 добавлено и 41 удалено
  1. 12 13
      psiphon/dialParameters.go
  2. 1 12
      psiphon/server/shadowsocks.go
  3. 14 16
      psiphon/shadowsocksConn.go
  4. 1 0
      psiphon/tunnel.go

+ 12 - 13
psiphon/dialParameters.go

@@ -31,7 +31,6 @@ import (
 	"sync/atomic"
 	"time"
 
-	"github.com/Jigsaw-Code/outline-sdk/transport"
 	"github.com/Jigsaw-Code/outline-sdk/transport/shadowsocks"
 	tls "github.com/Psiphon-Labs/psiphon-tls"
 	"github.com/Psiphon-Labs/psiphon-tunnel-core/psiphon/common"
@@ -119,6 +118,8 @@ type DialParameters struct {
 	TLSOSSHSNIServerName            string
 	TLSOSSHObfuscatorPaddingSeed    *prng.Seed
 
+	ShadowsocksEncryptionKey *shadowsocks.EncryptionKey
+
 	SelectedUserAgent bool
 	UserAgent         string
 
@@ -628,6 +629,14 @@ func MakeDialParameters(
 		}
 	}
 
+	if !isReplay && protocol.TunnelProtocolUsesShadowsocks(dialParams.TunnelProtocol) {
+		// TODO: will ShadowsocksEncryptionKey work with replay?
+		dialParams.ShadowsocksEncryptionKey, err = shadowsocks.NewEncryptionKey(shadowsocks.CHACHA20IETFPOLY1305, dialParams.ServerEntry.SshShadowsocksKey)
+		if err != nil {
+			return nil, errors.Trace(err)
+		}
+	}
+
 	if !isReplay || !replayFragmentor {
 		dialParams.FragmentorSeed, err = prng.NewSeed()
 		if err != nil {
@@ -1711,19 +1720,9 @@ func (dialParams *DialParameters) GetTLSOSSHConfig(config *Config) *TLSTunnelCon
 }
 
 func (dialParams *DialParameters) GetShadowsocksConfig() *ShadowsockConfig {
-
-	key, err := shadowsocks.NewEncryptionKey(shadowsocks.CHACHA20IETFPOLY1305, dialParams.ServerEntry.SshShadowsocksKey)
-	if err != nil {
-		// TODO: parse key in MakeDialParameters
-		panic(err)
-	}
-
 	return &ShadowsockConfig{
-		endpoint: &transport.TCPEndpoint{
-			Address: dialParams.DirectDialAddress,
-			// Dialer:  net.Dialer{}, // TODO: pass in custom TLS dialer?
-		},
-		key: key,
+		dialAddr: dialParams.DirectDialAddress,
+		key:      dialParams.ShadowsocksEncryptionKey,
 	}
 }
 

+ 1 - 12
psiphon/server/shadowsocks.go

@@ -26,7 +26,6 @@ import (
 	"github.com/Jigsaw-Code/outline-sdk/transport/shadowsocks"
 	"github.com/Psiphon-Labs/psiphon-tunnel-core/psiphon/common"
 	"github.com/Psiphon-Labs/psiphon-tunnel-core/psiphon/common/errors"
-	"github.com/shadowsocks/go-shadowsocks2/socks"
 )
 
 type ShadowsocksServer struct {
@@ -99,8 +98,7 @@ func (l *ShadowsocksListener) Accept() (net.Conn, error) {
 // ShadowsocksConn implements the net.Conn and common.MetricsSource interfaces.
 type ShadowsocksConn struct {
 	net.Conn
-	readTargetAddr bool // TODO: atomic?
-	server         *ShadowsocksServer
+	server *ShadowsocksServer
 }
 
 // NewShadowsocksConn initializes a new NewShadowsocksConn.
@@ -112,15 +110,6 @@ func NewShadowsocksConn(conn net.Conn, server *ShadowsocksServer) *ShadowsocksCo
 }
 
 func (conn *ShadowsocksConn) Read(b []byte) (int, error) {
-	// First read and discard target address
-	if !conn.readTargetAddr {
-		_, err := socks.ReadAddr(conn.Conn)
-		if err != nil {
-			return 0, errors.Trace(err)
-		}
-		// TODO: check target address is what we expect
-		conn.readTargetAddr = true
-	}
 	return conn.Conn.Read(b)
 }
 

+ 14 - 16
psiphon/shadowsocksConn.go

@@ -28,8 +28,9 @@ import (
 	"github.com/Psiphon-Labs/psiphon-tunnel-core/psiphon/common/errors"
 )
 
+// TODO: do fields need to be exported for replay?
 type ShadowsockConfig struct {
-	endpoint *transport.TCPEndpoint
+	dialAddr string
 
 	key *shadowsocks.EncryptionKey
 }
@@ -38,26 +39,23 @@ type shadowsocksConn struct {
 	net.Conn
 }
 
-func DialShadowsocksTunnel(ctx context.Context, shadowsocksConfig *ShadowsockConfig) (*shadowsocksConn, error) {
+func DialShadowsocksTunnel(
+	ctx context.Context,
+	shadowsocksConfig *ShadowsockConfig,
+	dialConfig *DialConfig) (*shadowsocksConn, error) {
 
-	// Connects to ss server
-	// TODO: ss also supports UDP with NewPacketListener
-	d, err := shadowsocks.NewStreamDialer(shadowsocksConfig.endpoint, shadowsocksConfig.key)
+	conn, err := DialTCP(ctx, shadowsocksConfig.dialAddr, dialConfig)
 	if err != nil {
-		return nil, errors.TraceMsg(err, "failed to create StreamDialer")
+		return nil, errors.Trace(err)
 	}
 
-	// Connects to target endpoint beyond ss server. We can use a phony address
-	// here, which will be ignored on the server, and pass data through this
-	// Conn.
-	phonyTargetAddr := "phony.local:1111"
-	conn, err := d.DialStream(context.Background(), phonyTargetAddr)
-	if err != nil {
-		return nil, errors.TraceMsg(err, "StreamDialer.Dial failed")
-	}
-	// conn.SetReadDeadline(time.Now().Add(time.Second * 5))
+	// Based on shadowsocks.DialStream
+	// TODO: explicitly set SaltGenerator?
+	ssw := shadowsocks.NewWriter(conn, shadowsocksConfig.key)
+	ssr := shadowsocks.NewReader(conn, shadowsocksConfig.key)
+	ssConn := transport.WrapConn(conn.(*TCPConn).Conn.(*net.TCPConn), ssr, ssw)
 
 	return &shadowsocksConn{
-		Conn: conn,
+		Conn: ssConn,
 	}, nil
 }

+ 1 - 0
psiphon/tunnel.go

@@ -996,6 +996,7 @@ func dialTunnel(
 		dialConn, err = DialShadowsocksTunnel(
 			ctx,
 			dialParams.GetShadowsocksConfig(),
+			dialParams.GetDialConfig(),
 		)
 		if err != nil {
 			return nil, errors.Trace(err)