Skip to content

Commit 4dc8303

Browse files
authored
Resolvers refactor; remove tcp connection pool in config for further test (shawn1m#211)
* Resolvers refactor; remove tcp connection pool in config for further test
1 parent 7b81109 commit 4dc8303

13 files changed

+124
-81
lines changed

README.md

-9
Original file line numberDiff line numberDiff line change
@@ -113,11 +113,6 @@ Configuration file is "config.json" by default:
113113
"OnlyPrimaryDNS": false,
114114
"IPv6UseAlternativeDNS": false,
115115
"AlternativeDNSConcurrent": false,
116-
"TCPPoolConfig": {
117-
"InitialCapacity": 0,
118-
"MaxCapacity": 15,
119-
"IdleTimeout": 30
120-
},
121116
"WhenPrimaryDNSAnswerNoneUse": "PrimaryDNS",
122117
"IPNetworkFile": {
123118
"Primary": "./ip_network_primary_sample",
@@ -211,10 +206,6 @@ IPv6). Overture will handle both TCP and UDP requests. Literal IPv6 addresses ar
211206
+ OnlyPrimaryDNS: Disable dispatcher feature, use primary DNS only.
212207
+ IPv6UseAlternativeDNS: Redirect IPv6 DNS queries to alternative DNS servers.
213208
+ AlternativeDNSConcurrent: Query the PrimaryDNS and AlternativeDNS at the same time
214-
+ TCPPoolConfig: Connection pool for TCP connections.
215-
+ IdleTimeout: Specify idle timeout for connection in pool
216-
+ InitialCapacity: Specify init capacity for connection pool
217-
+ MaxCapacity: Specify max capacity for connection pool
218209
+ WhenPrimaryDNSAnswerNoneUse: If the response of PrimaryDNS exists and there is no `ANSWER SECTION` in it, the final DNS should be defined. (There is no `AAAA` record for most domains right now)
219210
+ File: Absolute path like `/path/to/file` is allowed. For Windows users, please use properly escaped path like
220211
`C:\\path\\to\\file.txt` in the configuration.

config.sample.json

-5
Original file line numberDiff line numberDiff line change
@@ -32,11 +32,6 @@
3232
"OnlyPrimaryDNS": false,
3333
"IPv6UseAlternativeDNS": false,
3434
"AlternativeDNSConcurrent": false,
35-
"TCPPoolConfig": {
36-
"InitialCapacity": 0,
37-
"MaxCapacity": 15,
38-
"IdleTimeout": 30
39-
},
4035
"PoolIdleTimeout": 15,
4136
"PoolMaxCapacity": 15,
4237
"WhenPrimaryDNSAnswerNoneUse": "PrimaryDNS",

config.test.json

-5
Original file line numberDiff line numberDiff line change
@@ -32,11 +32,6 @@
3232
"OnlyPrimaryDNS": false,
3333
"IPv6UseAlternativeDNS": false,
3434
"AlternativeDNSConcurrent": false,
35-
"TCPPoolConfig": {
36-
"InitialCapacity": 0,
37-
"MaxCapacity": 15,
38-
"IdleTimeout": 30
39-
},
4035
"WhenPrimaryDNSAnswerNoneUse": "PrimaryDNS",
4136
"IPNetworkFile": {
4237
"Primary": "./ip_network_primary_sample",

core/common/upstream.go

+6
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,10 @@ type DNSUpstream struct {
77
SOCKS5Address string
88
Timeout int
99
EDNSClientSubnet *EDNSClientSubnetType
10+
TCPPoolConfig struct {
11+
Enable bool
12+
InitialCapacity int
13+
MaxCapacity int
14+
IdleTimeout int
15+
}
1016
}

core/config/config.go

+1-6
Original file line numberDiff line numberDiff line change
@@ -38,12 +38,7 @@ type Config struct {
3838
OnlyPrimaryDNS bool
3939
IPv6UseAlternativeDNS bool
4040
AlternativeDNSConcurrent bool
41-
TCPPoolConfig struct {
42-
InitialCapacity int
43-
MaxCapacity int
44-
IdleTimeout int
45-
}
46-
IPNetworkFile struct {
41+
IPNetworkFile struct {
4742
Primary string
4843
Alternative string
4944
}

core/init.go

-1
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@ func InitServer(configFilePath string) {
2828

2929
RedirectIPv6Record: conf.IPv6UseAlternativeDNS,
3030
AlternativeDNSConcurrent: conf.AlternativeDNSConcurrent,
31-
TCPPoolConfig: conf.TCPPoolConfig,
3231
MinimumTTL: conf.MinimumTTL,
3332
DomainTTLMap: conf.DomainTTLMap,
3433

core/outbound/clients/resolver/base_resolver.go

+50-18
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ import (
1818

1919
type Resolver interface {
2020
Exchange(*dns.Msg) (*dns.Msg, error)
21-
Init()
21+
Init() error
2222
}
2323

2424
type BaseResolver struct {
@@ -29,8 +29,34 @@ func (r *BaseResolver) Exchange(*dns.Msg) (*dns.Msg, error) {
2929
return nil, nil
3030
}
3131

32-
func (r *BaseResolver) Init() {
32+
func (r *BaseResolver) ExchangeByBaseConn(q *dns.Msg) (*dns.Msg, error) {
33+
conn, err := r.CreateBaseConn()
34+
if err != nil {
35+
return nil, err
36+
}
37+
r.setTimeout(conn)
38+
dc := &dns.Conn{Conn: conn, UDPSize: 65535}
39+
defer dc.Close()
40+
err = dc.WriteMsg(q)
41+
if err != nil {
42+
return nil, err
43+
}
44+
return dc.ReadMsg()
45+
}
3346

47+
func (r *BaseResolver) Init() error {
48+
if r.dnsUpstream.TCPPoolConfig.Enable {
49+
if r.dnsUpstream.TCPPoolConfig.IdleTimeout != 0 {
50+
IdleTimeout = time.Duration(r.dnsUpstream.TCPPoolConfig.IdleTimeout) * time.Second
51+
}
52+
if r.dnsUpstream.TCPPoolConfig.MaxCapacity != 0 {
53+
MaxCapacity = r.dnsUpstream.TCPPoolConfig.MaxCapacity
54+
}
55+
if r.dnsUpstream.TCPPoolConfig.InitialCapacity != 0 {
56+
InitialCapacity = r.dnsUpstream.TCPPoolConfig.InitialCapacity
57+
}
58+
}
59+
return nil
3460
}
3561

3662
func NewResolver(u *common.DNSUpstream) Resolver {
@@ -46,20 +72,26 @@ func NewResolver(u *common.DNSUpstream) Resolver {
4672
resolver = &HTTPSResolver{BaseResolver: BaseResolver{u}}
4773
default:
4874
log.Fatalf("Unsupported protocol: %s", u.Protocol)
75+
log.Errorf("Create resolver for %s failed", u.Name)
4976
return nil
5077
}
51-
resolver.Init()
78+
err := resolver.Init()
79+
if err != nil {
80+
log.Errorf("Init resolver for %s failed", u.Name)
81+
} else {
82+
log.Debugf("Init resolver for %s succeed", u.Name)
83+
}
5284
return resolver
5385
}
5486

55-
func (c *BaseResolver) CreateBaseConn() (conn net.Conn, err error) {
87+
func (r *BaseResolver) CreateBaseConn() (net.Conn, error) {
5688
dialer := net.Dial
57-
if c.dnsUpstream.SOCKS5Address != "" {
58-
socksAddress, err := ExtractSocksAddress(c.dnsUpstream.SOCKS5Address)
89+
if r.dnsUpstream.SOCKS5Address != "" {
90+
socksAddress, err := ExtractSocksAddress(r.dnsUpstream.SOCKS5Address)
5991
if err != nil {
6092
return nil, err
6193
}
62-
network := ToNetwork(c.dnsUpstream.Protocol)
94+
network := ToNetwork(r.dnsUpstream.Protocol)
6395
s, err := proxy.SOCKS5(network, socksAddress, nil, proxy.Direct)
6496
if err != nil {
6597
log.Warnf("Failed to connect to SOCKS5 proxy: %s", err)
@@ -68,41 +100,42 @@ func (c *BaseResolver) CreateBaseConn() (conn net.Conn, err error) {
68100
dialer = s.Dial
69101
}
70102

71-
network := ToNetwork(c.dnsUpstream.Protocol)
72-
host, port, err := ExtractDNSAddress(c.dnsUpstream.Address, c.dnsUpstream.Protocol)
103+
network := ToNetwork(r.dnsUpstream.Protocol)
104+
host, port, err := ExtractDNSAddress(r.dnsUpstream.Address, r.dnsUpstream.Protocol)
73105
if err != nil {
74106
return nil, err
75107
}
76108
address := net.JoinHostPort(host, port)
77109
log.Debugf("Creating new connection to %s:%s", host, port)
110+
var conn net.Conn
78111
if conn, err = dialer(network, address); err != nil {
79112
log.Warnf("Failed to connect to DNS upstream: %s", err)
80113
return nil, err
81114
}
82115

83116
// the Timeout setting is now moved to each resolver to support pool's idle timeout
84-
// c.setTimeout(conn)
117+
// r.setTimeout(conn)
85118
return conn, err
86119
}
87120

88121
var InitialCapacity = 0
89122
var IdleTimeout = 30 * time.Second
90123
var MaxCapacity = 15
91124

92-
func (c *BaseResolver) setTimeout(conn net.Conn) {
93-
dnsTimeout := time.Duration(c.dnsUpstream.Timeout) * time.Second / 3
125+
func (r *BaseResolver) setTimeout(conn net.Conn) {
126+
dnsTimeout := time.Duration(r.dnsUpstream.Timeout) * time.Second / 3
94127
conn.SetDeadline(time.Now().Add(dnsTimeout))
95128
conn.SetReadDeadline(time.Now().Add(dnsTimeout))
96129
conn.SetWriteDeadline(time.Now().Add(dnsTimeout))
97130
}
98131

99-
func (c *BaseResolver) setIdleTimeout(conn net.Conn) {
132+
func (r *BaseResolver) setIdleTimeout(conn net.Conn) {
100133
conn.SetDeadline(time.Now().Add(IdleTimeout))
101134
conn.SetReadDeadline(time.Now().Add(IdleTimeout))
102135
conn.SetWriteDeadline(time.Now().Add(IdleTimeout))
103136
}
104137

105-
func (c *BaseResolver) createConnectionPool(connCreate func() (interface{}, error), connClose func(interface{}) error) pool.Pool {
138+
func (r *BaseResolver) createConnectionPool(connCreate func() (interface{}, error), connClose func(interface{}) error) (pool.Pool, error) {
106139
poolConfig := &pool.Config{
107140
InitialCap: InitialCapacity,
108141
MaxCap: MaxCapacity,
@@ -111,11 +144,10 @@ func (c *BaseResolver) createConnectionPool(connCreate func() (interface{}, erro
111144
//Ping: ping,
112145
IdleTimeout: IdleTimeout,
113146
}
114-
ret, _ := pool.NewChannelPool(poolConfig)
115-
return ret
147+
return pool.NewChannelPool(poolConfig)
116148
}
117149

118-
func (c *BaseResolver) exchangeByDNSClient(q *dns.Msg, conn net.Conn) (msg *dns.Msg, err error) {
150+
func (r *BaseResolver) exchangeByDNSClient(q *dns.Msg, conn net.Conn) (msg *dns.Msg, err error) {
119151
if conn == nil {
120152
log.Fatal("Conn not initialized for exchangeByDNSClient")
121153
return nil, err
@@ -124,7 +156,7 @@ func (c *BaseResolver) exchangeByDNSClient(q *dns.Msg, conn net.Conn) (msg *dns.
124156
dc := &dns.Conn{Conn: conn, UDPSize: 65535}
125157
err = dc.WriteMsg(q)
126158
if err != nil {
127-
log.Warnf("%s Fail: Send question message failed", c.dnsUpstream.Name)
159+
log.Warnf("%s Fail: Send question message failed", r.dnsUpstream.Name)
128160
return nil, err
129161
}
130162
return dc.ReadMsg()

core/outbound/clients/resolver/https_resolver.go

+6-2
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ import (
1010

1111
type HTTPSResolver struct {
1212
BaseResolver
13-
1413
client http.Client
1514
}
1615

@@ -34,12 +33,17 @@ func (r *HTTPSResolver) Exchange(q *dns.Msg) (*dns.Msg, error) {
3433
return msg, nil
3534
}
3635

37-
func (r *HTTPSResolver) Init() {
36+
func (r *HTTPSResolver) Init() error {
37+
err := r.BaseResolver.Init()
38+
if err != nil {
39+
return err
40+
}
3841
r.client = http.Client{
3942
Transport: &http.Transport{
4043
Dial: func(network, addr string) (net.Conn, error) {
4144
return r.CreateBaseConn()
4245
},
4346
},
4447
}
48+
return nil
4549
}
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,53 @@
11
package resolver
22

33
import (
4+
"net"
5+
46
"github.com/miekg/dns"
57
"github.com/silenceper/pool"
6-
"net"
8+
log "github.com/sirupsen/logrus"
79
)
810

911
type TCPResolver struct {
1012
BaseResolver
11-
connpool pool.Pool
13+
poolConn pool.Pool
1214
}
1315

1416
func (r *TCPResolver) Exchange(q *dns.Msg) (*dns.Msg, error) {
15-
_conn, err := r.connpool.Get()
17+
if !r.dnsUpstream.TCPPoolConfig.Enable {
18+
return r.ExchangeByBaseConn(q)
19+
}
20+
21+
_conn, err := r.poolConn.Get()
1622
if err != nil {
1723
return nil, err
1824
}
1925
conn := _conn.(net.Conn)
2026
r.setTimeout(conn)
2127
ret, err := r.exchangeByDNSClient(q, conn)
2228
if err != nil {
23-
r.connpool.Close(conn)
29+
r.poolConn.Close(conn)
2430
} else {
2531
r.setIdleTimeout(conn)
26-
r.connpool.Put(conn)
32+
r.poolConn.Put(conn)
2733
}
2834
return ret, err
2935
}
3036

31-
func (r *TCPResolver) Init() {
32-
r.connpool = r.createConnectionPool(
33-
func() (interface{}, error) { return r.CreateBaseConn() },
34-
func(v interface{}) error { return v.(net.Conn).Close() })
37+
func (r *TCPResolver) Init() error {
38+
err := r.BaseResolver.Init()
39+
if err != nil {
40+
return err
41+
}
42+
if r.dnsUpstream.TCPPoolConfig.Enable {
43+
r.poolConn, err = r.createConnectionPool(
44+
func() (interface{}, error) { return r.CreateBaseConn() },
45+
func(v interface{}) error { return v.(net.Conn).Close() })
46+
if err != nil {
47+
log.Debugf("Set %s pool's IdleTimeout to %d, InitialCapacity to %d, MaxCapacity to %d", r.dnsUpstream.Name, r.dnsUpstream.TCPPoolConfig.IdleTimeout, r.dnsUpstream.TCPPoolConfig.InitialCapacity, r.dnsUpstream.TCPPoolConfig.MaxCapacity)
48+
}
49+
} else {
50+
return nil
51+
}
52+
return err
3553
}

core/outbound/clients/resolver/tcptls_resolver.go

+27-11
Original file line numberDiff line numberDiff line change
@@ -2,37 +2,41 @@ package resolver
22

33
import (
44
"crypto/tls"
5+
"net"
6+
57
"github.com/miekg/dns"
68
"github.com/silenceper/pool"
7-
"net"
9+
log "github.com/sirupsen/logrus"
810
)
911

1012
type TCPTLSResolver struct {
1113
BaseResolver
12-
13-
connpool pool.Pool
14+
poolConn pool.Pool
1415
}
1516

1617
func (r *TCPTLSResolver) Exchange(q *dns.Msg) (*dns.Msg, error) {
17-
_conn, err := r.connpool.Get()
18+
if !r.dnsUpstream.TCPPoolConfig.Enable {
19+
return r.ExchangeByBaseConn(q)
20+
}
21+
_conn, err := r.poolConn.Get()
1822
if err != nil {
1923
return nil, err
2024
}
2125
conn := _conn.(net.Conn)
2226
r.setTimeout(conn)
2327
ret, err := r.exchangeByDNSClient(q, conn)
2428
if err != nil {
25-
r.connpool.Close(conn)
29+
r.poolConn.Close(conn)
2630
} else {
2731
r.setIdleTimeout(conn)
28-
r.connpool.Put(conn)
32+
r.poolConn.Put(conn)
2933
}
3034
return ret, err
3135
}
3236

3337
func (r *TCPTLSResolver) createTlsConn() (conn net.Conn, err error) {
3438
conn, err = r.CreateBaseConn()
35-
if conn == nil {
39+
if err != nil {
3640
return nil, err
3741
}
3842
host, _, _ := ExtractTLSDNSAddress(r.dnsUpstream.Address)
@@ -45,8 +49,20 @@ func (r *TCPTLSResolver) createTlsConn() (conn net.Conn, err error) {
4549
return conn, nil
4650
}
4751

48-
func (r *TCPTLSResolver) Init() {
49-
r.connpool = r.createConnectionPool(
50-
func() (interface{}, error) { return r.createTlsConn() },
51-
func(v interface{}) error { return v.(net.Conn).Close() })
52+
func (r *TCPTLSResolver) Init() error {
53+
err := r.BaseResolver.Init()
54+
if err != nil {
55+
return err
56+
}
57+
if r.dnsUpstream.TCPPoolConfig.Enable {
58+
r.poolConn, err = r.createConnectionPool(
59+
func() (interface{}, error) { return r.createTlsConn() },
60+
func(v interface{}) error { return v.(net.Conn).Close() })
61+
if err != nil {
62+
log.Debugf("Set %s pool's IdleTimeout to %d, InitialCapacity to %d, MaxCapacity to %d", r.dnsUpstream.Name, r.dnsUpstream.TCPPoolConfig.IdleTimeout, r.dnsUpstream.TCPPoolConfig.InitialCapacity, r.dnsUpstream.TCPPoolConfig.MaxCapacity)
63+
}
64+
} else {
65+
return nil
66+
}
67+
return err
5268
}

0 commit comments

Comments
 (0)