diff --git a/handler.go b/handler.go new file mode 100644 index 0000000..e832bdc --- /dev/null +++ b/handler.go @@ -0,0 +1,26 @@ +package gost + +import ( + "net" +) + +type Handler interface { + Handle(net.Conn) +} + +type DefaultHandler struct { + server Server +} + +func (h *DefaultHandler) Handle(conn net.Conn) { + var handler Handler + + switch h.server.Options().BaseOptions().Protocol { + case "http": + case "ss": // shadowsocks + handler = ShadowHandler(h.server) + + } + + handler.Handle(conn) +} diff --git a/options.go b/options.go index e7fa3a7..f27b825 100644 --- a/options.go +++ b/options.go @@ -2,6 +2,7 @@ package gost import ( "log" + "net/url" "reflect" ) @@ -13,9 +14,10 @@ type Options interface { type Option func(Options) type BaseOptions struct { - Addr string `opt:"addr"` // [host]:port - Protocol string `opt:"protocol"` // protocol: http/socks5/ss - Transport string `opt:"transport"` // transport: ws/wss/tls/http2/tcp/udp/rtcp/rudp + Addr string `opt:"addr"` // [host]:port + Protocol string `opt:"protocol"` // protocol: http/socks5/ss + Transport string `opt:"transport"` // transport: ws/wss/tls/http2/tcp/udp/rtcp/rudp + Users []url.Userinfo `opt:"users"` // authentication for proxy } func AddrOption(a string) Option { @@ -36,6 +38,12 @@ func TransportOption(t string) Option { } } +func UsersOption(users ...url.Userinfo) Option { + return func(opts Options) { + opts.BaseOptions().Users = users + } +} + func GetOption(i interface{}, opt string) interface{} { ps := reflect.ValueOf(i) if ps.Kind() != reflect.Ptr && ps.Kind() != reflect.Interface { diff --git a/ss.go b/ss.go index 58841d7..3b21ae9 100644 --- a/ss.go +++ b/ss.go @@ -3,7 +3,6 @@ package gost import ( "bytes" "encoding/binary" - "errors" "fmt" "io" "net" @@ -11,197 +10,19 @@ import ( "time" "github.com/ginuerzh/gosocks5" + "github.com/go-log/log" "github.com/golang/glog" ss "github.com/shadowsocks/shadowsocks-go/shadowsocks" ) -const ( - idType = 0 // address type index - idIP0 = 1 // ip addres start index - idDmLen = 1 // domain address length index - idDm0 = 2 // domain address start index - - typeIPv4 = 1 // type is ipv4 address - typeDm = 3 // type is domain address - typeIPv6 = 4 // type is ipv6 address - - lenIPv4 = net.IPv4len + 2 // ipv4 + 2port - lenIPv6 = net.IPv6len + 2 // ipv6 + 2port - lenDmBase = 2 // 1addrLen + 2port, plus addrLen - lenHmacSha1 = 10 -) - -type ShadowServer struct { - conn *ss.Conn - Base *ProxyServer - OTA bool // one time auth -} - -func NewShadowServer(conn *ss.Conn, base *ProxyServer) *ShadowServer { - return &ShadowServer{conn: conn, Base: base} -} - -func (s *ShadowServer) Serve() { - glog.V(LINFO).Infof("[ss] %s - %s", s.conn.RemoteAddr(), s.conn.LocalAddr()) - - addr, ota, err := s.getRequest() - if err != nil { - glog.V(LWARNING).Infof("[ss] %s - %s : %s", s.conn.RemoteAddr(), s.conn.LocalAddr(), err) - return - } - glog.V(LINFO).Infof("[ss] %s -> %s, ota: %v", s.conn.RemoteAddr(), addr, ota) - - cc, err := s.Base.Chain.Dial(addr) - if err != nil { - glog.V(LWARNING).Infof("[ss] %s -> %s : %s", s.conn.RemoteAddr(), addr, err) - return - } - defer cc.Close() - - glog.V(LINFO).Infof("[ss] %s <-> %s", s.conn.RemoteAddr(), addr) - if ota { - s.transportOTA(s.conn, cc) - } else { - s.Base.transport(&shadowConn{conn: s.conn}, cc) - } - glog.V(LINFO).Infof("[ss] %s >-< %s", s.conn.RemoteAddr(), addr) -} - -// This function is copied from shadowsocks library with some modification. -func (s *ShadowServer) getRequest() (host string, ota bool, err error) { - // buf size should at least have the same size with the largest possible - // request size (when addrType is 3, domain name has at most 256 bytes) - // 1(addrType) + 1(lenByte) + 256(max length address) + 2(port) - buf := make([]byte, SmallBufferSize) - - // read till we get possible domain length field - s.conn.SetReadDeadline(time.Now().Add(ReadTimeout)) - if _, err = io.ReadFull(s.conn, buf[:idType+1]); err != nil { - return - } - - var reqStart, reqEnd int - addrType := buf[idType] - switch addrType & ss.AddrMask { - case typeIPv4: - reqStart, reqEnd = idIP0, idIP0+lenIPv4 - case typeIPv6: - reqStart, reqEnd = idIP0, idIP0+lenIPv6 - case typeDm: - if _, err = io.ReadFull(s.conn, buf[idType+1:idDmLen+1]); err != nil { - return - } - reqStart, reqEnd = idDm0, int(idDm0+buf[idDmLen]+lenDmBase) - default: - err = fmt.Errorf("addr type %d not supported", addrType&ss.AddrMask) - return - } - - if _, err = io.ReadFull(s.conn, buf[reqStart:reqEnd]); err != nil { - return - } - - // Return string for typeIP is not most efficient, but browsers (Chrome, - // Safari, Firefox) all seems using typeDm exclusively. So this is not a - // big problem. - switch addrType & ss.AddrMask { - case typeIPv4: - host = net.IP(buf[idIP0 : idIP0+net.IPv4len]).String() - case typeIPv6: - host = net.IP(buf[idIP0 : idIP0+net.IPv6len]).String() - case typeDm: - host = string(buf[idDm0 : idDm0+buf[idDmLen]]) - } - // parse port - port := binary.BigEndian.Uint16(buf[reqEnd-2 : reqEnd]) - host = net.JoinHostPort(host, strconv.Itoa(int(port))) - // if specified one time auth enabled, we should verify this - if s.OTA || addrType&ss.OneTimeAuthMask > 0 { - ota = true - if _, err = io.ReadFull(s.conn, buf[reqEnd:reqEnd+lenHmacSha1]); err != nil { - return - } - iv := s.conn.GetIv() - key := s.conn.GetKey() - actualHmacSha1Buf := ss.HmacSha1(append(iv, key...), buf[:reqEnd]) - if !bytes.Equal(buf[reqEnd:reqEnd+lenHmacSha1], actualHmacSha1Buf) { - err = fmt.Errorf("verify one time auth failed, iv=%v key=%v data=%v", iv, key, buf[:reqEnd]) - return - } - } - return -} - -const ( - dataLenLen = 2 - hmacSha1Len = 10 - idxData0 = dataLenLen + hmacSha1Len -) - -// copyOta copies data from src to dst with ota verification. -// -// This function is copied from shadowsocks library with some modification. -func (s *ShadowServer) copyOta(dst net.Conn, src *ss.Conn) (int64, error) { - // sometimes it have to fill large block - buf := make([]byte, LargeBufferSize) - for { - src.SetReadDeadline(time.Now().Add(ReadTimeout)) - if n, err := io.ReadFull(src, buf[:dataLenLen+hmacSha1Len]); err != nil { - return int64(n), err - } - src.SetReadDeadline(time.Time{}) - - dataLen := binary.BigEndian.Uint16(buf[:dataLenLen]) - expectedHmacSha1 := buf[dataLenLen:idxData0] - - var dataBuf []byte - if len(buf) < int(idxData0+dataLen) { - dataBuf = make([]byte, dataLen) - } else { - dataBuf = buf[idxData0 : idxData0+dataLen] - } - if n, err := io.ReadFull(src, dataBuf); err != nil { - return int64(n), err - } - chunkIdBytes := make([]byte, 4) - chunkId := src.GetAndIncrChunkId() - binary.BigEndian.PutUint32(chunkIdBytes, chunkId) - actualHmacSha1 := ss.HmacSha1(append(src.GetIv(), chunkIdBytes...), dataBuf) - if !bytes.Equal(expectedHmacSha1, actualHmacSha1) { - return 0, errors.New("ota error: mismatch") - } - - if n, err := dst.Write(dataBuf); err != nil { - return int64(n), err - } - } -} - -func (s *ShadowServer) transportOTA(sc *ss.Conn, cc net.Conn) (err error) { - errc := make(chan error, 2) - - go func() { - _, err := io.Copy(&shadowConn{conn: sc}, cc) - errc <- err - }() - - go func() { - _, err := s.copyOta(cc, sc) - errc <- err - }() - - select { - case err = <-errc: - //glog.V(LWARNING).Infoln("transport exit", err) - } - - return -} - // Due to in/out byte length is inconsistent of the shadowsocks.Conn.Write, // we wrap around it to make io.Copy happy type shadowConn struct { - conn *ss.Conn + conn net.Conn +} + +func ShadowConn(conn net.Conn) net.Conn { + return &shadowConn{conn: conn} } func (c *shadowConn) Read(b []byte) (n int, err error) { @@ -238,6 +59,118 @@ func (c *shadowConn) SetWriteDeadline(t time.Time) error { return c.conn.SetWriteDeadline(t) } +type shadowHandler struct { + server Server +} + +func ShadowHandler(server Server) Handler { + return &shadowHandler{server: server} +} + +func (h *shadowHandler) Handle(conn net.Conn) { + var method, password string + + users := h.server.Options().BaseOptions().Users + if len(users) > 0 { + method = users[0].Username() + password, _ = users[0].Password() + } + cipher, err := ss.NewCipher(method, password) + if err != nil { + log.Log("[ss]", err) + return + } + conn = ShadowConn(ss.NewConn(conn, cipher)) + + log.Logf("[ss] %s - %s", conn.RemoteAddr(), conn.LocalAddr()) + + addr, err := h.getRequest(conn) + if err != nil { + log.Logf("[ss] %s - %s : %s", conn.RemoteAddr(), conn.LocalAddr(), err) + return + } + log.Logf("[ss] %s -> %s", conn.RemoteAddr(), addr) + + cc, err := h.server.Chain().Dial(addr) + if err != nil { + log.Logf("[ss] %s -> %s : %s", conn.RemoteAddr(), addr, err) + return + } + defer cc.Close() + + log.Logf("[ss] %s <-> %s", conn.RemoteAddr(), addr) + defer log.Logf("[ss] %s >-< %s", conn.RemoteAddr(), addr) + + Transport(conn, cc) +} + +const ( + idType = 0 // address type index + idIP0 = 1 // ip addres start index + idDmLen = 1 // domain address length index + idDm0 = 2 // domain address start index + + typeIPv4 = 1 // type is ipv4 address + typeDm = 3 // type is domain address + typeIPv6 = 4 // type is ipv6 address + + lenIPv4 = net.IPv4len + 2 // ipv4 + 2port + lenIPv6 = net.IPv6len + 2 // ipv6 + 2port + lenDmBase = 2 // 1addrLen + 2port, plus addrLen + lenHmacSha1 = 10 +) + +// This function is copied from shadowsocks library with some modification. +func (h *shadowHandler) getRequest(conn net.Conn) (host string, err error) { + // buf size should at least have the same size with the largest possible + // request size (when addrType is 3, domain name has at most 256 bytes) + // 1(addrType) + 1(lenByte) + 256(max length address) + 2(port) + buf := make([]byte, SmallBufferSize) + + // read till we get possible domain length field + conn.SetReadDeadline(time.Now().Add(30 * time.Second)) + if _, err = io.ReadFull(conn, buf[:idType+1]); err != nil { + return + } + + var reqStart, reqEnd int + addrType := buf[idType] + switch addrType & ss.AddrMask { + case typeIPv4: + reqStart, reqEnd = idIP0, idIP0+lenIPv4 + case typeIPv6: + reqStart, reqEnd = idIP0, idIP0+lenIPv6 + case typeDm: + if _, err = io.ReadFull(conn, buf[idType+1:idDmLen+1]); err != nil { + return + } + reqStart, reqEnd = idDm0, int(idDm0+buf[idDmLen]+lenDmBase) + default: + err = fmt.Errorf("addr type %d not supported", addrType&ss.AddrMask) + return + } + + if _, err = io.ReadFull(conn, buf[reqStart:reqEnd]); err != nil { + return + } + + // Return string for typeIP is not most efficient, but browsers (Chrome, + // Safari, Firefox) all seems using typeDm exclusively. So this is not a + // big problem. + switch addrType & ss.AddrMask { + case typeIPv4: + host = net.IP(buf[idIP0 : idIP0+net.IPv4len]).String() + case typeIPv6: + host = net.IP(buf[idIP0 : idIP0+net.IPv6len]).String() + case typeDm: + host = string(buf[idDm0 : idDm0+buf[idDmLen]]) + } + // parse port + port := binary.BigEndian.Uint16(buf[reqEnd-2 : reqEnd]) + host = net.JoinHostPort(host, strconv.Itoa(int(port))) + return +} + type ShadowUdpServer struct { Base *ProxyServer TTL int diff --git a/ssocks/ssocks.go b/ssocks/ssocks.go deleted file mode 100644 index afde874..0000000 --- a/ssocks/ssocks.go +++ /dev/null @@ -1,165 +0,0 @@ -package ssocks - -import ( - "encoding/binary" - "fmt" - "io" - "net" - "net/url" - "strconv" - "time" - - "github.com/go-log/log" - - "github.com/ginuerzh/gost" - ss "github.com/shadowsocks/shadowsocks-go/shadowsocks" -) - -// Due to in/out byte length is inconsistent of the shadowsocks.Conn.Write, -// we wrap around it to make io.Copy happy -type shadowConn struct { - conn net.Conn -} - -func NewConn(conn net.Conn) net.Conn { - return &shadowConn{conn: conn} -} - -func (c *shadowConn) Read(b []byte) (n int, err error) { - return c.conn.Read(b) -} - -func (c *shadowConn) Write(b []byte) (n int, err error) { - n = len(b) // force byte length consistent - _, err = c.conn.Write(b) - return -} - -func (c *shadowConn) Close() error { - return c.conn.Close() -} - -func (c *shadowConn) LocalAddr() net.Addr { - return c.conn.LocalAddr() -} - -func (c *shadowConn) RemoteAddr() net.Addr { - return c.conn.RemoteAddr() -} - -func (c *shadowConn) SetDeadline(t time.Time) error { - return c.conn.SetDeadline(t) -} - -func (c *shadowConn) SetReadDeadline(t time.Time) error { - return c.conn.SetReadDeadline(t) -} - -func (c *shadowConn) SetWriteDeadline(t time.Time) error { - return c.conn.SetWriteDeadline(t) -} - -const ( - idType = 0 // address type index - idIP0 = 1 // ip addres start index - idDmLen = 1 // domain address length index - idDm0 = 2 // domain address start index - - typeIPv4 = 1 // type is ipv4 address - typeDm = 3 // type is domain address - typeIPv6 = 4 // type is ipv6 address - - lenIPv4 = net.IPv4len + 2 // ipv4 + 2port - lenIPv6 = net.IPv6len + 2 // ipv6 + 2port - lenDmBase = 2 // 1addrLen + 2port, plus addrLen - lenHmacSha1 = 10 -) - -type ShadowServer struct { - conn net.Conn - base gost.Server -} - -func NewServer(conn net.Conn, cipher *url.Userinfo, base gost.Server) (*ShadowServer, error) { - method := cipher.Username() - password, _ := cipher.Password() - cp, err := ss.NewCipher(method, password) - if err != nil { - return nil, err - } - return &ShadowServer{conn: ss.NewConn(conn, cp), base: base}, nil -} - -func (s *ShadowServer) Serve() error { - log.Logf("[ss] %s - %s", s.conn.RemoteAddr(), s.conn.LocalAddr()) - - addr, err := s.getRequest() - if err != nil { - log.Logf("[ss] %s - %s : %s", s.conn.RemoteAddr(), s.conn.LocalAddr(), err) - return err - } - log.Logf("[ss] %s -> %s", s.conn.RemoteAddr(), addr) - - cc, err := s.base.Chain().Dial(addr) - if err != nil { - log.Logf("[ss] %s -> %s : %s", s.conn.RemoteAddr(), addr, err) - return err - } - defer cc.Close() - - log.Logf("[ss] %s <-> %s", s.conn.RemoteAddr(), addr) - defer log.Logf("[ss] %s >-< %s", s.conn.RemoteAddr(), addr) - - return gost.Transport(&shadowConn{conn: s.conn}, cc) -} - -// This function is copied from shadowsocks library with some modification. -func (s *ShadowServer) getRequest() (host string, err error) { - // buf size should at least have the same size with the largest possible - // request size (when addrType is 3, domain name has at most 256 bytes) - // 1(addrType) + 1(lenByte) + 256(max length address) + 2(port) - buf := make([]byte, gost.SmallBufferSize) - - // read till we get possible domain length field - s.conn.SetReadDeadline(time.Now().Add(30 * time.Second)) - if _, err = io.ReadFull(s.conn, buf[:idType+1]); err != nil { - return - } - - var reqStart, reqEnd int - addrType := buf[idType] - switch addrType & ss.AddrMask { - case typeIPv4: - reqStart, reqEnd = idIP0, idIP0+lenIPv4 - case typeIPv6: - reqStart, reqEnd = idIP0, idIP0+lenIPv6 - case typeDm: - if _, err = io.ReadFull(s.conn, buf[idType+1:idDmLen+1]); err != nil { - return - } - reqStart, reqEnd = idDm0, int(idDm0+buf[idDmLen]+lenDmBase) - default: - err = fmt.Errorf("addr type %d not supported", addrType&ss.AddrMask) - return - } - - if _, err = io.ReadFull(s.conn, buf[reqStart:reqEnd]); err != nil { - return - } - - // Return string for typeIP is not most efficient, but browsers (Chrome, - // Safari, Firefox) all seems using typeDm exclusively. So this is not a - // big problem. - switch addrType & ss.AddrMask { - case typeIPv4: - host = net.IP(buf[idIP0 : idIP0+net.IPv4len]).String() - case typeIPv6: - host = net.IP(buf[idIP0 : idIP0+net.IPv6len]).String() - case typeDm: - host = string(buf[idDm0 : idDm0+buf[idDmLen]]) - } - // parse port - port := binary.BigEndian.Uint16(buf[reqEnd-2 : reqEnd]) - host = net.JoinHostPort(host, strconv.Itoa(int(port))) - return -} diff --git a/tcp/client.go b/tcp/client.go index 33e9c98..b177fda 100644 --- a/tcp/client.go +++ b/tcp/client.go @@ -14,8 +14,8 @@ import ( "github.com/ginuerzh/gosocks4" "github.com/ginuerzh/gosocks5" + "github.com/ginuerzh/gost" "github.com/ginuerzh/gost/socks" - "github.com/ginuerzh/gost/ssocks" "github.com/go-log/log" ss "github.com/shadowsocks/shadowsocks-go/shadowsocks" ) @@ -45,8 +45,9 @@ func (c *nodeClient) Dial(conn net.Conn, addr string) (net.Conn, error) { gosocks5.MethodUserPass, socks.MethodTLS, ) - if len(c.options.users) > 0 { - selector.User = &c.options.users[0] + users := c.options.BaseOptions().Users + if len(users) > 0 { + selector.User = &users[0] } cc := gosocks5.ClientConn(conn, selector) @@ -69,9 +70,10 @@ func (c *nodeClient) dial(conn net.Conn, addr string) (net.Conn, error) { } var method, password string - if len(c.options.users) > 0 { - method = c.options.users[0].Username() - password, _ = c.options.users[0].Password() + users := c.options.BaseOptions().Users + if len(users) > 0 { + method = users[0].Username() + password, _ = users[0].Password() } cipher, err := ss.NewCipher(method, password) @@ -83,7 +85,7 @@ func (c *nodeClient) dial(conn net.Conn, addr string) (net.Conn, error) { if err != nil { return nil, err } - conn = ssocks.NewConn(sc) + conn = gost.ShadowConn(sc) case "socks5": host, port, err := net.SplitHostPort(addr) @@ -155,8 +157,9 @@ func (c *nodeClient) dial(conn net.Conn, addr string) (net.Conn, error) { Header: make(http.Header), } req.Header.Set("Proxy-Connection", "keep-alive") - if len(c.options.users) > 0 { - user := c.options.users[0] + users := c.options.BaseOptions().Users + if len(users) > 0 { + user := users[0] s := user.String() if _, set := user.Password(); !set { s += ":" diff --git a/tcp/options.go b/tcp/options.go index 063b3c9..045ffc1 100644 --- a/tcp/options.go +++ b/tcp/options.go @@ -1,32 +1,21 @@ package tcp import ( - "net/url" - "github.com/ginuerzh/gost" ) type nodeOptions struct { base *gost.BaseOptions - users []url.Userinfo `opt:"users"` // authentication for proxy - certFile string `opt:"cert"` - keyFile string `opt:"key"` - serverName string `opt:"server_name"` - secureVerify bool `opt:"secure"` + certFile string `opt:"cert"` + keyFile string `opt:"key"` + serverName string `opt:"server_name"` + secureVerify bool `opt:"secure"` } func (o *nodeOptions) BaseOptions() *gost.BaseOptions { return o.base } -func UsersOption(users ...url.Userinfo) gost.Option { - return func(opts gost.Options) { - if o, ok := opts.(*nodeOptions); ok { - o.users = users - } - } -} - func (o *nodeOptions) ServerNameOption(n string) gost.Option { return func(opts gost.Options) { if o, ok := opts.(*nodeOptions); ok { diff --git a/tcp/server.go b/tcp/server.go index d33447a..acee09c 100644 --- a/tcp/server.go +++ b/tcp/server.go @@ -4,13 +4,12 @@ import ( "bufio" "net" "net/http" - "net/url" - "weed-fs/go/glog" "github.com/ginuerzh/gosocks4" "github.com/ginuerzh/gosocks5" "github.com/ginuerzh/gost" "github.com/ginuerzh/gost/ssocks" + "github.com/go-log/log" ) type nodeServer struct { @@ -42,26 +41,28 @@ func (s *nodeServer) Run() error { if err != nil { return err } - go s.handleConn(conn) + go func(c net.Conn) { + defer c.Close() + s.handleConn(c) + }(conn) } } func (s *nodeServer) handleConn(conn net.Conn) { - defer conn.Close() switch s.options.BaseOptions().Protocol { case "ss": // shadowsocks - var cipher url.Userinfo - if len(s.options.users) > 0 { - cipher = s.options.users[0] + server, err := ssocks.NewServer(conn, s) + if err != nil { + log.Log("[ss]", err) } - server := ssocks.NewServer(conn, &cipher, s) server.Serve() return + case "http": req, err := http.ReadRequest(bufio.NewReader(conn)) if err != nil { - glog.V(LWARNING).Infoln("[http]", err) + log.Log("[http]", err) return } NewHttpServer(conn, s).HandleRequest(req) @@ -70,7 +71,7 @@ func (s *nodeServer) handleConn(conn net.Conn) { conn = gosocks5.ServerConn(conn, s.selector) req, err := gosocks5.ReadRequest(conn) if err != nil { - glog.V(LWARNING).Infoln("[socks5]", err) + log.Log("[socks5]", err) return } NewSocks5Server(conn, s).HandleRequest(req) @@ -78,7 +79,7 @@ func (s *nodeServer) handleConn(conn net.Conn) { case "socks4", "socks4a": req, err := gosocks4.ReadRequest(conn) if err != nil { - glog.V(LWARNING).Infoln("[socks4]", err) + log.Log("[socks4]", err) return } NewSocks4Server(conn, s).HandleRequest(req) @@ -88,7 +89,7 @@ func (s *nodeServer) handleConn(conn net.Conn) { br := bufio.NewReader(conn) b, err := br.Peek(1) if err != nil { - glog.V(LWARNING).Infoln(err) + log.Log(err) return } @@ -96,7 +97,7 @@ func (s *nodeServer) handleConn(conn net.Conn) { case gosocks4.Ver4: req, err := gosocks4.ReadRequest(br) if err != nil { - glog.V(LWARNING).Infoln("[socks4]", err) + log.Log("[socks4]", err) return } NewSocks4Server(conn, s).HandleRequest(req) @@ -104,24 +105,24 @@ func (s *nodeServer) handleConn(conn net.Conn) { case gosocks5.Ver5: methods, err := gosocks5.ReadMethods(br) if err != nil { - glog.V(LWARNING).Infoln("[socks5]", err) + log.Log("[socks5]", err) return } method := s.selector.Select(methods...) if _, err := conn.Write([]byte{gosocks5.Ver5, method}); err != nil { - glog.V(LWARNING).Infoln("[socks5] select:", err) + log.Log("[socks5] select:", err) return } c, err := s.selector.OnSelected(method, conn) if err != nil { - glog.V(LWARNING).Infoln("[socks5] onselected:", err) + log.Log("[socks5] onselected:", err) return } conn = c req, err := gosocks5.ReadRequest(conn) if err != nil { - glog.V(LWARNING).Infoln("[socks5] request:", err) + log.Log("[socks5] request:", err) return } NewSocks5Server(conn, s).HandleRequest(req) @@ -129,7 +130,7 @@ func (s *nodeServer) handleConn(conn net.Conn) { default: // http req, err := http.ReadRequest(br) if err != nil { - glog.V(LWARNING).Infoln("[http]", err) + log.Log("[http]", err) return } NewHttpServer(conn, s).HandleRequest(req)