From 148d114c7366e1d15e807fe2e472f635fb6ed557 Mon Sep 17 00:00:00 2001 From: "rui.zheng" Date: Sat, 14 Jan 2017 13:41:49 +0800 Subject: [PATCH] ss client now support OTA --- conn.go | 45 +++++++++++++++++++++------------------------ server.go | 21 +++++++++++++++++---- 2 files changed, 38 insertions(+), 28 deletions(-) diff --git a/conn.go b/conn.go index f44fcc1..a46a285 100644 --- a/conn.go +++ b/conn.go @@ -2,18 +2,18 @@ package gost import ( "bufio" - "bytes" "crypto/tls" "encoding/base64" "errors" "github.com/ginuerzh/gosocks5" "github.com/golang/glog" - "github.com/shadowsocks/shadowsocks-go/shadowsocks" + ss "github.com/shadowsocks/shadowsocks-go/shadowsocks" "net" "net/http" "net/http/httputil" "net/url" "strconv" + "strings" "sync" "time" ) @@ -115,15 +115,7 @@ func (c *ProxyConn) handshake() error { } c.conn = conn case "ss": // shadowsocks - if len(c.Node.Users) > 0 { - method := c.Node.Users[0].Username() - password, _ := c.Node.Users[0].Password() - cipher, err := shadowsocks.NewCipher(method, password) - if err != nil { - return err - } - c.conn = &shadowConn{conn: shadowsocks.NewConn(c.conn, cipher)} - } + // nothing to do case "http", "http2": fallthrough default: @@ -138,26 +130,31 @@ func (c *ProxyConn) handshake() error { func (c *ProxyConn) Connect(addr string) error { switch c.Node.Protocol { case "ss": // shadowsocks - host, port, err := net.SplitHostPort(addr) + rawaddr, err := ss.RawAddr(addr) if err != nil { return err } - p, _ := strconv.Atoi(port) - req := gosocks5.NewRequest(gosocks5.CmdConnect, &gosocks5.Addr{ - Type: gosocks5.AddrDomain, - Host: host, - Port: uint16(p), - }) - buf := bytes.Buffer{} - if err := req.Write(&buf); err != nil { - return err + + var method, password string + if len(c.Node.Users) > 0 { + method = c.Node.Users[0].Username() + password, _ = c.Node.Users[0].Password() } - b := buf.Bytes() - if _, err := c.Write(b[3:]); err != nil { + if c.Node.getBool("ota") && !strings.HasSuffix(method, "-auth") { + method += "-auth" + } + + cipher, err := ss.NewCipher(method, password) + if err != nil { return err } - glog.V(LDEBUG).Infoln("[ss]", req) + ssc, err := ss.DialWithRawAddrConn(rawaddr, c.conn, cipher) + if err != nil { + return err + } + c.conn = &shadowConn{conn: ssc} + return nil case "socks", "socks5": host, port, err := net.SplitHostPort(addr) if err != nil { diff --git a/server.go b/server.go index 955dd2f..74b3861 100644 --- a/server.go +++ b/server.go @@ -10,6 +10,7 @@ import ( "net" "net/http" "strconv" + "strings" ) type ProxyServer struct { @@ -18,6 +19,7 @@ type ProxyServer struct { TLSConfig *tls.Config selector *serverSelector cipher *ss.Cipher + ota bool } func NewProxyServer(node ProxyNode, chain *ProxyChain, config *tls.Config) *ProxyServer { @@ -29,10 +31,20 @@ func NewProxyServer(node ProxyNode, chain *ProxyChain, config *tls.Config) *Prox } var cipher *ss.Cipher - if node.Protocol == "ss" && node.Users != nil { + var ota bool + if node.Protocol == "ss" { var err error - method := node.Users[0].Username() - password, _ := node.Users[0].Password() + var method, password string + + if len(node.Users) > 0 { + method = node.Users[0].Username() + password, _ = node.Users[0].Password() + } + ota = node.getBool("ota") + if strings.HasSuffix(method, "-auth") { + ota = true + method = strings.TrimSuffix(method, "-auth") + } cipher, err = ss.NewCipher(method, password) if err != nil { glog.Fatal(err) @@ -54,6 +66,7 @@ func NewProxyServer(node ProxyNode, chain *ProxyChain, config *tls.Config) *Prox tlsConfig: config, }, cipher: cipher, + ota: ota, } } @@ -134,7 +147,7 @@ func (s *ProxyServer) handleConn(conn net.Conn) { switch s.Node.Protocol { case "ss": // shadowsocks server := NewShadowServer(ss.NewConn(conn, s.cipher.Copy()), s) - server.OTA = s.Node.getBool("ota") + server.OTA = s.ota server.Serve() return case "http":