better support for SOCKS4

This commit is contained in:
rui.zheng 2017-02-11 19:29:38 +08:00
parent ab87ca05fa
commit 69399ee74f
3 changed files with 49 additions and 77 deletions

View File

@ -184,27 +184,28 @@ func (s *ProxyServer) handleConn(conn net.Conn) {
return return
} }
// http or socks5 br := bufio.NewReader(conn)
b := make([]byte, MediumBufferSize) b, err := br.Peek(1)
n, err := io.ReadAtLeast(conn, b, 2)
if err != nil { if err != nil {
glog.V(LWARNING).Infoln(err) glog.V(LWARNING).Infoln(err)
return return
} }
// TODO: use bufio.Reader switch b[0] {
if b[0] == gosocks5.Ver5 { case gosocks4.Ver4:
mn := int(b[1]) // methods count req, err := gosocks4.ReadRequest(br)
length := 2 + mn if err != nil {
if n < length { glog.V(LWARNING).Infoln("[socks4]", err)
if _, err := io.ReadFull(conn, b[n:length]); err != nil { return
}
NewSocks4Server(conn, s).HandleRequest(req)
case gosocks5.Ver5:
methods, err := gosocks5.ReadMethods(br)
if err != nil {
glog.V(LWARNING).Infoln("[socks5]", err) glog.V(LWARNING).Infoln("[socks5]", err)
return return
} }
}
// TODO: use gosocks5.ServerConn
methods := b[2 : 2+mn]
method := s.selector.Select(methods...) method := s.selector.Select(methods...)
if _, err := conn.Write([]byte{gosocks5.Ver5, method}); err != nil { if _, err := conn.Write([]byte{gosocks5.Ver5, method}); err != nil {
glog.V(LWARNING).Infoln("[socks5] select:", err) glog.V(LWARNING).Infoln("[socks5] select:", err)
@ -223,15 +224,15 @@ func (s *ProxyServer) handleConn(conn net.Conn) {
return return
} }
NewSocks5Server(conn, s).HandleRequest(req) NewSocks5Server(conn, s).HandleRequest(req)
return
}
req, err := http.ReadRequest(bufio.NewReader(&reqReader{b: b[:n], r: conn})) default: // http
req, err := http.ReadRequest(br)
if err != nil { if err != nil {
glog.V(LWARNING).Infoln("[http]", err) glog.V(LWARNING).Infoln("[http]", err)
return return
} }
NewHttpServer(conn, s).HandleRequest(req) NewHttpServer(conn, s).HandleRequest(req)
}
} }
func (_ *ProxyServer) transport(conn1, conn2 net.Conn) (err error) { func (_ *ProxyServer) transport(conn1, conn2 net.Conn) (err error) {
@ -254,18 +255,3 @@ func (_ *ProxyServer) transport(conn1, conn2 net.Conn) (err error) {
return return
} }
type reqReader struct {
b []byte
r io.Reader
}
func (r *reqReader) Read(p []byte) (n int, err error) {
if len(r.b) == 0 {
return r.r.Read(p)
}
n = copy(p, r.b)
r.b = r.b[n:]
return
}

View File

@ -27,10 +27,10 @@
"revisionTime": "2017-01-19T05:34:58Z" "revisionTime": "2017-01-19T05:34:58Z"
}, },
{ {
"checksumSHA1": "1iyn4OEHEJknBi+IiZuUaJi6Ifw=", "checksumSHA1": "/unEypznQ0qT7TWxnA4KLOgOXwo=",
"path": "github.com/ginuerzh/gost", "path": "github.com/ginuerzh/gost",
"revision": "333291e9bc766a76d6df5243a7022c5f028be17c", "revision": "ab87ca05fa5553dab59aa1623624ddefa66b408b",
"revisionTime": "2017-02-05T06:35:38Z" "revisionTime": "2017-02-11T10:34:35Z"
}, },
{ {
"checksumSHA1": "+XIOnTW0rv8Kr/amkXgMraNeUr4=", "checksumSHA1": "+XIOnTW0rv8Kr/amkXgMraNeUr4=",

View File

@ -184,27 +184,28 @@ func (s *ProxyServer) handleConn(conn net.Conn) {
return return
} }
// http or socks5 br := bufio.NewReader(conn)
b := make([]byte, MediumBufferSize) b, err := br.Peek(1)
n, err := io.ReadAtLeast(conn, b, 2)
if err != nil { if err != nil {
glog.V(LWARNING).Infoln(err) glog.V(LWARNING).Infoln(err)
return return
} }
// TODO: use bufio.Reader switch b[0] {
if b[0] == gosocks5.Ver5 { case gosocks4.Ver4:
mn := int(b[1]) // methods count req, err := gosocks4.ReadRequest(br)
length := 2 + mn if err != nil {
if n < length { glog.V(LWARNING).Infoln("[socks4]", err)
if _, err := io.ReadFull(conn, b[n:length]); err != nil { return
}
NewSocks4Server(conn, s).HandleRequest(req)
case gosocks5.Ver5:
methods, err := gosocks5.ReadMethods(br)
if err != nil {
glog.V(LWARNING).Infoln("[socks5]", err) glog.V(LWARNING).Infoln("[socks5]", err)
return return
} }
}
// TODO: use gosocks5.ServerConn
methods := b[2 : 2+mn]
method := s.selector.Select(methods...) method := s.selector.Select(methods...)
if _, err := conn.Write([]byte{gosocks5.Ver5, method}); err != nil { if _, err := conn.Write([]byte{gosocks5.Ver5, method}); err != nil {
glog.V(LWARNING).Infoln("[socks5] select:", err) glog.V(LWARNING).Infoln("[socks5] select:", err)
@ -223,15 +224,15 @@ func (s *ProxyServer) handleConn(conn net.Conn) {
return return
} }
NewSocks5Server(conn, s).HandleRequest(req) NewSocks5Server(conn, s).HandleRequest(req)
return
}
req, err := http.ReadRequest(bufio.NewReader(&reqReader{b: b[:n], r: conn})) default: // http
req, err := http.ReadRequest(br)
if err != nil { if err != nil {
glog.V(LWARNING).Infoln("[http]", err) glog.V(LWARNING).Infoln("[http]", err)
return return
} }
NewHttpServer(conn, s).HandleRequest(req) NewHttpServer(conn, s).HandleRequest(req)
}
} }
func (_ *ProxyServer) transport(conn1, conn2 net.Conn) (err error) { func (_ *ProxyServer) transport(conn1, conn2 net.Conn) (err error) {
@ -254,18 +255,3 @@ func (_ *ProxyServer) transport(conn1, conn2 net.Conn) (err error) {
return return
} }
type reqReader struct {
b []byte
r io.Reader
}
func (r *reqReader) Read(p []byte) (n int, err error) {
if len(r.b) == 0 {
return r.r.Read(p)
}
n = copy(p, r.b)
r.b = r.b[n:]
return
}