From f5a20fd0fc4048ca61bcd4933b1322682ad7c2a6 Mon Sep 17 00:00:00 2001 From: ginuerzh Date: Thu, 16 Nov 2023 20:36:17 +0800 Subject: [PATCH 1/3] remove nodelay option for tunnel --- connector/relay/conn.go | 16 ++-------- connector/tunnel/conn.go | 55 ++--------------------------------- connector/tunnel/connector.go | 34 +++++----------------- connector/tunnel/metadata.go | 2 -- internal/util/relay/conn.go | 24 +++++++++++++++ 5 files changed, 35 insertions(+), 96 deletions(-) diff --git a/connector/relay/conn.go b/connector/relay/conn.go index 4e9cc4f..e2d16a2 100644 --- a/connector/relay/conn.go +++ b/connector/relay/conn.go @@ -13,6 +13,7 @@ import ( "github.com/go-gost/core/common/bufpool" mdata "github.com/go-gost/core/metadata" "github.com/go-gost/relay" + xrelay "github.com/go-gost/x/internal/util/relay" ) type tcpConn struct { @@ -129,7 +130,7 @@ func readResponse(r io.Reader) (err error) { } if resp.Status != relay.StatusOK { - err = fmt.Errorf("status %d", resp.Status) + err = fmt.Errorf("%d %s", resp.Status, xrelay.StatusText(resp.Status)) return } return nil @@ -223,16 +224,3 @@ func (c *bindUDPConn) RemoteAddr() net.Addr { func (c *bindUDPConn) Metadata() mdata.Metadata { return c.md } - -type bindAddr struct { - network string - addr string -} - -func (p *bindAddr) Network() string { - return p.network -} - -func (p *bindAddr) String() string { - return p.addr -} diff --git a/connector/tunnel/conn.go b/connector/tunnel/conn.go index cd712b2..2a025bc 100644 --- a/connector/tunnel/conn.go +++ b/connector/tunnel/conn.go @@ -1,67 +1,24 @@ package tunnel import ( - "bytes" "encoding/binary" "errors" "fmt" "io" "math" "net" - "sync" "github.com/go-gost/core/common/bufpool" mdata "github.com/go-gost/core/metadata" "github.com/go-gost/relay" + xrelay "github.com/go-gost/x/internal/util/relay" ) -type tcpConn struct { - net.Conn - wbuf *bytes.Buffer - once sync.Once -} - -func (c *tcpConn) Read(b []byte) (n int, err error) { - c.once.Do(func() { - if c.wbuf != nil { - err = readResponse(c.Conn) - } - }) - - if err != nil { - return - } - return c.Conn.Read(b) -} - -func (c *tcpConn) Write(b []byte) (n int, err error) { - n = len(b) // force byte length consistent - if c.wbuf != nil && c.wbuf.Len() > 0 { - c.wbuf.Write(b) // append the data to the cached header - _, err = c.Conn.Write(c.wbuf.Bytes()) - c.wbuf.Reset() - return - } - _, err = c.Conn.Write(b) - return -} - type udpConn struct { net.Conn - wbuf *bytes.Buffer - once sync.Once } func (c *udpConn) Read(b []byte) (n int, err error) { - c.once.Do(func() { - if c.wbuf != nil { - err = readResponse(c.Conn) - } - }) - if err != nil { - return - } - var bb [2]byte _, err = io.ReadFull(c.Conn, bb[:]) if err != nil { @@ -88,14 +45,6 @@ func (c *udpConn) Write(b []byte) (n int, err error) { } n = len(b) - if c.wbuf != nil && c.wbuf.Len() > 0 { - var bb [2]byte - binary.BigEndian.PutUint16(bb[:], uint16(len(b))) - c.wbuf.Write(bb[:]) - c.wbuf.Write(b) // append the data to the cached header - _, err = c.wbuf.WriteTo(c.Conn) - return - } var bb [2]byte binary.BigEndian.PutUint16(bb[:], uint16(len(b))) @@ -119,7 +68,7 @@ func readResponse(r io.Reader) (err error) { } if resp.Status != relay.StatusOK { - err = fmt.Errorf("status %d", resp.Status) + err = fmt.Errorf("%d %s", resp.Status, xrelay.StatusText(resp.Status)) return } return nil diff --git a/connector/tunnel/connector.go b/connector/tunnel/connector.go index 824cf28..a427dfd 100644 --- a/connector/tunnel/connector.go +++ b/connector/tunnel/connector.go @@ -1,7 +1,6 @@ package tunnel import ( - "bytes" "context" "fmt" "net" @@ -90,39 +89,20 @@ func (c *tunnelConnector) Connect(ctx context.Context, conn net.Conn, network, a ID: c.md.tunnelID.ID(), }) - if c.md.noDelay { - if _, err := req.WriteTo(conn); err != nil { - return nil, err - } - // drain the response - if err := readResponse(conn); err != nil { - return nil, err - } + if _, err := req.WriteTo(conn); err != nil { + return nil, err + } + // drain the response + if err := readResponse(conn); err != nil { + return nil, err } switch network { case "tcp", "tcp4", "tcp6": - if !c.md.noDelay { - cc := &tcpConn{ - Conn: conn, - wbuf: &bytes.Buffer{}, - } - if _, err := req.WriteTo(cc.wbuf); err != nil { - return nil, err - } - conn = cc - } case "udp", "udp4", "udp6": - cc := &udpConn{ + conn = &udpConn{ Conn: conn, } - if !c.md.noDelay { - cc.wbuf = &bytes.Buffer{} - if _, err := req.WriteTo(cc.wbuf); err != nil { - return nil, err - } - } - conn = cc default: err := fmt.Errorf("network %s is unsupported", network) log.Error(err) diff --git a/connector/tunnel/metadata.go b/connector/tunnel/metadata.go index 4839cbe..d678b62 100644 --- a/connector/tunnel/metadata.go +++ b/connector/tunnel/metadata.go @@ -18,13 +18,11 @@ var ( type metadata struct { connectTimeout time.Duration tunnelID relay.TunnelID - noDelay bool muxCfg *mux.Config } func (c *tunnelConnector) parseMetadata(md mdata.Metadata) (err error) { c.md.connectTimeout = mdutil.GetDuration(md, "connectTimeout") - c.md.noDelay = mdutil.GetBool(md, "nodelay") if s := mdutil.GetString(md, "tunnelID", "tunnel.id"); s != "" { uuid, err := uuid.Parse(s) diff --git a/internal/util/relay/conn.go b/internal/util/relay/conn.go index 2d25125..865094d 100644 --- a/internal/util/relay/conn.go +++ b/internal/util/relay/conn.go @@ -6,8 +6,32 @@ import ( "github.com/go-gost/core/common/bufpool" "github.com/go-gost/gosocks5" + "github.com/go-gost/relay" ) +func StatusText(code uint8) string { + switch code { + case relay.StatusBadRequest: + return "Bad Request" + case relay.StatusForbidden: + return "Forbidden" + case relay.StatusHostUnreachable: + return "Host Unreachable" + case relay.StatusInternalServerError: + return "Internal Server Error" + case relay.StatusNetworkUnreachable: + return "Network Unreachable" + case relay.StatusServiceUnavailable: + return "Service Unavailable" + case relay.StatusTimeout: + return "Timeout" + case relay.StatusUnauthorized: + return "Unauthorized" + default: + return "" + } +} + type udpTunConn struct { net.Conn taddr net.Addr From a465210bd6ad12635f7b1177401e1d3305f3b4b7 Mon Sep 17 00:00:00 2001 From: ginuerzh Date: Thu, 16 Nov 2023 20:38:16 +0800 Subject: [PATCH 2/3] fix forwarding node address parsing --- internal/net/addr.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/internal/net/addr.go b/internal/net/addr.go index b549a00..8b24a0b 100644 --- a/internal/net/addr.go +++ b/internal/net/addr.go @@ -12,6 +12,11 @@ import ( type AddrPortRange string func (p AddrPortRange) Addrs() (addrs []string) { + // ignore url scheme, e.g. http://, tls://, tcp://. + if strings.Contains(string(p), "://") { + return nil + } + h, sp, err := net.SplitHostPort(string(p)) if err != nil { return nil From 2c82233b4f2f242172aa57f84741c090090bc72c Mon Sep 17 00:00:00 2001 From: ginuerzh Date: Thu, 16 Nov 2023 21:42:11 +0800 Subject: [PATCH 3/3] add more config options for kcp --- dialer/kcp/metadata.go | 12 ++++++++++-- listener/kcp/metadata.go | 13 ++++++++++--- 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/dialer/kcp/metadata.go b/dialer/kcp/metadata.go index 126f473..a9a8c27 100644 --- a/dialer/kcp/metadata.go +++ b/dialer/kcp/metadata.go @@ -21,14 +21,14 @@ func (d *kcpDialer) parseMetadata(md mdata.Metadata) (err error) { handshakeTimeout = "handshakeTimeout" ) - if file := mdutil.GetString(md, configFile); file != "" { + if file := mdutil.GetString(md, "kcp.configFile", "configFile", "c"); file != "" { d.md.config, err = kcp_util.ParseFromFile(file) if err != nil { return } } - if m := mdutil.GetStringMap(md, config); len(m) > 0 { + if m := mdutil.GetStringMap(md, "kcp.config", "config"); len(m) > 0 { b, err := json.Marshal(m) if err != nil { return err @@ -42,6 +42,14 @@ func (d *kcpDialer) parseMetadata(md mdata.Metadata) (err error) { if d.md.config == nil { d.md.config = kcp_util.DefaultConfig } + d.md.config.TCP = mdutil.GetBool(md, "kcp.tcp", "tcp") + d.md.config.Key = mdutil.GetString(md, "kcp.key") + d.md.config.Crypt = mdutil.GetString(md, "kcp.crypt") + d.md.config.Mode = mdutil.GetString(md, "kcp.mode") + d.md.config.KeepAlive = mdutil.GetInt(md, "kcp.keepalive") + d.md.config.Interval = mdutil.GetInt(md, "kcp.interval") + d.md.config.MTU = mdutil.GetInt(md, "kcp.mtu") + d.md.config.SmuxVer = mdutil.GetInt(md, "kcp.smuxver") d.md.handshakeTimeout = mdutil.GetDuration(md, handshakeTimeout) return diff --git a/listener/kcp/metadata.go b/listener/kcp/metadata.go index c1358ce..6fe8c96 100644 --- a/listener/kcp/metadata.go +++ b/listener/kcp/metadata.go @@ -20,18 +20,17 @@ type metadata struct { func (l *kcpListener) parseMetadata(md mdata.Metadata) (err error) { const ( backlog = "backlog" - config = "config" configFile = "c" ) - if file := mdutil.GetString(md, configFile); file != "" { + if file := mdutil.GetString(md, "kcp.configFile", "configFile", "c"); file != "" { l.md.config, err = kcp_util.ParseFromFile(file) if err != nil { return } } - if m := mdutil.GetStringMap(md, config); len(m) > 0 { + if m := mdutil.GetStringMap(md, "kcp.config", "config"); len(m) > 0 { b, err := json.Marshal(m) if err != nil { return err @@ -46,6 +45,14 @@ func (l *kcpListener) parseMetadata(md mdata.Metadata) (err error) { if l.md.config == nil { l.md.config = kcp_util.DefaultConfig } + l.md.config.TCP = mdutil.GetBool(md, "kcp.tcp", "tcp") + l.md.config.Key = mdutil.GetString(md, "kcp.key") + l.md.config.Crypt = mdutil.GetString(md, "kcp.crypt") + l.md.config.Mode = mdutil.GetString(md, "kcp.mode") + l.md.config.KeepAlive = mdutil.GetInt(md, "kcp.keepalive") + l.md.config.Interval = mdutil.GetInt(md, "kcp.interval") + l.md.config.MTU = mdutil.GetInt(md, "kcp.mtu") + l.md.config.SmuxVer = mdutil.GetInt(md, "kcp.smuxVer") l.md.backlog = mdutil.GetInt(md, backlog) if l.md.backlog <= 0 {