mirror of
https://github.com/cmz0228/hysteria-dev.git
synced 2025-07-25 20:38:35 +00:00
feat: transport refactorization
This commit is contained in:
50
.github/workflows/codeql-analysis.yml
vendored
50
.github/workflows/codeql-analysis.yml
vendored
@@ -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
|
||||
|
@@ -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(),
|
||||
|
21
cmd/resolver.go
Normal file
21
cmd/resolver.go
Normal file
@@ -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)
|
||||
},
|
||||
}
|
||||
}
|
@@ -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))
|
||||
|
18
cmd/utils.go
18
cmd/utils.go
@@ -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)
|
||||
}
|
||||
}
|
@@ -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" ]
|
||||
|
@@ -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)
|
||||
|
@@ -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)
|
||||
|
@@ -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,
|
||||
|
@@ -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,
|
||||
|
@@ -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)
|
||||
}
|
||||
|
@@ -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
|
||||
}
|
||||
|
@@ -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
|
||||
}
|
||||
|
@@ -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
|
||||
|
@@ -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,
|
||||
|
@@ -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")
|
||||
|
@@ -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,
|
||||
|
@@ -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")
|
||||
}
|
||||
|
96
pkg/transport/client.go
Normal file
96
pkg/transport/client.go
Normal file
@@ -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)
|
||||
}
|
105
pkg/transport/server.go
Normal file
105
pkg/transport/server.go
Normal file
@@ -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)
|
||||
}
|
@@ -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)
|
||||
}
|
@@ -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 {
|
||||
|
@@ -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")
|
||||
}
|
||||
|
@@ -1,3 +1,4 @@
|
||||
//go:build cgo
|
||||
// +build cgo
|
||||
|
||||
package tun
|
||||
|
@@ -1,3 +1,4 @@
|
||||
//go:build cgo
|
||||
// +build cgo
|
||||
|
||||
package tun
|
||||
|
Reference in New Issue
Block a user