-
Notifications
You must be signed in to change notification settings - Fork 4
Expand file tree
/
Copy pathoptions.go
More file actions
104 lines (92 loc) · 2.57 KB
/
Copy pathoptions.go
File metadata and controls
104 lines (92 loc) · 2.57 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
package multidns
import (
"context"
"crypto/tls"
"net"
"time"
)
// Protocol identifies the wire transport used to talk to an upstream resolver.
type Protocol string
const (
ProtoUDP Protocol = "udp"
ProtoTCP Protocol = "tcp"
ProtoDoT Protocol = "dot"
ProtoDoH Protocol = "doh"
)
// LBStrategy controls candidate ordering when multiple resolvers are healthy.
type LBStrategy int
const (
LBRoundRobin LBStrategy = iota
LBWeighted
LBLowestLatency
)
// DialFunc is the optional custom dialer hook. When set on a ResolverConfig
// it is used for UDP/TCP/DoT connections and as the http.Transport DialContext
// for DoH, so an embedder (e.g. hiddify-sing-box) can route DNS through a tunnel.
type DialFunc func(ctx context.Context, network, address string) (net.Conn, error)
// ResolverConfig describes a single upstream resolver.
type ResolverConfig struct {
Name string
Protocol Protocol
Address string
Timeout time.Duration
TLSConfig *tls.Config
Dialer DialFunc
Weight int
InitialRPM int
}
// Options configures a Manager.
type Options struct {
DefaultDeadline time.Duration
LoadBalance LBStrategy
ProbeInterval time.Duration
DownAfterFailures int
RateLimitFloorRPM int
RateLimitUncapRPM int
RateLimitAdditive int
// DefaultResolverTimeout is the per-attempt cap applied to a resolver
// when its ResolverConfig.Timeout is unset. Defaults to 2s. This exists
// so a single hung upstream cannot consume the entire DefaultDeadline
// before failover kicks in.
DefaultResolverTimeout time.Duration
Logger Logger
}
// Logger is the minimal logging surface; defaults to a no-op. Embedders
// (e.g. sing-box) inject their own.
type Logger interface {
Debugf(format string, args ...any)
Infof(format string, args ...any)
Warnf(format string, args ...any)
Errorf(format string, args ...any)
}
type nopLogger struct{}
func (nopLogger) Debugf(string, ...any) {}
func (nopLogger) Infof(string, ...any) {}
func (nopLogger) Warnf(string, ...any) {}
func (nopLogger) Errorf(string, ...any) {}
func (o *Options) applyDefaults() {
if o.DefaultDeadline <= 0 {
o.DefaultDeadline = 5 * time.Second
}
if o.ProbeInterval <= 0 {
o.ProbeInterval = 5 * time.Second
}
if o.DownAfterFailures <= 0 {
o.DownAfterFailures = 8
}
if o.RateLimitFloorRPM <= 0 {
o.RateLimitFloorRPM = 6
}
if o.RateLimitUncapRPM <= 0 {
o.RateLimitUncapRPM = 600
}
if o.RateLimitAdditive <= 0 {
o.RateLimitAdditive = 5
}
if o.DefaultResolverTimeout <= 0 {
o.DefaultResolverTimeout = 2 * time.Second
}
if o.Logger == nil {
o.Logger = nopLogger{}
}
}