Selaa lähdekoodia

Add support for custom DNS resolvers

tags/v2.1.13
9seconds 2 kuukautta sitten
vanhempi
commit
317d7380cb
4 muutettua tiedostoa jossa 124 lisäystä ja 0 poistoa
  1. 1
    0
      go.mod
  2. 2
    0
      go.sum
  3. 53
    0
      network/v2/dns.go
  4. 68
    0
      network/v2/dns_test.go

+ 1
- 0
go.mod Näytä tiedosto

27
 )
27
 )
28
 
28
 
29
 require (
29
 require (
30
+	github.com/ncruces/go-dns v1.3.2
30
 	github.com/pelletier/go-toml/v2 v2.2.4
31
 	github.com/pelletier/go-toml/v2 v2.2.4
31
 	github.com/pires/go-proxyproto v0.11.0
32
 	github.com/pires/go-proxyproto v0.11.0
32
 	github.com/things-go/go-socks5 v0.1.0
33
 	github.com/things-go/go-socks5 v0.1.0

+ 2
- 0
go.sum Näytä tiedosto

51
 github.com/miekg/dns v1.1.51/go.mod h1:2Z9d3CP1LQWihRZUf29mQ19yDThaI4DAYzte2CaQW5c=
51
 github.com/miekg/dns v1.1.51/go.mod h1:2Z9d3CP1LQWihRZUf29mQ19yDThaI4DAYzte2CaQW5c=
52
 github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=
52
 github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=
53
 github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
53
 github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
54
+github.com/ncruces/go-dns v1.3.2 h1:kBLuUZBgkQ4qF4WDXZRQ4rG0Gk6sLVJQ5tESkWrxUa0=
55
+github.com/ncruces/go-dns v1.3.2/go.mod h1:tuzixNY8PY/M7yUzcvRbUaeLs3ifIdydpi5H2bfRU+s=
54
 github.com/panjf2000/ants/v2 v2.11.5 h1:a7LMnMEeux/ebqTux140tRiaqcFTV0q2bEHF03nl6Rg=
56
 github.com/panjf2000/ants/v2 v2.11.5 h1:a7LMnMEeux/ebqTux140tRiaqcFTV0q2bEHF03nl6Rg=
55
 github.com/panjf2000/ants/v2 v2.11.5/go.mod h1:8u92CYMUc6gyvTIw8Ru7Mt7+/ESnJahz5EVtqfrilek=
57
 github.com/panjf2000/ants/v2 v2.11.5/go.mod h1:8u92CYMUc6gyvTIw8Ru7Mt7+/ESnJahz5EVtqfrilek=
56
 github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaRUnok+kx1WdO15EQc=
58
 github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaRUnok+kx1WdO15EQc=

+ 53
- 0
network/v2/dns.go Näytä tiedosto

1
+package network
2
+
3
+import (
4
+	"context"
5
+	"fmt"
6
+	"net"
7
+	"net/url"
8
+	"time"
9
+
10
+	"github.com/ncruces/go-dns"
11
+)
12
+
13
+var dnsCacheOptions = []dns.CacheOption{
14
+	dns.MaxCacheEntries(dns.DefaultMaxCacheEntries),
15
+	dns.MaxCacheTTL(time.Hour),
16
+	dns.NegativeCache(false),
17
+}
18
+
19
+func GetDNS(u *url.URL) (*net.Resolver, error) {
20
+	if u == nil {
21
+		return dns.NewCachingResolver(nil, dnsCacheOptions...), nil
22
+	}
23
+
24
+	switch u.Scheme {
25
+	case "tls":
26
+		return dns.NewDoTResolver(u.Host, dns.DoTCache(dnsCacheOptions...))
27
+	case "https":
28
+		if u.Path == "" {
29
+			u.Path = "/dns-query"
30
+		}
31
+
32
+		return dns.NewDoHResolver(u.String(), dns.DoHCache(dnsCacheOptions...))
33
+	case "udp", "":
34
+	default:
35
+		return nil, fmt.Errorf("unsupported DNS %v", u)
36
+	}
37
+
38
+	port := u.Port()
39
+	if port == "" {
40
+		port = "53"
41
+	}
42
+
43
+	hostport := net.JoinHostPort(u.Hostname(), port)
44
+	dialer := &net.Dialer{}
45
+	resolver := &net.Resolver{
46
+		PreferGo: true,
47
+		Dial: func(ctx context.Context, network, address string) (net.Conn, error) {
48
+			return dialer.DialContext(ctx, "udp", hostport)
49
+		},
50
+	}
51
+
52
+	return dns.NewCachingResolver(resolver, dnsCacheOptions...), nil
53
+}

+ 68
- 0
network/v2/dns_test.go Näytä tiedosto

1
+package network_test
2
+
3
+import (
4
+	"context"
5
+	"net"
6
+	"net/url"
7
+	"testing"
8
+	"time"
9
+
10
+	"github.com/9seconds/mtg/v2/network/v2"
11
+	"github.com/stretchr/testify/require"
12
+	"github.com/stretchr/testify/suite"
13
+)
14
+
15
+type DNSTestSuite struct {
16
+	suite.Suite
17
+}
18
+
19
+func (suite *DNSTestSuite) TestDefault() {
20
+	resolver, err := network.GetDNS(nil)
21
+	suite.NoError(err)
22
+	suite.doTest(resolver)
23
+}
24
+
25
+func (suite *DNSTestSuite) TestDoH() {
26
+	for _, addr := range []string{"1.1.1.1", "cloudflare-dns.com"} {
27
+		suite.Run(addr, func() {
28
+			u, err := url.Parse("https://" + addr)
29
+			require.NoError(suite.T(), err)
30
+
31
+			resolver, err := network.GetDNS(u)
32
+			suite.NoError(err)
33
+			suite.doTest(resolver)
34
+		})
35
+	}
36
+}
37
+
38
+func (suite *DNSTestSuite) TestDoT() {
39
+	u, err := url.Parse("tls://dns.google")
40
+	require.NoError(suite.T(), err)
41
+
42
+	resolver, err := network.GetDNS(u)
43
+	suite.NoError(err)
44
+	suite.doTest(resolver)
45
+}
46
+
47
+func (suite *DNSTestSuite) TestUDP() {
48
+	u, err := url.Parse("8.8.8.8")
49
+	require.NoError(suite.T(), err)
50
+
51
+	resolver, err := network.GetDNS(u)
52
+	suite.NoError(err)
53
+	suite.doTest(resolver)
54
+}
55
+
56
+func (suite *DNSTestSuite) doTest(resolver *net.Resolver) {
57
+	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
58
+	defer cancel()
59
+
60
+	ips, err := resolver.LookupIP(ctx, "ip4", "dns.google")
61
+	suite.NoError(err)
62
+	suite.Greater(len(ips), 0)
63
+}
64
+
65
+func TestGetDNS(t *testing.T) {
66
+	t.Parallel()
67
+	suite.Run(t, &DNSTestSuite{})
68
+}

Loading…
Peruuta
Tallenna