diff --git a/README.md b/README.md index 4d7dfc8..0274950 100644 --- a/README.md +++ b/README.md @@ -280,16 +280,24 @@ hysteria_traffic_uplink_bytes_total{auth="aGFja2VyISE="} 37452 "dns": [ "8.8.8.8", "8.8.4.4" ], // TUN interface DNS, only applicable for Windows "persist": false // Persist TUN interface after exit, only applicable for Linux }, - "relay_tcp": { + "relay_tcps": [{ "listen": "127.0.0.1:2222", // TCP relay listen address "remote": "123.123.123.123:22", // TCP relay remote address "timeout": 300 // TCP timeout in seconds - }, - "relay_udp": { + },{ + "listen": "127.0.0.1:13389", // TCP relay listen address + "remote": "124.124.124.124:3389", // TCP relay remote address + "timeout": 300 // TCP timeout in seconds + }], + "relay_udps": [{ "listen": "127.0.0.1:5333", // UDP relay listen address "remote": "8.8.8.8:53", // UDP relay remote address "timeout": 60 // UDP session timeout in seconds - }, + },{ + "listen": "127.0.0.1:11080", // UDP relay listen address + "remote": "9.9.9.9.9:1080", // UDP relay remote address + "timeout": 60 // UDP session timeout in seconds + }], "tproxy_tcp": { "listen": "127.0.0.1:9000", // TCP TProxy listen address "timeout": 300 // TCP timeout in seconds diff --git a/README.zh.md b/README.zh.md index 0891d6d..26fd804 100644 --- a/README.zh.md +++ b/README.zh.md @@ -265,16 +265,24 @@ hysteria_traffic_uplink_bytes_total{auth="aGFja2VyISE="} 37452 "dns": [ "8.8.8.8", "8.8.4.4" ], // TUN 接口 DNS 服务器(仅适用于 Windows) "persist": false // 在程序退出之后保留接口(仅适用于 Linux) }, - "relay_tcp": { + "relay_tcps": [{ "listen": "127.0.0.1:2222", // TCP 转发监听地址 "remote": "123.123.123.123:22", // TCP 转发目标地址 "timeout": 300 // TCP 超时秒数 - }, - "relay_udp": { + },{ + "listen": "127.0.0.1:13389", // TCP 转发监听地址 + "remote": "124.124.124.124:3389", // TCP 转发目标地址 + "timeout": 300 // TCP 超时秒数 + }], + "relay_udps": [{ "listen": "127.0.0.1:5333", // UDP 转发监听地址 "remote": "8.8.8.8:53", // UDP 转发目标地址 "timeout": 60 // UDP 超时秒数 - }, + },{ + "listen": "127.0.0.1:11080", // UDP 转发监听地址 + "remote": "9.9.9.9.9:1080", // UDP 转发目标地址 + "timeout": 60 // UDP 超时秒数 + }], "tproxy_tcp": { "listen": "127.0.0.1:9000", // TCP 透明代理监听地址 "timeout": 300 // TCP 超时秒数 diff --git a/cmd/client.go b/cmd/client.go index 0fa84fe..782f637 100644 --- a/cmd/client.go +++ b/cmd/client.go @@ -3,6 +3,13 @@ package main import ( "crypto/tls" "crypto/x509" + "io" + "io/ioutil" + "net" + "net/http" + "strings" + "time" + "github.com/lucas-clemente/quic-go" "github.com/lucas-clemente/quic-go/congestion" "github.com/sirupsen/logrus" @@ -16,12 +23,6 @@ import ( "github.com/tobyxdd/hysteria/pkg/tproxy" "github.com/tobyxdd/hysteria/pkg/transport" "github.com/tobyxdd/hysteria/pkg/tun" - "io" - "io/ioutil" - "net" - "net/http" - "strings" - "time" ) func client(config *clientConfig) { @@ -244,6 +245,7 @@ func client(config *clientConfig) { }() } + //deprecated, but still support, compatibility if len(config.TCPRelay.Listen) > 0 { go func() { rl, err := relay.NewTCPRelay(client, transport.DefaultTransport, @@ -274,6 +276,39 @@ func client(config *clientConfig) { }() } + if len(config.TCPRelays) > 0 { + for _, tcpr := range config.TCPRelays { + go func(tcpr Relay) { + rl, err := relay.NewTCPRelay(client, transport.DefaultTransport, + tcpr.Listen, tcpr.Remote, + time.Duration(tcpr.Timeout)*time.Second, + func(addr net.Addr) { + logrus.WithFields(logrus.Fields{ + "src": addr.String(), + }).Debug("TCP relay request") + }, + func(addr net.Addr, err error) { + if err != io.EOF { + logrus.WithFields(logrus.Fields{ + "error": err, + "src": addr.String(), + }).Info("TCP relay error") + } else { + logrus.WithFields(logrus.Fields{ + "src": addr.String(), + }).Debug("TCP relay EOF") + } + }) + if err != nil { + logrus.WithField("error", err).Fatal("Failed to initialize TCP relay") + } + logrus.WithField("addr", tcpr.Listen).Info("TCP relay up and running") + errChan <- rl.ListenAndServe() + }(tcpr) + } + } + + // deprecated, but still support, compatibility if len(config.UDPRelay.Listen) > 0 { go func() { rl, err := relay.NewUDPRelay(client, transport.DefaultTransport, @@ -304,6 +339,38 @@ func client(config *clientConfig) { }() } + if len(config.UDPRelays) > 0 { + for _, udpr := range config.UDPRelays { + go func(udpr Relay) { + rl, err := relay.NewUDPRelay(client, transport.DefaultTransport, + udpr.Listen, udpr.Remote, + time.Duration(udpr.Timeout)*time.Second, + func(addr net.Addr) { + logrus.WithFields(logrus.Fields{ + "src": addr.String(), + }).Debug("UDP relay request") + }, + func(addr net.Addr, err error) { + if err != relay.ErrTimeout { + logrus.WithFields(logrus.Fields{ + "error": err, + "src": addr.String(), + }).Info("UDP relay error") + } else { + logrus.WithFields(logrus.Fields{ + "src": addr.String(), + }).Debug("UDP relay session closed") + } + }) + if err != nil { + logrus.WithField("error", err).Fatal("Failed to initialize UDP relay") + } + logrus.WithField("addr", udpr.Listen).Info("UDP relay up and running") + errChan <- rl.ListenAndServe() + }(udpr) + } + } + if len(config.TCPTProxy.Listen) > 0 { go func() { rl, err := tproxy.NewTCPTProxy(client, transport.DefaultTransport, diff --git a/cmd/config.go b/cmd/config.go index 5d88dbc..019922b 100644 --- a/cmd/config.go +++ b/cmd/config.go @@ -4,6 +4,7 @@ import ( "errors" "fmt" + "github.com/sirupsen/logrus" "github.com/yosuke-furukawa/json5/encoding/json5" ) @@ -107,9 +108,9 @@ type clientConfig struct { Persist bool `json:"persist"` } `json:"tun"` TCPRelays []Relay `json:"relay_tcps"` - TCPRelay Relay `json:"relay_tcp"` + TCPRelay Relay `json:"relay_tcp"` // deprecated, but still support, compatibility UDPRelays []Relay `json:"relay_udps"` - UDPRelay Relay `json:"relay_udp"` + UDPRelay Relay `json:"relay_udp"` // deprecated, but still support, compatibility TCPTProxy struct { Listen string `json:"listen"` Timeout int `json:"timeout"` @@ -134,6 +135,7 @@ type clientConfig struct { func (c *clientConfig) Check() error { if len(c.SOCKS5.Listen) == 0 && len(c.HTTP.Listen) == 0 && len(c.TUN.Name) == 0 && len(c.TCPRelay.Listen) == 0 && len(c.UDPRelay.Listen) == 0 && + len(c.TCPRelays) == 0 && len(c.UDPRelays) == 0 && len(c.TCPTProxy.Listen) == 0 && len(c.UDPTProxy.Listen) == 0 { return errors.New("please enable at least one mode") } @@ -174,6 +176,12 @@ func (c *clientConfig) Check() error { (c.ReceiveWindow != 0 && c.ReceiveWindow < 65536) { return errors.New("invalid receive window size") } + if len(c.TCPRelay.Listen) > 0 { + logrus.Warn("config 'relay_tcp' is deprecated, please use 'relay_tcps' instead of it") + } + if len(c.UDPRelay.Listen) > 0 { + logrus.Warn("config 'relay_udp' is deprecated, please use 'relay_udps' instead of it") + } return nil } diff --git a/cmd/main.go b/cmd/main.go index b7e1b1d..5ab74bd 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -9,9 +9,8 @@ import ( nested "github.com/antonfisher/nested-logrus-formatter" "github.com/sirupsen/logrus" - "github.com/yosuke-furukawa/json5/encoding/json5" - "github.com/urfave/cli/v2" + "github.com/yosuke-furukawa/json5/encoding/json5" ) var (