diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 0a8df81..3967e86 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -38,34 +38,34 @@ jobs: # https://docs.github.com/en/free-pro-team@latest/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#changing-the-languages-that-are-analyzed steps: - - name: Checkout repository - uses: actions/checkout@v2.4.0 + - name: Checkout repository + uses: actions/checkout@v2.4.0 - # Initializes the CodeQL tools for scanning. - - name: Initialize CodeQL - uses: github/codeql-action/init@v1 - with: - languages: ${{ matrix.language }} - # If you wish to specify custom queries, you can do so here or in a config file. - # By default, queries listed here will override any specified in a config file. - # Prefix the list here with "+" to use these queries and those in the config file. - # queries: ./path/to/local/query, your-org/your-repo/queries@main + # Initializes the CodeQL tools for scanning. + - name: Initialize CodeQL + uses: github/codeql-action/init@v1 + with: + languages: ${{ matrix.language }} + # If you wish to specify custom queries, you can do so here or in a config file. + # By default, queries listed here will override any specified in a config file. + # Prefix the list here with "+" to use these queries and those in the config file. + # queries: ./path/to/local/query, your-org/your-repo/queries@main - # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). - # If this step fails, then you should remove it and run the build manually (see below) - - name: Autobuild - uses: github/codeql-action/autobuild@v1 + # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). + # If this step fails, then you should remove it and run the build manually (see below) + - name: Autobuild + uses: github/codeql-action/autobuild@v1 - # â„šī¸ Command-line programs to run using the OS shell. - # 📚 https://git.io/JvXDl + # â„šī¸ Command-line programs to run using the OS shell. + # 📚 https://git.io/JvXDl - # âœī¸ If the Autobuild fails above, remove it and uncomment the following three lines - # and modify them (or add more) to build your code if your project - # uses a compiled language + # âœī¸ If the Autobuild fails above, remove it and uncomment the following three lines + # and modify them (or add more) to build your code if your project + # uses a compiled language - #- run: | - # make bootstrap - # make release + #- run: | + # make bootstrap + # make release - - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v1 + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v1 diff --git a/.github/workflows/docker.yaml b/.github/workflows/docker.yaml index 8c6ae41..af12da9 100644 --- a/.github/workflows/docker.yaml +++ b/.github/workflows/docker.yaml @@ -26,7 +26,7 @@ jobs: uses: docker/setup-buildx-action@v1 - name: Login to DockerHub - uses: docker/login-action@v1.12.0 + uses: docker/login-action@v1.12.0 with: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_TOKEN }} diff --git a/cmd/client.go b/cmd/client.go index 088a865..ac9bc58 100644 --- a/cmd/client.go +++ b/cmd/client.go @@ -94,13 +94,14 @@ func client(config *clientConfig) { var aclEngine *acl.Engine if len(config.ACL) > 0 { var err error - aclEngine, err = acl.LoadFromFile(config.ACL, transport.DefaultTransport, func() (*geoip2.Reader, error) { - if len(config.MMDB) > 0 { - return loadMMDBReader(config.MMDB) - } else { - return loadMMDBReader(DefaultMMDBFilename) - } - }) + aclEngine, err = acl.LoadFromFile(config.ACL, transport.DefaultClientTransport.ResolveIPAddr, + func() (*geoip2.Reader, error) { + if len(config.MMDB) > 0 { + return loadMMDBReader(config.MMDB) + } else { + return loadMMDBReader(DefaultMMDBFilename) + } + }) if err != nil { logrus.WithFields(logrus.Fields{ "error": err, @@ -110,7 +111,7 @@ func client(config *clientConfig) { } // Client client, err := core.NewClient(config.Server, config.Protocol, auth, tlsConfig, quicConfig, - transport.DefaultTransport, uint64(config.UpMbps)*mbpsToBps, uint64(config.DownMbps)*mbpsToBps, + transport.DefaultClientTransport, uint64(config.UpMbps)*mbpsToBps, uint64(config.DownMbps)*mbpsToBps, func(refBPS uint64) congestion.CongestionControl { return hyCongestion.NewBrutalSender(congestion.ByteCount(refBPS)) }, obfuscator) @@ -130,8 +131,8 @@ func client(config *clientConfig) { return config.SOCKS5.User == user && config.SOCKS5.Password == password } } - socks5server, err := socks5.NewServer(client, transport.DefaultTransport, config.SOCKS5.Listen, authFunc, - time.Duration(config.SOCKS5.Timeout)*time.Second, aclEngine, config.SOCKS5.DisableUDP, + socks5server, err := socks5.NewServer(client, transport.DefaultClientTransport, config.SOCKS5.Listen, + authFunc, time.Duration(config.SOCKS5.Timeout)*time.Second, aclEngine, config.SOCKS5.DisableUDP, func(addr net.Addr, reqAddr string, action acl.Action, arg string) { logrus.WithFields(logrus.Fields{ "action": actionToString(action, arg), @@ -186,7 +187,7 @@ func client(config *clientConfig) { return config.HTTP.User == user && config.HTTP.Password == password } } - proxy, err := hyHTTP.NewProxyHTTPServer(client, transport.DefaultTransport, + proxy, err := hyHTTP.NewProxyHTTPServer(client, transport.DefaultClientTransport, time.Duration(config.HTTP.Timeout)*time.Second, aclEngine, func(reqAddr string, action acl.Action, arg string) { logrus.WithFields(logrus.Fields{ @@ -214,8 +215,7 @@ func client(config *clientConfig) { if timeout == 0 { timeout = 300 * time.Second } - tunServer, err := tun.NewServer(client, transport.DefaultTransport, - time.Duration(config.TUN.Timeout)*time.Second, + tunServer, err := tun.NewServer(client, time.Duration(config.TUN.Timeout)*time.Second, config.TUN.Name, config.TUN.Address, config.TUN.Gateway, config.TUN.Mask, config.TUN.DNS, config.TUN.Persist) if err != nil { logrus.WithField("error", err).Fatal("Failed to initialize TUN server") @@ -267,8 +267,7 @@ 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, + rl, err := relay.NewTCPRelay(client, tcpr.Listen, tcpr.Remote, time.Duration(tcpr.Timeout)*time.Second, func(addr net.Addr) { logrus.WithFields(logrus.Fields{ @@ -307,8 +306,7 @@ 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, + rl, err := relay.NewUDPRelay(client, udpr.Listen, udpr.Remote, time.Duration(udpr.Timeout)*time.Second, func(addr net.Addr) { logrus.WithFields(logrus.Fields{ @@ -338,8 +336,8 @@ func client(config *clientConfig) { if len(config.TCPTProxy.Listen) > 0 { go func() { - rl, err := tproxy.NewTCPTProxy(client, transport.DefaultTransport, - config.TCPTProxy.Listen, time.Duration(config.TCPTProxy.Timeout)*time.Second, + rl, err := tproxy.NewTCPTProxy(client, config.TCPTProxy.Listen, + time.Duration(config.TCPTProxy.Timeout)*time.Second, func(addr, reqAddr net.Addr) { logrus.WithFields(logrus.Fields{ "src": addr.String(), @@ -370,8 +368,8 @@ func client(config *clientConfig) { if len(config.UDPTProxy.Listen) > 0 { go func() { - rl, err := tproxy.NewUDPTProxy(client, transport.DefaultTransport, - config.UDPTProxy.Listen, time.Duration(config.UDPTProxy.Timeout)*time.Second, + rl, err := tproxy.NewUDPTProxy(client, config.UDPTProxy.Listen, + time.Duration(config.UDPTProxy.Timeout)*time.Second, func(addr net.Addr) { logrus.WithFields(logrus.Fields{ "src": addr.String(), diff --git a/cmd/resolver.go b/cmd/resolver.go new file mode 100644 index 0000000..f60442d --- /dev/null +++ b/cmd/resolver.go @@ -0,0 +1,21 @@ +package main + +import ( + "context" + "github.com/tobyxdd/hysteria/pkg/utils" + "net" +) + +func setResolver(dns string) { + if _, _, err := utils.SplitHostPort(dns); err != nil { + // Append the default DNS port + dns = net.JoinHostPort(dns, "53") + } + dialer := net.Dialer{} + net.DefaultResolver = &net.Resolver{ + PreferGo: true, + Dial: func(ctx context.Context, network, address string) (net.Conn, error) { + return dialer.DialContext(ctx, network, dns) + }, + } +} diff --git a/cmd/server.go b/cmd/server.go index a4529bb..427dc98 100644 --- a/cmd/server.go +++ b/cmd/server.go @@ -149,18 +149,19 @@ func server(config *serverConfig) { } // IPv6 only mode if config.IPv6Only { - transport.DefaultTransport = transport.IPv6OnlyTransport + transport.DefaultServerTransport.IPv6Only = true } // ACL var aclEngine *acl.Engine if len(config.ACL) > 0 { - aclEngine, err = acl.LoadFromFile(config.ACL, transport.DefaultTransport, func() (*geoip2.Reader, error) { - if len(config.MMDB) > 0 { - return loadMMDBReader(config.MMDB) - } else { - return loadMMDBReader(DefaultMMDBFilename) - } - }) + aclEngine, err = acl.LoadFromFile(config.ACL, transport.DefaultServerTransport.ResolveIPAddr, + func() (*geoip2.Reader, error) { + if len(config.MMDB) > 0 { + return loadMMDBReader(config.MMDB) + } else { + return loadMMDBReader(DefaultMMDBFilename) + } + }) if err != nil { logrus.WithFields(logrus.Fields{ "error": err, @@ -179,7 +180,7 @@ func server(config *serverConfig) { logrus.WithField("error", err).Fatal("Prometheus HTTP server error") }() } - server, err := core.NewServer(config.Listen, config.Protocol, tlsConfig, quicConfig, transport.DefaultTransport, + server, err := core.NewServer(config.Listen, config.Protocol, tlsConfig, quicConfig, transport.DefaultServerTransport, uint64(config.UpMbps)*mbpsToBps, uint64(config.DownMbps)*mbpsToBps, func(refBPS uint64) congestion.CongestionControl { return hyCongestion.NewBrutalSender(congestion.ByteCount(refBPS)) diff --git a/cmd/utils.go b/cmd/utils.go deleted file mode 100644 index 46a8858..0000000 --- a/cmd/utils.go +++ /dev/null @@ -1,18 +0,0 @@ -package main - -import ( - "context" - "net" -) - -func setResolver(addr string) { - if _, _, err := net.SplitHostPort(addr); err != nil { - // Append the default DNS port - addr = net.JoinHostPort(addr, "53") - } - net.DefaultResolver.PreferGo = true - net.DefaultResolver.Dial = func(ctx context.Context, network, address string) (net.Conn, error) { - d := net.Dialer{} - return d.DialContext(ctx, "udp", addr) - } -} diff --git a/docker-compose.yaml b/docker-compose.yaml index 964ccd8..80130c9 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -7,4 +7,4 @@ services: network_mode: "host" volumes: - ./hysteria.json:/etc/hysteria.json - command: ["-config","/etc/hysteria.json","server"] + command: [ "-config","/etc/hysteria.json","server" ] diff --git a/pkg/acl/engine.go b/pkg/acl/engine.go index ead693b..151df18 100644 --- a/pkg/acl/engine.go +++ b/pkg/acl/engine.go @@ -4,7 +4,6 @@ import ( "bufio" lru "github.com/hashicorp/golang-lru" "github.com/oschwald/geoip2-golang" - "github.com/tobyxdd/hysteria/pkg/transport" "net" "os" "strings" @@ -16,7 +15,7 @@ type Engine struct { DefaultAction Action Entries []Entry Cache *lru.ARCCache - Transport transport.Transport + ResolveIPAddr func(string) (*net.IPAddr, error) GeoIPReader *geoip2.Reader } @@ -25,7 +24,7 @@ type cacheEntry struct { Arg string } -func LoadFromFile(filename string, transport transport.Transport, geoIPLoadFunc func() (*geoip2.Reader, error)) (*Engine, error) { +func LoadFromFile(filename string, resolveIPAddr func(string) (*net.IPAddr, error), geoIPLoadFunc func() (*geoip2.Reader, error)) (*Engine, error) { f, err := os.Open(filename) if err != nil { return nil, err @@ -60,7 +59,7 @@ func LoadFromFile(filename string, transport transport.Transport, geoIPLoadFunc DefaultAction: ActionProxy, Entries: entries, Cache: cache, - Transport: transport, + ResolveIPAddr: resolveIPAddr, GeoIPReader: geoIPReader, }, nil } @@ -69,7 +68,7 @@ func (e *Engine) ResolveAndMatch(host string) (Action, string, *net.IPAddr, erro ip, zone := parseIPZone(host) if ip == nil { // Domain - ipAddr, err := e.Transport.LocalResolveIPAddr(host) + ipAddr, err := e.ResolveIPAddr(host) if v, ok := e.Cache.Get(host); ok { // Cache hit ce := v.(cacheEntry) diff --git a/pkg/core/client.go b/pkg/core/client.go index 157a718..51660ea 100644 --- a/pkg/core/client.go +++ b/pkg/core/client.go @@ -10,7 +10,7 @@ import ( "github.com/lucas-clemente/quic-go/congestion" "github.com/lunixbochs/struc" "github.com/tobyxdd/hysteria/pkg/obfs" - transport2 "github.com/tobyxdd/hysteria/pkg/transport" + "github.com/tobyxdd/hysteria/pkg/transport" "github.com/tobyxdd/hysteria/pkg/utils" "net" "strconv" @@ -25,7 +25,7 @@ var ( type CongestionFactory func(refBPS uint64) congestion.CongestionControl type Client struct { - transport transport2.Transport + transport *transport.ClientTransport serverAddr string protocol string sendBPS, recvBPS uint64 @@ -45,7 +45,7 @@ type Client struct { } func NewClient(serverAddr string, protocol string, auth []byte, tlsConfig *tls.Config, quicConfig *quic.Config, - transport transport2.Transport, sendBPS uint64, recvBPS uint64, congestionFactory CongestionFactory, + transport *transport.ClientTransport, sendBPS uint64, recvBPS uint64, congestionFactory CongestionFactory, obfuscator obfs.Obfuscator) (*Client, error) { c := &Client{ transport: transport, @@ -66,19 +66,10 @@ func NewClient(serverAddr string, protocol string, auth []byte, tlsConfig *tls.C } func (c *Client) connectToServer() error { - serverUDPAddr, err := c.transport.QUICResolveUDPAddr(c.serverAddr) + qs, err := c.transport.QUICDial(c.protocol, c.serverAddr, c.tlsConfig, c.quicConfig, c.obfuscator) if err != nil { return err } - pktConn, err := c.transport.QUICPacketConn(c.protocol, false, "", c.serverAddr, c.obfuscator) - if err != nil { - return err - } - qs, err := quic.Dial(pktConn, serverUDPAddr, c.serverAddr, c.tlsConfig, c.quicConfig) - if err != nil { - _ = pktConn.Close() - return err - } // Control stream ctx, ctxCancel := context.WithTimeout(context.Background(), protocolTimeout) stream, err := qs.OpenStreamSync(ctx) diff --git a/pkg/core/server.go b/pkg/core/server.go index 76b2565..3002bf4 100644 --- a/pkg/core/server.go +++ b/pkg/core/server.go @@ -10,7 +10,7 @@ import ( "github.com/prometheus/client_golang/prometheus" "github.com/tobyxdd/hysteria/pkg/acl" "github.com/tobyxdd/hysteria/pkg/obfs" - transport2 "github.com/tobyxdd/hysteria/pkg/transport" + "github.com/tobyxdd/hysteria/pkg/transport" "net" ) @@ -22,7 +22,7 @@ type UDPRequestFunc func(addr net.Addr, auth []byte, sessionID uint32) type UDPErrorFunc func(addr net.Addr, auth []byte, sessionID uint32, err error) type Server struct { - transport transport2.Transport + transport *transport.ServerTransport sendBPS, recvBPS uint64 congestionFactory CongestionFactory disableUDP bool @@ -41,20 +41,15 @@ type Server struct { listener quic.Listener } -func NewServer(addr string, protocol string, tlsConfig *tls.Config, quicConfig *quic.Config, transport transport2.Transport, +func NewServer(addr string, protocol string, tlsConfig *tls.Config, quicConfig *quic.Config, transport *transport.ServerTransport, sendBPS uint64, recvBPS uint64, congestionFactory CongestionFactory, disableUDP bool, aclEngine *acl.Engine, obfuscator obfs.Obfuscator, connectFunc ConnectFunc, disconnectFunc DisconnectFunc, tcpRequestFunc TCPRequestFunc, tcpErrorFunc TCPErrorFunc, udpRequestFunc UDPRequestFunc, udpErrorFunc UDPErrorFunc, promRegistry *prometheus.Registry) (*Server, error) { - pktConn, err := transport.QUICPacketConn(protocol, true, addr, "", obfuscator) + listener, err := transport.QUICListen(protocol, addr, tlsConfig, quicConfig, obfuscator) if err != nil { return nil, err } - listener, err := quic.Listen(pktConn, tlsConfig, quicConfig) - if err != nil { - _ = pktConn.Close() - return nil, err - } s := &Server{ listener: listener, transport: transport, diff --git a/pkg/core/server_client.go b/pkg/core/server_client.go index 857bb12..40e2649 100644 --- a/pkg/core/server_client.go +++ b/pkg/core/server_client.go @@ -19,7 +19,7 @@ const udpBufferSize = 65535 type serverClient struct { CS quic.Session - Transport transport.Transport + Transport *transport.ServerTransport Auth []byte ClientAddr net.Addr DisableUDP bool @@ -37,7 +37,7 @@ type serverClient struct { nextUDPSessionID uint32 } -func newServerClient(cs quic.Session, transport transport.Transport, auth []byte, disableUDP bool, ACLEngine *acl.Engine, +func newServerClient(cs quic.Session, transport *transport.ServerTransport, auth []byte, disableUDP bool, ACLEngine *acl.Engine, CTCPRequestFunc TCPRequestFunc, CTCPErrorFunc TCPErrorFunc, CUDPRequestFunc UDPRequestFunc, CUDPErrorFunc UDPErrorFunc, UpCounterVec, DownCounterVec *prometheus.CounterVec, @@ -133,7 +133,7 @@ func (c *serverClient) handleMessage(msg []byte) { if c.ACLEngine != nil { action, arg, ipAddr, err = c.ACLEngine.ResolveAndMatch(udpMsg.Host) } else { - ipAddr, err = c.Transport.LocalResolveIPAddr(udpMsg.Host) + ipAddr, err = c.Transport.ResolveIPAddr(udpMsg.Host) } if err != nil { return @@ -151,10 +151,13 @@ func (c *serverClient) handleMessage(msg []byte) { case acl.ActionBlock: // Do nothing case acl.ActionHijack: - hijackAddr := net.JoinHostPort(arg, strconv.Itoa(int(udpMsg.Port))) - addr, err := c.Transport.LocalResolveUDPAddr(hijackAddr) + hijackIPAddr, err := c.Transport.ResolveIPAddr(arg) if err == nil { - _, _ = conn.WriteToUDP(udpMsg.Data, addr) + _, _ = conn.WriteToUDP(udpMsg.Data, &net.UDPAddr{ + IP: hijackIPAddr.IP, + Port: int(udpMsg.Port), + Zone: hijackIPAddr.Zone, + }) if c.UpCounter != nil { c.UpCounter.Add(float64(len(udpMsg.Data))) } @@ -173,7 +176,7 @@ func (c *serverClient) handleTCP(stream quic.Stream, host string, port uint16) { if c.ACLEngine != nil { action, arg, ipAddr, err = c.ACLEngine.ResolveAndMatch(host) } else { - ipAddr, err = c.Transport.LocalResolveIPAddr(host) + ipAddr, err = c.Transport.ResolveIPAddr(host) } if err != nil { _ = struc.Pack(stream, &serverResponse{ @@ -188,7 +191,7 @@ func (c *serverClient) handleTCP(stream quic.Stream, host string, port uint16) { var conn net.Conn // Connection to be piped switch action { case acl.ActionDirect, acl.ActionProxy: // Treat proxy as direct on server side - conn, err = c.Transport.LocalDialTCP(nil, &net.TCPAddr{ + conn, err = c.Transport.DialTCP(&net.TCPAddr{ IP: ipAddr.IP, Port: int(port), Zone: ipAddr.Zone, @@ -208,8 +211,20 @@ func (c *serverClient) handleTCP(stream quic.Stream, host string, port uint16) { }) return case acl.ActionHijack: - hijackAddr := net.JoinHostPort(arg, strconv.Itoa(int(port))) - conn, err = c.Transport.LocalDial("tcp", hijackAddr) + hijackIPAddr, err := c.Transport.ResolveIPAddr(arg) + if err != nil { + _ = struc.Pack(stream, &serverResponse{ + OK: false, + Message: err.Error(), + }) + c.CTCPErrorFunc(c.ClientAddr, c.Auth, addrStr, err) + return + } + conn, err = c.Transport.DialTCP(&net.TCPAddr{ + IP: hijackIPAddr.IP, + Port: int(port), + Zone: hijackIPAddr.Zone, + }) if err != nil { _ = struc.Pack(stream, &serverResponse{ OK: false, @@ -249,7 +264,7 @@ func (c *serverClient) handleTCP(stream quic.Stream, host string, port uint16) { func (c *serverClient) handleUDP(stream quic.Stream) { // Like in SOCKS5, the stream here is only used to maintain the UDP session. No need to read anything from it - conn, err := c.Transport.LocalListenUDP(nil) + conn, err := c.Transport.ListenUDP(nil) if err != nil { _ = struc.Pack(stream, &serverResponse{ OK: false, diff --git a/pkg/http/server.go b/pkg/http/server.go index b1c8368..b4d899e 100644 --- a/pkg/http/server.go +++ b/pkg/http/server.go @@ -7,7 +7,6 @@ import ( "github.com/tobyxdd/hysteria/pkg/utils" "net" "net/http" - "strconv" "time" "github.com/elazarl/goproxy/ext/auth" @@ -17,8 +16,8 @@ import ( "github.com/tobyxdd/hysteria/pkg/core" ) -func NewProxyHTTPServer(hyClient *core.Client, transport transport.Transport, idleTimeout time.Duration, aclEngine *acl.Engine, - newDialFunc func(reqAddr string, action acl.Action, arg string), +func NewProxyHTTPServer(hyClient *core.Client, transport *transport.ClientTransport, idleTimeout time.Duration, + aclEngine *acl.Engine, newDialFunc func(reqAddr string, action acl.Action, arg string), basicAuthFunc func(user, password string) bool) (*goproxy.ProxyHttpServer, error) { proxy := goproxy.NewProxyHttpServer() proxy.Logger = &nopLogger{} @@ -45,7 +44,7 @@ func NewProxyHTTPServer(hyClient *core.Client, transport transport.Transport, id if resErr != nil { return nil, resErr } - return transport.LocalDialTCP(nil, &net.TCPAddr{ + return transport.DialTCP(&net.TCPAddr{ IP: ipAddr.IP, Port: int(port), Zone: ipAddr.Zone, @@ -55,7 +54,15 @@ func NewProxyHTTPServer(hyClient *core.Client, transport transport.Transport, id case acl.ActionBlock: return nil, errors.New("blocked by ACL") case acl.ActionHijack: - return transport.LocalDial(network, net.JoinHostPort(arg, strconv.Itoa(int(port)))) + hijackIPAddr, err := transport.ResolveIPAddr(arg) + if err != nil { + return nil, err + } + return transport.DialTCP(&net.TCPAddr{ + IP: hijackIPAddr.IP, + Port: int(port), + Zone: hijackIPAddr.Zone, + }) default: return nil, fmt.Errorf("unknown action %d", action) } diff --git a/pkg/relay/tcp.go b/pkg/relay/tcp.go index b8dfaff..9e16349 100644 --- a/pkg/relay/tcp.go +++ b/pkg/relay/tcp.go @@ -2,7 +2,6 @@ package relay import ( "github.com/tobyxdd/hysteria/pkg/core" - "github.com/tobyxdd/hysteria/pkg/transport" "github.com/tobyxdd/hysteria/pkg/utils" "net" "time" @@ -10,7 +9,6 @@ import ( type TCPRelay struct { HyClient *core.Client - Transport transport.Transport ListenAddr *net.TCPAddr Remote string Timeout time.Duration @@ -19,15 +17,14 @@ type TCPRelay struct { ErrorFunc func(addr net.Addr, err error) } -func NewTCPRelay(hyClient *core.Client, transport transport.Transport, listen, remote string, timeout time.Duration, +func NewTCPRelay(hyClient *core.Client, listen, remote string, timeout time.Duration, connFunc func(addr net.Addr), errorFunc func(addr net.Addr, err error)) (*TCPRelay, error) { - tAddr, err := transport.LocalResolveTCPAddr(listen) + tAddr, err := net.ResolveTCPAddr("tcp", listen) if err != nil { return nil, err } r := &TCPRelay{ HyClient: hyClient, - Transport: transport, ListenAddr: tAddr, Remote: remote, Timeout: timeout, @@ -38,7 +35,7 @@ func NewTCPRelay(hyClient *core.Client, transport transport.Transport, listen, r } func (r *TCPRelay) ListenAndServe() error { - listener, err := r.Transport.LocalListenTCP(r.ListenAddr) + listener, err := net.ListenTCP("tcp", r.ListenAddr) if err != nil { return err } diff --git a/pkg/relay/udp.go b/pkg/relay/udp.go index 2e49d49..c1181d7 100644 --- a/pkg/relay/udp.go +++ b/pkg/relay/udp.go @@ -3,7 +3,6 @@ package relay import ( "errors" "github.com/tobyxdd/hysteria/pkg/core" - "github.com/tobyxdd/hysteria/pkg/transport" "net" "sync" "sync/atomic" @@ -16,7 +15,6 @@ var ErrTimeout = errors.New("inactivity timeout") type UDPRelay struct { HyClient *core.Client - Transport transport.Transport ListenAddr *net.UDPAddr Remote string Timeout time.Duration @@ -25,15 +23,14 @@ type UDPRelay struct { ErrorFunc func(addr net.Addr, err error) } -func NewUDPRelay(hyClient *core.Client, transport transport.Transport, listen, remote string, timeout time.Duration, +func NewUDPRelay(hyClient *core.Client, listen, remote string, timeout time.Duration, connFunc func(addr net.Addr), errorFunc func(addr net.Addr, err error)) (*UDPRelay, error) { - uAddr, err := transport.LocalResolveUDPAddr(listen) + uAddr, err := net.ResolveUDPAddr("udp", listen) if err != nil { return nil, err } r := &UDPRelay{ HyClient: hyClient, - Transport: transport, ListenAddr: uAddr, Remote: remote, Timeout: timeout, @@ -52,7 +49,7 @@ type connEntry struct { } func (r *UDPRelay) ListenAndServe() error { - conn, err := r.Transport.LocalListenUDP(r.ListenAddr) + conn, err := net.ListenUDP("udp", r.ListenAddr) if err != nil { return err } diff --git a/pkg/socks5/server.go b/pkg/socks5/server.go index 62143dc..8adcc6a 100644 --- a/pkg/socks5/server.go +++ b/pkg/socks5/server.go @@ -26,7 +26,7 @@ var ( type Server struct { HyClient *core.Client - Transport transport.Transport + Transport *transport.ClientTransport AuthFunc func(username, password string) bool Method byte TCPAddr *net.TCPAddr @@ -42,13 +42,13 @@ type Server struct { tcpListener *net.TCPListener } -func NewServer(hyClient *core.Client, transport transport.Transport, addr string, +func NewServer(hyClient *core.Client, transport *transport.ClientTransport, addr string, authFunc func(username, password string) bool, tcpTimeout time.Duration, aclEngine *acl.Engine, disableUDP bool, tcpReqFunc func(addr net.Addr, reqAddr string, action acl.Action, arg string), tcpErrorFunc func(addr net.Addr, reqAddr string, err error), udpAssocFunc func(addr net.Addr), udpErrorFunc func(addr net.Addr, err error)) (*Server, error) { - tAddr, err := transport.LocalResolveTCPAddr(addr) + tAddr, err := net.ResolveTCPAddr("tcp", addr) if err != nil { return nil, err } @@ -118,7 +118,7 @@ func (s *Server) negotiate(c *net.TCPConn) error { func (s *Server) ListenAndServe() error { var err error - s.tcpListener, err = s.Transport.LocalListenTCP(s.TCPAddr) + s.tcpListener, err = net.ListenTCP("tcp", s.TCPAddr) if err != nil { return err } @@ -187,7 +187,7 @@ func (s *Server) handleTCP(c *net.TCPConn, r *socks5.Request) error { closeErr = resErr return resErr } - rc, err := s.Transport.LocalDialTCP(nil, &net.TCPAddr{ + rc, err := s.Transport.DialTCP(&net.TCPAddr{ IP: ipAddr.IP, Port: int(port), Zone: ipAddr.Zone, @@ -217,7 +217,17 @@ func (s *Server) handleTCP(c *net.TCPConn, r *socks5.Request) error { closeErr = errors.New("blocked in ACL") return nil case acl.ActionHijack: - rc, err := s.Transport.LocalDial("tcp", net.JoinHostPort(arg, strconv.Itoa(int(port)))) + hijackIPAddr, err := s.Transport.ResolveIPAddr(arg) + if err != nil { + _ = sendReply(c, socks5.RepHostUnreachable) + closeErr = err + return err + } + rc, err := s.Transport.DialTCP(&net.TCPAddr{ + IP: hijackIPAddr.IP, + Port: int(port), + Zone: hijackIPAddr.Zone, + }) if err != nil { _ = sendReply(c, socks5.RepHostUnreachable) closeErr = err @@ -241,7 +251,7 @@ func (s *Server) handleUDP(c *net.TCPConn, r *socks5.Request) error { s.UDPErrorFunc(c.RemoteAddr(), closeErr) }() // Start local UDP server - udpConn, err := s.Transport.LocalListenUDP(&net.UDPAddr{ + udpConn, err := net.ListenUDP("udp", &net.UDPAddr{ IP: s.TCPAddr.IP, Zone: s.TCPAddr.Zone, }) @@ -254,7 +264,7 @@ func (s *Server) handleUDP(c *net.TCPConn, r *socks5.Request) error { // Local UDP relay conn for ACL Direct var localRelayConn *net.UDPConn if s.ACLEngine != nil { - localRelayConn, err = s.Transport.LocalListenUDP(nil) + localRelayConn, err = s.Transport.ListenUDP(nil) if err != nil { _ = sendReply(c, socks5.RepServerFailure) closeErr = err @@ -385,10 +395,13 @@ func (s *Server) udpServer(clientConn *net.UDPConn, localRelayConn *net.UDPConn, case acl.ActionBlock: // Do nothing case acl.ActionHijack: - hijackAddr := net.JoinHostPort(arg, strconv.Itoa(int(port))) - rAddr, err := s.Transport.LocalResolveUDPAddr(hijackAddr) + hijackIPAddr, err := s.Transport.ResolveIPAddr(arg) if err == nil { - _, _ = localRelayConn.WriteToUDP(d.Data, rAddr) + _, _ = localRelayConn.WriteToUDP(d.Data, &net.UDPAddr{ + IP: hijackIPAddr.IP, + Port: int(port), + Zone: hijackIPAddr.Zone, + }) } default: // Do nothing diff --git a/pkg/tproxy/tcp_linux.go b/pkg/tproxy/tcp_linux.go index 556f60e..3d8fc11 100644 --- a/pkg/tproxy/tcp_linux.go +++ b/pkg/tproxy/tcp_linux.go @@ -3,7 +3,6 @@ package tproxy import ( "github.com/LiamHaworth/go-tproxy" "github.com/tobyxdd/hysteria/pkg/core" - "github.com/tobyxdd/hysteria/pkg/transport" "github.com/tobyxdd/hysteria/pkg/utils" "net" "time" @@ -11,7 +10,6 @@ import ( type TCPTProxy struct { HyClient *core.Client - Transport transport.Transport ListenAddr *net.TCPAddr Timeout time.Duration @@ -19,16 +17,15 @@ type TCPTProxy struct { ErrorFunc func(addr, reqAddr net.Addr, err error) } -func NewTCPTProxy(hyClient *core.Client, transport transport.Transport, listen string, timeout time.Duration, +func NewTCPTProxy(hyClient *core.Client, listen string, timeout time.Duration, connFunc func(addr, reqAddr net.Addr), errorFunc func(addr, reqAddr net.Addr, err error)) (*TCPTProxy, error) { - tAddr, err := transport.LocalResolveTCPAddr(listen) + tAddr, err := net.ResolveTCPAddr("tcp", listen) if err != nil { return nil, err } r := &TCPTProxy{ HyClient: hyClient, - Transport: transport, ListenAddr: tAddr, Timeout: timeout, ConnFunc: connFunc, diff --git a/pkg/tproxy/tcp_stub.go b/pkg/tproxy/tcp_stub.go index 302c487..a527c07 100644 --- a/pkg/tproxy/tcp_stub.go +++ b/pkg/tproxy/tcp_stub.go @@ -1,3 +1,4 @@ +//go:build !linux // +build !linux package tproxy @@ -5,14 +6,13 @@ package tproxy import ( "errors" "github.com/tobyxdd/hysteria/pkg/core" - "github.com/tobyxdd/hysteria/pkg/transport" "net" "time" ) type TCPTProxy struct{} -func NewTCPTProxy(hyClient *core.Client, transport transport.Transport, listen string, timeout time.Duration, +func NewTCPTProxy(hyClient *core.Client, listen string, timeout time.Duration, connFunc func(addr, reqAddr net.Addr), errorFunc func(addr, reqAddr net.Addr, err error)) (*TCPTProxy, error) { return nil, errors.New("not supported on the current system") diff --git a/pkg/tproxy/udp_linux.go b/pkg/tproxy/udp_linux.go index 155d86c..d61da27 100644 --- a/pkg/tproxy/udp_linux.go +++ b/pkg/tproxy/udp_linux.go @@ -4,7 +4,6 @@ import ( "errors" "github.com/LiamHaworth/go-tproxy" "github.com/tobyxdd/hysteria/pkg/core" - "github.com/tobyxdd/hysteria/pkg/transport" "net" "sync" "sync/atomic" @@ -17,7 +16,6 @@ var ErrTimeout = errors.New("inactivity timeout") type UDPTProxy struct { HyClient *core.Client - Transport transport.Transport ListenAddr *net.UDPAddr Timeout time.Duration @@ -25,15 +23,14 @@ type UDPTProxy struct { ErrorFunc func(addr net.Addr, err error) } -func NewUDPTProxy(hyClient *core.Client, transport transport.Transport, listen string, timeout time.Duration, +func NewUDPTProxy(hyClient *core.Client, listen string, timeout time.Duration, connFunc func(addr net.Addr), errorFunc func(addr net.Addr, err error)) (*UDPTProxy, error) { - uAddr, err := transport.LocalResolveUDPAddr(listen) + uAddr, err := net.ResolveUDPAddr("udp", listen) if err != nil { return nil, err } r := &UDPTProxy{ HyClient: hyClient, - Transport: transport, ListenAddr: uAddr, Timeout: timeout, ConnFunc: connFunc, diff --git a/pkg/tproxy/udp_stub.go b/pkg/tproxy/udp_stub.go index a24a51d..cc33aed 100644 --- a/pkg/tproxy/udp_stub.go +++ b/pkg/tproxy/udp_stub.go @@ -1,3 +1,4 @@ +//go:build !linux // +build !linux package tproxy @@ -5,7 +6,6 @@ package tproxy import ( "errors" "github.com/tobyxdd/hysteria/pkg/core" - "github.com/tobyxdd/hysteria/pkg/transport" "net" "time" ) @@ -14,7 +14,7 @@ var ErrTimeout = errors.New("inactivity timeout") type UDPTProxy struct{} -func NewUDPTProxy(hyClient *core.Client, transport transport.Transport, listen string, timeout time.Duration, +func NewUDPTProxy(hyClient *core.Client, listen string, timeout time.Duration, connFunc func(addr net.Addr), errorFunc func(addr net.Addr, err error)) (*UDPTProxy, error) { return nil, errors.New("not supported on the current system") } diff --git a/pkg/transport/client.go b/pkg/transport/client.go new file mode 100644 index 0000000..ec91059 --- /dev/null +++ b/pkg/transport/client.go @@ -0,0 +1,96 @@ +package transport + +import ( + "crypto/tls" + "fmt" + "github.com/lucas-clemente/quic-go" + "github.com/tobyxdd/hysteria/pkg/conns/faketcp" + "github.com/tobyxdd/hysteria/pkg/conns/udp" + "github.com/tobyxdd/hysteria/pkg/conns/wechat" + "github.com/tobyxdd/hysteria/pkg/obfs" + "net" + "time" +) + +type ClientTransport struct { + Dialer *net.Dialer +} + +var DefaultClientTransport = &ClientTransport{ + Dialer: &net.Dialer{ + Timeout: 8 * time.Second, + }, +} + +func (ct *ClientTransport) quicPacketConn(proto string, server string, obfs obfs.Obfuscator) (net.PacketConn, error) { + if len(proto) == 0 || proto == "udp" { + conn, err := net.ListenUDP("udp", nil) + if err != nil { + return nil, err + } + if obfs != nil { + oc := udp.NewObfsUDPConn(conn, obfs) + return oc, nil + } else { + return conn, nil + } + } else if proto == "wechat-video" { + conn, err := net.ListenUDP("udp", nil) + if err != nil { + return nil, err + } + if obfs != nil { + oc := wechat.NewObfsWeChatUDPConn(conn, obfs) + return oc, nil + } else { + return conn, nil + } + } else if proto == "faketcp" { + var conn *faketcp.TCPConn + conn, err := faketcp.Dial("tcp", server) + if err != nil { + return nil, err + } + if obfs != nil { + oc := faketcp.NewObfsFakeTCPConn(conn, obfs) + return oc, nil + } else { + return conn, nil + } + } else { + return nil, fmt.Errorf("unsupported protocol: %s", proto) + } +} + +func (ct *ClientTransport) QUICDial(proto string, server string, tlsConfig *tls.Config, quicConfig *quic.Config, obfs obfs.Obfuscator) (quic.Session, error) { + serverUDPAddr, err := net.ResolveUDPAddr("udp", server) + if err != nil { + return nil, err + } + pktConn, err := ct.quicPacketConn(proto, server, obfs) + if err != nil { + return nil, err + } + qs, err := quic.Dial(pktConn, serverUDPAddr, server, tlsConfig, quicConfig) + if err != nil { + _ = pktConn.Close() + return nil, err + } + return qs, nil +} + +func (ct *ClientTransport) ResolveIPAddr(address string) (*net.IPAddr, error) { + return net.ResolveIPAddr("ip", address) +} + +func (ct *ClientTransport) DialTCP(raddr *net.TCPAddr) (*net.TCPConn, error) { + conn, err := ct.Dialer.Dial("tcp", raddr.String()) + if err != nil { + return nil, err + } + return conn.(*net.TCPConn), nil +} + +func (ct *ClientTransport) ListenUDP(laddr *net.UDPAddr) (*net.UDPConn, error) { + return net.ListenUDP("udp", laddr) +} diff --git a/pkg/transport/server.go b/pkg/transport/server.go new file mode 100644 index 0000000..42985d0 --- /dev/null +++ b/pkg/transport/server.go @@ -0,0 +1,105 @@ +package transport + +import ( + "crypto/tls" + "fmt" + "github.com/lucas-clemente/quic-go" + "github.com/tobyxdd/hysteria/pkg/conns/faketcp" + "github.com/tobyxdd/hysteria/pkg/conns/udp" + "github.com/tobyxdd/hysteria/pkg/conns/wechat" + "github.com/tobyxdd/hysteria/pkg/obfs" + "net" + "time" +) + +type ServerTransport struct { + Dialer *net.Dialer + IPv6Only bool +} + +var DefaultServerTransport = &ServerTransport{ + Dialer: &net.Dialer{ + Timeout: 8 * time.Second, + }, + IPv6Only: false, +} + +func (st *ServerTransport) quicPacketConn(proto string, laddr string, obfs obfs.Obfuscator) (net.PacketConn, error) { + if len(proto) == 0 || proto == "udp" { + laddrU, err := net.ResolveUDPAddr("udp", laddr) + if err != nil { + return nil, err + } + conn, err := net.ListenUDP("udp", laddrU) + if err != nil { + return nil, err + } + if obfs != nil { + oc := udp.NewObfsUDPConn(conn, obfs) + return oc, nil + } else { + return conn, nil + } + } else if proto == "wechat-video" { + laddrU, err := net.ResolveUDPAddr("udp", laddr) + if err != nil { + return nil, err + } + conn, err := net.ListenUDP("udp", laddrU) + if err != nil { + return nil, err + } + if obfs != nil { + oc := wechat.NewObfsWeChatUDPConn(conn, obfs) + return oc, nil + } else { + return conn, nil + } + } else if proto == "faketcp" { + conn, err := faketcp.Listen("tcp", laddr) + if err != nil { + return nil, err + } + if obfs != nil { + oc := faketcp.NewObfsFakeTCPConn(conn, obfs) + return oc, nil + } else { + return conn, nil + } + } else { + return nil, fmt.Errorf("unsupported protocol: %s", proto) + } +} + +func (ct *ServerTransport) QUICListen(proto string, listen string, tlsConfig *tls.Config, quicConfig *quic.Config, obfs obfs.Obfuscator) (quic.Listener, error) { + pktConn, err := ct.quicPacketConn(proto, listen, obfs) + if err != nil { + return nil, err + } + l, err := quic.Listen(pktConn, tlsConfig, quicConfig) + if err != nil { + _ = pktConn.Close() + return nil, err + } + return l, nil +} + +func (ct *ServerTransport) ResolveIPAddr(address string) (*net.IPAddr, error) { + if ct.IPv6Only { + return net.ResolveIPAddr("ip6", address) + } else { + return net.ResolveIPAddr("ip", address) + } +} + +func (ct *ServerTransport) DialTCP(raddr *net.TCPAddr) (*net.TCPConn, error) { + conn, err := ct.Dialer.Dial("tcp", raddr.String()) + if err != nil { + return nil, err + } + return conn.(*net.TCPConn), nil +} + +func (ct *ServerTransport) ListenUDP(laddr *net.UDPAddr) (*net.UDPConn, error) { + return net.ListenUDP("udp", laddr) +} diff --git a/pkg/transport/transport.go b/pkg/transport/transport.go deleted file mode 100644 index ada5568..0000000 --- a/pkg/transport/transport.go +++ /dev/null @@ -1,148 +0,0 @@ -package transport - -import ( - "fmt" - "github.com/tobyxdd/hysteria/pkg/conns/faketcp" - "github.com/tobyxdd/hysteria/pkg/conns/udp" - "github.com/tobyxdd/hysteria/pkg/conns/wechat" - "github.com/tobyxdd/hysteria/pkg/obfs" - "net" - "time" -) - -type Transport interface { - QUICResolveUDPAddr(address string) (*net.UDPAddr, error) - QUICPacketConn(proto string, server bool, laddr, raddr string, obfs obfs.Obfuscator) (net.PacketConn, error) - - LocalResolveIPAddr(address string) (*net.IPAddr, error) - LocalResolveTCPAddr(address string) (*net.TCPAddr, error) - LocalResolveUDPAddr(address string) (*net.UDPAddr, error) - LocalDial(network, address string) (net.Conn, error) - LocalDialTCP(laddr, raddr *net.TCPAddr) (*net.TCPConn, error) - LocalListenTCP(laddr *net.TCPAddr) (*net.TCPListener, error) - LocalListenUDP(laddr *net.UDPAddr) (*net.UDPConn, error) -} - -var DefaultTransport Transport = &defaultTransport{ - Timeout: 8 * time.Second, -} - -var IPv6OnlyTransport Transport = &ipv6OnlyTransport{ - defaultTransport{ - Timeout: 8 * time.Second, - }, -} - -type defaultTransport struct { - Timeout time.Duration -} - -func (t *defaultTransport) QUICResolveUDPAddr(address string) (*net.UDPAddr, error) { - return net.ResolveUDPAddr("udp", address) -} - -func (t *defaultTransport) QUICPacketConn(proto string, server bool, laddr, raddr string, obfs obfs.Obfuscator) (net.PacketConn, error) { - if len(proto) == 0 || proto == "udp" { - var laddrU *net.UDPAddr - if len(laddr) > 0 { - var err error - laddrU, err = t.QUICResolveUDPAddr(laddr) - if err != nil { - return nil, err - } - } - conn, err := net.ListenUDP("udp", laddrU) - if err != nil { - return nil, err - } - if obfs != nil { - oc := udp.NewObfsUDPConn(conn, obfs) - return oc, nil - } else { - return conn, nil - } - } else if proto == "wechat-video" { - var laddrU *net.UDPAddr - if len(laddr) > 0 { - var err error - laddrU, err = t.QUICResolveUDPAddr(laddr) - if err != nil { - return nil, err - } - } - conn, err := net.ListenUDP("udp", laddrU) - if err != nil { - return nil, err - } - if obfs != nil { - oc := wechat.NewObfsWeChatUDPConn(conn, obfs) - return oc, nil - } else { - return conn, nil - } - } else if proto == "faketcp" { - var conn *faketcp.TCPConn - var err error - if server { - conn, err = faketcp.Listen("tcp", laddr) - if err != nil { - return nil, err - } - } else { - conn, err = faketcp.Dial("tcp", raddr) - if err != nil { - return nil, err - } - } - if obfs != nil { - oc := faketcp.NewObfsFakeTCPConn(conn, obfs) - return oc, nil - } else { - return conn, nil - } - } else { - return nil, fmt.Errorf("unsupported protocol: %s", proto) - } -} - -func (t *defaultTransport) LocalResolveIPAddr(address string) (*net.IPAddr, error) { - return net.ResolveIPAddr("ip", address) -} - -func (t *defaultTransport) LocalResolveTCPAddr(address string) (*net.TCPAddr, error) { - return net.ResolveTCPAddr("tcp", address) -} - -func (t *defaultTransport) LocalResolveUDPAddr(address string) (*net.UDPAddr, error) { - return net.ResolveUDPAddr("udp", address) -} - -func (t *defaultTransport) LocalDial(network, address string) (net.Conn, error) { - dialer := &net.Dialer{Timeout: t.Timeout} - return dialer.Dial(network, address) -} - -func (t *defaultTransport) LocalDialTCP(laddr, raddr *net.TCPAddr) (*net.TCPConn, error) { - dialer := &net.Dialer{Timeout: t.Timeout, LocalAddr: laddr} - conn, err := dialer.Dial("tcp", raddr.String()) - if err != nil { - return nil, err - } - return conn.(*net.TCPConn), nil -} - -func (t *defaultTransport) LocalListenTCP(laddr *net.TCPAddr) (*net.TCPListener, error) { - return net.ListenTCP("tcp", laddr) -} - -func (t *defaultTransport) LocalListenUDP(laddr *net.UDPAddr) (*net.UDPConn, error) { - return net.ListenUDP("udp", laddr) -} - -type ipv6OnlyTransport struct { - defaultTransport -} - -func (t *ipv6OnlyTransport) LocalResolveIPAddr(address string) (*net.IPAddr, error) { - return net.ResolveIPAddr("ip6", address) -} diff --git a/pkg/tun/server.go b/pkg/tun/server.go index 8976a66..4dbf8c5 100644 --- a/pkg/tun/server.go +++ b/pkg/tun/server.go @@ -1,3 +1,4 @@ +//go:build cgo // +build cgo package tun @@ -6,7 +7,6 @@ import ( tun2socks "github.com/eycorsican/go-tun2socks/core" "github.com/eycorsican/go-tun2socks/tun" "github.com/tobyxdd/hysteria/pkg/core" - "github.com/tobyxdd/hysteria/pkg/transport" "io" "net" "sync" @@ -14,10 +14,9 @@ import ( ) type Server struct { - HyClient *core.Client - Timeout time.Duration - TunDev io.ReadWriteCloser - Transport transport.Transport + HyClient *core.Client + Timeout time.Duration + TunDev io.ReadWriteCloser RequestFunc func(addr net.Addr, reqAddr string) ErrorFunc func(addr net.Addr, reqAddr string, err error) @@ -30,12 +29,9 @@ const ( MTU = 1500 ) -func NewServerWithTunDev(hyClient *core.Client, transport transport.Transport, - timeout time.Duration, - tunDev io.ReadWriteCloser) (*Server, error) { +func NewServerWithTunDev(hyClient *core.Client, timeout time.Duration, tunDev io.ReadWriteCloser) (*Server, error) { s := &Server{ HyClient: hyClient, - Transport: transport, Timeout: timeout, TunDev: tunDev, udpConnMap: make(map[tun2socks.UDPConn]*udpConnInfo), @@ -43,14 +39,13 @@ func NewServerWithTunDev(hyClient *core.Client, transport transport.Transport, return s, nil } -func NewServer(hyClient *core.Client, transport transport.Transport, - timeout time.Duration, +func NewServer(hyClient *core.Client, timeout time.Duration, name, address, gateway, mask string, dnsServers []string, persist bool) (*Server, error) { tunDev, err := tun.OpenTunDevice(name, address, gateway, mask, dnsServers, persist) if err != nil { return nil, err } - return NewServerWithTunDev(hyClient, transport, timeout, tunDev) + return NewServerWithTunDev(hyClient, timeout, tunDev) } func (s *Server) ListenAndServe() error { diff --git a/pkg/tun/server_stub.go b/pkg/tun/server_stub.go index b5c0879..41159bf 100644 --- a/pkg/tun/server_stub.go +++ b/pkg/tun/server_stub.go @@ -1,3 +1,4 @@ +//go:build !cgo // +build !cgo package tun @@ -5,17 +6,15 @@ package tun import ( "errors" "github.com/tobyxdd/hysteria/pkg/core" - "github.com/tobyxdd/hysteria/pkg/transport" "io" "net" "time" ) type Server struct { - HyClient *core.Client - Timeout time.Duration - TunDev io.ReadWriteCloser - Transport transport.Transport + HyClient *core.Client + Timeout time.Duration + TunDev io.ReadWriteCloser RequestFunc func(addr net.Addr, reqAddr string) ErrorFunc func(addr net.Addr, reqAddr string, err error) @@ -25,14 +24,11 @@ const ( MTU = 1500 ) -func NewServerWithTunDev(hyClient *core.Client, transport transport.Transport, - timeout time.Duration, - tunDev io.ReadWriteCloser) (*Server, error) { +func NewServerWithTunDev(hyClient *core.Client, timeout time.Duration, tunDev io.ReadWriteCloser) (*Server, error) { return nil, errors.New("TUN mode is not available in this build") } -func NewServer(hyClient *core.Client, transport transport.Transport, - timeout time.Duration, +func NewServer(hyClient *core.Client, timeout time.Duration, name, address, gateway, mask string, dnsServers []string, persist bool) (*Server, error) { return nil, errors.New("TUN mode is not available in this build") } diff --git a/pkg/tun/tcp.go b/pkg/tun/tcp.go index 4e2fc86..f1bac1c 100644 --- a/pkg/tun/tcp.go +++ b/pkg/tun/tcp.go @@ -1,3 +1,4 @@ +//go:build cgo // +build cgo package tun diff --git a/pkg/tun/udp.go b/pkg/tun/udp.go index 1cfd898..e4a69f1 100644 --- a/pkg/tun/udp.go +++ b/pkg/tun/udp.go @@ -1,3 +1,4 @@ +//go:build cgo // +build cgo package tun