From 4309ea67e2425c4586864c956aa44834aa6d231c Mon Sep 17 00:00:00 2001 From: ginuerzh Date: Sun, 11 Oct 2015 22:19:27 +0800 Subject: [PATCH] forward now works --- conn.go | 85 +++++++++++++++++++++++++------------------------------- http.go | 3 +- socks.go | 29 ++++++++++++++----- 3 files changed, 61 insertions(+), 56 deletions(-) diff --git a/conn.go b/conn.go index 5ee0c5f..e203f92 100644 --- a/conn.go +++ b/conn.go @@ -92,7 +92,8 @@ func handleConn(conn net.Conn, arg Args) { selector := &serverSelector{ methods: []uint8{ - gosocks5.MethodNoAuth, gosocks5.MethodUserPass, + gosocks5.MethodNoAuth, + gosocks5.MethodUserPass, }, arg: arg, } @@ -215,32 +216,40 @@ func connect(connType, addr string) (conn net.Conn, err error) { addr += ":80" } + if len(proxyArgs) > 0 && len(forwardArgs) > 0 { + return connectProxyForward(connType, addr, proxyArgs[0], forwardArgs[0]) + } + if len(forwardArgs) > 0 { // TODO: multi-foward forward := forwardArgs[0] - return connectForward(addr, forward) + return connectForward(connType, addr, forward) } if len(proxyArgs) > 0 { proxy := proxyArgs[0] - return connectProxy(connType, addr, proxy) + return connectForward(connType, addr, proxy) } return net.Dial("tcp", addr) } -func connectProxy(connType, addr string, proxy Args) (conn net.Conn, err error) { +func connectProxyForward(connType, addr string, proxy, forward Args) (conn net.Conn, err error) { + return nil, errors.New("Not implemented") +} + +func connectForward(connType, addr string, forward Args) (conn net.Conn, err error) { if glog.V(LINFO) { - glog.Infoln("connect proxy:", proxy.Addr) + glog.Infoln(forward.Protocol, "forward:", forward.Addr) } - conn, err = net.Dial("tcp", proxy.Addr) + conn, err = net.Dial("tcp", forward.Addr) if err != nil { return } - switch proxy.Transport { + switch forward.Transport { case "ws": // websocket connection - c, err := wsClient(conn, proxy.Addr) + c, err := wsClient(conn, forward.Addr) if err != nil { conn.Close() return nil, err @@ -253,16 +262,16 @@ func connectProxy(connType, addr string, proxy Args) (conn net.Conn, err error) default: } - switch proxy.Protocol { + switch forward.Protocol { case "ss": // shadowsocks conn.Close() return nil, errors.New("Not implemented") case "socks", "socks5": selector := &clientSelector{ methods: []uint8{gosocks5.MethodNoAuth, gosocks5.MethodUserPass}, - arg: proxy, + arg: forward, } - if proxy.EncMeth == "tls" { + if forward.EncMeth == "tls" { selector.methods = []uint8{MethodTLS, MethodTLSAuth} } c := gosocks5.ClientConn(conn, selector) @@ -272,40 +281,26 @@ func connectProxy(connType, addr string, proxy Args) (conn net.Conn, err error) } conn = c - if connType == ConnHttp || connType == ConnHttpConnect { - host, port, _ := net.SplitHostPort(addr) - p, _ := strconv.ParseUint(port, 10, 16) - r := gosocks5.NewRequest(gosocks5.CmdConnect, &gosocks5.Addr{ - Type: gosocks5.AddrDomain, - Host: host, - Port: uint16(p), - }) - if glog.V(LDEBUG) { - glog.Infoln(r.String()) - } - if err := r.Write(conn); err != nil { - conn.Close() - return nil, err - } - - rep, err := gosocks5.ReadReply(conn) - if err != nil { - conn.Close() - return nil, err - } - if glog.V(LDEBUG) { - glog.Infoln(rep.String()) - } - - if rep.Rep != gosocks5.Succeeded { - conn.Close() - return nil, errors.New("Service unavailable") - } + host, port, _ := net.SplitHostPort(addr) + p, _ := strconv.ParseUint(port, 10, 16) + r := gosocks5.NewRequest(gosocks5.CmdConnect, &gosocks5.Addr{ + Type: gosocks5.AddrDomain, + Host: host, + Port: uint16(p), + }) + rep, err := requestSocks5(conn, r) + if err != nil { + conn.Close() + return nil, err + } + if rep.Rep != gosocks5.Succeeded { + conn.Close() + return nil, errors.New("Service unavailable") } case "http": fallthrough default: - if connType == ConnHttpConnect { + if connType == ConnHttpConnect || connType == ConnSocks5 { req := &http.Request{ Method: "CONNECT", URL: &url.URL{Host: addr}, @@ -315,9 +310,9 @@ func connectProxy(connType, addr string, proxy Args) (conn net.Conn, err error) Header: make(http.Header), } req.Header.Set("Proxy-Connection", "keep-alive") - if proxy.User != nil { + if forward.User != nil { req.Header.Set("Proxy-Authorization", - "Basic "+base64.StdEncoding.EncodeToString([]byte(proxy.User.String()))) + "Basic "+base64.StdEncoding.EncodeToString([]byte(forward.User.String()))) } if err = req.Write(conn); err != nil { conn.Close() @@ -347,7 +342,3 @@ func connectProxy(connType, addr string, proxy Args) (conn net.Conn, err error) return } - -func connectForward(addr string, forward Args) (net.Conn, error) { - return nil, errors.New("Not implemented") -} diff --git a/http.go b/http.go index aa960fa..c4be6a2 100644 --- a/http.go +++ b/http.go @@ -80,7 +80,7 @@ func handleHttpRequest(req *http.Request, conn net.Conn, arg Args) { return } } else { - if len(proxyArgs) > 0 { + if len(proxyArgs) > 0 || len(forwardArgs) > 0 { err = req.WriteProxy(c) } else { err = req.Write(c) @@ -92,7 +92,6 @@ func handleHttpRequest(req *http.Request, conn net.Conn, arg Args) { return } } - Transport(conn, c) } diff --git a/socks.go b/socks.go index 899ded4..73ab490 100644 --- a/socks.go +++ b/socks.go @@ -85,7 +85,7 @@ func (selector *serverSelector) Methods() []uint8 { func (selector *serverSelector) Select(methods ...uint8) (method uint8) { if glog.V(LDEBUG) { - glog.Infof("%x %x % x", gosocks5.Ver5, len(methods), methods) + glog.Infof("%d %d % d", gosocks5.Ver5, len(methods), methods) } method = gosocks5.MethodNoAcceptable @@ -94,11 +94,12 @@ func (selector *serverSelector) Select(methods ...uint8) (method uint8) { for _, mm := range selector.methods { if m == mm { method = m - break + goto out } } } +out: if method == gosocks5.MethodNoAcceptable { return } @@ -117,7 +118,7 @@ func (selector *serverSelector) Select(methods ...uint8) (method uint8) { func (selector *serverSelector) OnSelected(method uint8, conn net.Conn) (net.Conn, error) { if glog.V(LDEBUG) { - glog.Infof("%x %x", gosocks5.Ver5, method) + glog.Infof("%d %d", gosocks5.Ver5, method) } switch method { @@ -178,6 +179,23 @@ func (selector *serverSelector) OnSelected(method uint8, conn net.Conn) (net.Con return conn, nil } +func requestSocks5(conn net.Conn, req *gosocks5.Request) (*gosocks5.Reply, error) { + if err := req.Write(conn); err != nil { + return nil, err + } + if glog.V(LDEBUG) { + glog.Infoln(req.String()) + } + rep, err := gosocks5.ReadReply(conn) + if err != nil { + return nil, err + } + if glog.V(LDEBUG) { + glog.Infoln(rep.String()) + } + return rep, nil +} + func handleSocks5Request(req *gosocks5.Request, conn net.Conn, arg Args) { if glog.V(LDEBUG) { glog.Infoln(req) @@ -218,10 +236,7 @@ func handleSocks5Request(req *gosocks5.Request, conn net.Conn, arg Args) { glog.Infoln(rep) } } - - if err := Transport(conn, tconn); err != nil { - //log.Println(err) - } + Transport(conn, tconn) case gosocks5.CmdBind: l, err := net.ListenTCP("tcp", nil) if err != nil {