mirror of
https://github.com/apernet/hysteria.git
synced 2025-04-03 20:47:38 +03:00
feat: server resolver config options
This commit is contained in:
parent
be76f0650e
commit
7c94b072ed
5 changed files with 97 additions and 5 deletions
|
@ -19,6 +19,7 @@ import (
|
|||
"github.com/apernet/hysteria/core/server"
|
||||
"github.com/apernet/hysteria/extras/auth"
|
||||
"github.com/apernet/hysteria/extras/obfs"
|
||||
"github.com/apernet/hysteria/extras/outbounds"
|
||||
)
|
||||
|
||||
var serverCmd = &cobra.Command{
|
||||
|
@ -41,6 +42,7 @@ type serverConfig struct {
|
|||
DisableUDP bool `mapstructure:"disableUDP"`
|
||||
UDPIdleTimeout time.Duration `mapstructure:"udpIdleTimeout"`
|
||||
Auth serverConfigAuth `mapstructure:"auth"`
|
||||
Resolver serverConfigResolver `mapstructure:"resolver"`
|
||||
Masquerade serverConfigMasquerade `mapstructure:"masquerade"`
|
||||
}
|
||||
|
||||
|
@ -89,6 +91,22 @@ type serverConfigAuth struct {
|
|||
Password string `mapstructure:"password"`
|
||||
}
|
||||
|
||||
type serverConfigResolverTCP struct {
|
||||
Addr string `mapstructure:"addr"`
|
||||
Timeout time.Duration `mapstructure:"timeout"`
|
||||
}
|
||||
|
||||
type serverConfigResolverUDP struct {
|
||||
Addr string `mapstructure:"addr"`
|
||||
Timeout time.Duration `mapstructure:"timeout"`
|
||||
}
|
||||
|
||||
type serverConfigResolver struct {
|
||||
Type string `mapstructure:"type"`
|
||||
TCP serverConfigResolverTCP `mapstructure:"tcp"`
|
||||
UDP serverConfigResolverUDP `mapstructure:"udp"`
|
||||
}
|
||||
|
||||
type serverConfigMasqueradeFile struct {
|
||||
Dir string `mapstructure:"dir"`
|
||||
}
|
||||
|
@ -214,6 +232,36 @@ func (c *serverConfig) fillQUICConfig(hyConfig *server.Config) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (c *serverConfig) fillOutboundConfig(hyConfig *server.Config) error {
|
||||
// Resolver, ACL, actual outbound are all implemented through the Outbound interface.
|
||||
// Depending on the config, we build a chain like this:
|
||||
// Resolver(ACL(Outbounds...))
|
||||
|
||||
// Outbounds
|
||||
ob := outbounds.NewDirectOutboundSimple(outbounds.DirectOutboundModeAuto)
|
||||
|
||||
// Resolver
|
||||
switch strings.ToLower(c.Resolver.Type) {
|
||||
case "", "system":
|
||||
// Do nothing. DirectOutbound will use system resolver by default.
|
||||
case "tcp":
|
||||
if c.Resolver.TCP.Addr == "" {
|
||||
return configError{Field: "resolver.tcp.addr", Err: errors.New("empty resolver address")}
|
||||
}
|
||||
ob = outbounds.NewStandardResolverTCP(c.Resolver.TCP.Addr, c.Resolver.TCP.Timeout, ob)
|
||||
case "udp":
|
||||
if c.Resolver.UDP.Addr == "" {
|
||||
return configError{Field: "resolver.udp.addr", Err: errors.New("empty resolver address")}
|
||||
}
|
||||
ob = outbounds.NewStandardResolverUDP(c.Resolver.UDP.Addr, c.Resolver.UDP.Timeout, ob)
|
||||
default:
|
||||
return configError{Field: "resolver.type", Err: errors.New("unsupported resolver type")}
|
||||
}
|
||||
|
||||
hyConfig.Outbound = &outbounds.PluggableOutboundAdapter{PluggableOutbound: ob}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *serverConfig) fillBandwidthConfig(hyConfig *server.Config) error {
|
||||
var err error
|
||||
if c.Bandwidth.Up != "" {
|
||||
|
@ -308,6 +356,7 @@ func (c *serverConfig) Config() (*server.Config, error) {
|
|||
c.fillConn,
|
||||
c.fillTLSConfig,
|
||||
c.fillQUICConfig,
|
||||
c.fillOutboundConfig,
|
||||
c.fillBandwidthConfig,
|
||||
c.fillDisableUDP,
|
||||
c.fillUDPIdleTimeout,
|
||||
|
@ -320,6 +369,7 @@ func (c *serverConfig) Config() (*server.Config, error) {
|
|||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
return hyConfig, nil
|
||||
}
|
||||
|
||||
|
|
|
@ -61,6 +61,17 @@ func TestServerConfig(t *testing.T) {
|
|||
Type: "password",
|
||||
Password: "goofy_ahh_password",
|
||||
},
|
||||
Resolver: serverConfigResolver{
|
||||
Type: "udp",
|
||||
TCP: serverConfigResolverTCP{
|
||||
Addr: "123.123.123.123:5353",
|
||||
Timeout: 4 * time.Second,
|
||||
},
|
||||
UDP: serverConfigResolverUDP{
|
||||
Addr: "4.6.8.0:53",
|
||||
Timeout: 2 * time.Second,
|
||||
},
|
||||
},
|
||||
Masquerade: serverConfigMasquerade{
|
||||
Type: "proxy",
|
||||
File: serverConfigMasqueradeFile{
|
||||
|
|
|
@ -41,6 +41,15 @@ auth:
|
|||
type: password
|
||||
password: goofy_ahh_password
|
||||
|
||||
resolver:
|
||||
type: udp
|
||||
tcp:
|
||||
addr: 123.123.123.123:5353
|
||||
timeout: 4s
|
||||
udp:
|
||||
addr: 4.6.8.0:53
|
||||
timeout: 2s
|
||||
|
||||
masquerade:
|
||||
type: proxy
|
||||
file:
|
||||
|
|
|
@ -40,6 +40,12 @@ auth:
|
|||
type: password
|
||||
password: some_password
|
||||
|
||||
# resolver:
|
||||
# type: udp
|
||||
# udp:
|
||||
# addr: 8.8.4.4
|
||||
# timeout: 2s
|
||||
|
||||
masquerade:
|
||||
type: proxy
|
||||
proxy:
|
||||
|
|
|
@ -8,7 +8,8 @@ import (
|
|||
)
|
||||
|
||||
const (
|
||||
standardResolverRetryTimes = 2
|
||||
standardResolverDefaultTimeout = 2 * time.Second
|
||||
standardResolverRetryTimes = 2
|
||||
)
|
||||
|
||||
// standardResolver is a PluggableOutbound DNS resolver that resolves hostnames
|
||||
|
@ -22,9 +23,9 @@ type standardResolver struct {
|
|||
|
||||
func NewStandardResolverUDP(addr string, timeout time.Duration, next PluggableOutbound) PluggableOutbound {
|
||||
return &standardResolver{
|
||||
Addr: addr,
|
||||
Addr: addDefaultPort(addr),
|
||||
Client: &dns.Client{
|
||||
Timeout: timeout,
|
||||
Timeout: timeoutOrDefault(timeout),
|
||||
},
|
||||
Next: next,
|
||||
}
|
||||
|
@ -32,15 +33,30 @@ func NewStandardResolverUDP(addr string, timeout time.Duration, next PluggableOu
|
|||
|
||||
func NewStandardResolverTCP(addr string, timeout time.Duration, next PluggableOutbound) PluggableOutbound {
|
||||
return &standardResolver{
|
||||
Addr: addr,
|
||||
Addr: addDefaultPort(addr),
|
||||
Client: &dns.Client{
|
||||
Net: "tcp",
|
||||
Timeout: timeout,
|
||||
Timeout: timeoutOrDefault(timeout),
|
||||
},
|
||||
Next: next,
|
||||
}
|
||||
}
|
||||
|
||||
// addDefaultPort adds the default DNS port (53) to the address if not present.
|
||||
func addDefaultPort(addr string) string {
|
||||
if _, _, err := net.SplitHostPort(addr); err != nil {
|
||||
return net.JoinHostPort(addr, "53")
|
||||
}
|
||||
return addr
|
||||
}
|
||||
|
||||
func timeoutOrDefault(timeout time.Duration) time.Duration {
|
||||
if timeout == 0 {
|
||||
return standardResolverDefaultTimeout
|
||||
}
|
||||
return timeout
|
||||
}
|
||||
|
||||
// skipCNAMEChain skips the CNAME chain and returns the last CNAME target.
|
||||
// Sometimes the DNS server returns a CNAME chain like this, in one packet:
|
||||
// domain1.com. CNAME domain2.com.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue