Skip to content

Commit

Permalink
fix goroutines leak
Browse files Browse the repository at this point in the history
Signed-off-by: denis-tingajkin <[email protected]>
denis-tingaikin committed Apr 13, 2020

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
1 parent 89e1e9d commit 2c8032c
Showing 10 changed files with 100 additions and 25 deletions.
24 changes: 12 additions & 12 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
@@ -7,7 +7,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Check out code into the Go module directory
uses: actions/checkout@v1
uses: actions/checkout@v2
- name: Setup Python
uses: actions/setup-python@v1
- name: Install yamllint
@@ -18,14 +18,14 @@ jobs:
name: shellcheck
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- uses: actions/checkout@v2
- name: shellcheck
uses: azohra/shell-linter@v0.2.0
uses: fkautz/shell-linter@v1.0.1
build:
name: build
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- uses: actions/checkout@v2
- uses: actions/setup-go@v1
with:
go-version: 1.13.4
@@ -35,7 +35,7 @@ jobs:
name: test
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- uses: actions/checkout@v2
- uses: actions/setup-go@v1
with:
go-version: 1.13.4
@@ -53,7 +53,7 @@ jobs:
GOLANGCI_LINT_CONTAINER: golangci/golangci-lint:v1.23.2
steps:
- name: Check out code into the Go module directory
uses: actions/checkout@v1
uses: actions/checkout@v2
- name: Pull golangci-lint docker container
run: docker pull ${GOLANGCI_LINT_CONTAINER}
- name: Run golangci-lint
@@ -65,7 +65,7 @@ jobs:
TAG: test
ORG: networkservicemesh
steps:
- uses: actions/checkout@v1
- uses: actions/checkout@v2
- uses: actions/setup-go@v1
with:
go-version: 1.13.4
@@ -82,7 +82,7 @@ jobs:
name: exclude fmt.Errorf
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- uses: actions/checkout@v2
- name: Exclude fmt.Errorf
run: |
if grep -r --include=*.go fmt.Errorf . ; then
@@ -94,7 +94,7 @@ jobs:
name: Restrict dependencies on github.com/networkservicemesh/*
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- uses: actions/checkout@v2
- name: Restrict dependencies on github.com/networkservicemesh/*
run: |
for i in $(grep github.com/networkservicemesh/ go.mod |grep -v '^module' | sed 's;.*\(github.com\/networkservicemesh\/[a-zA-z\/]*\).*;\1;g' | sort -u);do
@@ -108,7 +108,7 @@ jobs:
name: check go.mod and go.sum
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- uses: actions/checkout@v2
- uses: actions/setup-go@v1
with:
go-version: 1.13.4
@@ -121,7 +121,7 @@ jobs:
name: license header check
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- uses: actions/checkout@v2
- uses: actions/setup-go@v1
with:
go-version: 1.13.4
@@ -136,7 +136,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Check out the code
uses: actions/checkout@v1
uses: actions/checkout@v2
- name: Exclude replace in go.mod
run: |
grep ^replace go.mod || exit 0
12 changes: 9 additions & 3 deletions client.go
Original file line number Diff line number Diff line change
@@ -17,6 +17,7 @@
package fanout

import (
"context"
"crypto/tls"
"fmt"
"time"
@@ -27,7 +28,7 @@ import (

// Client represents the proxy for remote DNS server
type Client interface {
Request(*request.Request) (*dns.Msg, error)
Request(context.Context, *request.Request) (*dns.Msg, error)
Endpoint() string
SetTLSConfig(*tls.Config)
}
@@ -62,9 +63,10 @@ func (c *client) Endpoint() string {
}

// Request sends request to DNS server
func (c *client) Request(r *request.Request) (*dns.Msg, error) {
func (c *client) Request(ctx context.Context, r *request.Request) (*dns.Msg, error) {
start := time.Now()
conn, err := c.transport.Dial(c.net)

conn, err := c.transport.Dial(ctx, c.net)
if err != nil {
return nil, err
}
@@ -79,6 +81,10 @@ func (c *client) Request(r *request.Request) (*dns.Msg, error) {
}
logErrIfNotNil(conn.SetReadDeadline(time.Now().Add(readTimeout)))
var ret *dns.Msg
go func() {
<-ctx.Done()
_ = conn.Close()
}()
for {
ret, err = conn.ReadMsg()
if err != nil {
11 changes: 11 additions & 0 deletions coredns/go.sum
Original file line number Diff line number Diff line change
@@ -352,13 +352,15 @@ github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ=
github.com/xeipuuv/gojsonschema v1.1.0/go.mod h1:5yf86TLmAcydyeJq5YvxkGPE2fm/u4myDekKRoLuqhs=
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
go.etcd.io/etcd v0.5.0-alpha.5.0.20190917205325-a14579fbfb1a/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg=
go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk=
go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk=
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
go.uber.org/goleak v1.0.0/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A=
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
go.uber.org/ratelimit v0.0.0-20180316092928-c15da0234277/go.mod h1:2X8KaoNd1J0lZV+PxJk/5+DGbO/tpwLR1m++a7FnB/Y=
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
@@ -383,8 +385,11 @@ golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvx
golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/net v0.0.0-20170114055629-f2499483f923/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180611182652-db08ff08e862/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@@ -410,6 +415,7 @@ golang.org/x/net v0.0.0-20191004110552-13f9640d40b9/go.mod h1:z5CRVTTTmAJ677TzLL
golang.org/x/net v0.0.0-20191027093000-83d349e8ac1a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553 h1:efeOvDhwQ29Dj3SdAV/MJf8oukgn+8D8WgaCaRMchF8=
golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
@@ -471,7 +477,12 @@ golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBn
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190624190245-7f2218787638/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20191108193012-7d206e10da11/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191216052735-49a3e744a425/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200413015812-1f08ef6002a8/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
2 changes: 1 addition & 1 deletion domain_test.go
Original file line number Diff line number Diff line change
@@ -67,7 +67,7 @@ func TestDomain_ContainsShouldWorkFast(t *testing.T) {
for i := 0; i < 10000; i++ {
require.True(t, d.Contains(samples[i]))
}
require.True(t, time.Since(start) < time.Second/5)
require.True(t, time.Since(start) < time.Second/4)
}

func TestDomainFewEntries(t *testing.T) {
3 changes: 2 additions & 1 deletion fanout.go
Original file line number Diff line number Diff line change
@@ -76,6 +76,7 @@ func (f *Fanout) ServeDNS(ctx context.Context, w dns.ResponseWriter, m *dns.Msg)
defer cancel()
clientCount := len(f.clients)
workerChannel := make(chan Client, f.workerCount)
defer close(workerChannel)
responseCh := make(chan *response, clientCount)
go func() {
for i := 0; i < clientCount; i++ {
@@ -148,7 +149,7 @@ func (f *Fanout) processClient(ctx context.Context, c Client, r *request.Request
if ctx.Err() != nil {
return &response{client: c, response: nil, start: start, err: ctx.Err()}
}
msg, err := c.Request(r)
msg, err := c.Request(ctx, r)
if err == nil {
return &response{client: c, response: msg, start: start, err: err}
}
12 changes: 11 additions & 1 deletion fanout_test.go
Original file line number Diff line number Diff line change
@@ -29,6 +29,7 @@ import (
"time"

"github.com/stretchr/testify/require"
"go.uber.org/goleak"

"github.com/caddyserver/caddy"
"github.com/coredns/coredns/plugin/pkg/dnstest"
@@ -131,6 +132,7 @@ func TestFanout_ExceptFile(t *testing.T) {
}

func (t *fanoutTestSuite) TestConfigFromCorefile() {
defer goleak.VerifyNone(t.T())
s := newServer(t.network, func(w dns.ResponseWriter, r *dns.Msg) {
ret := new(dns.Msg)
ret.SetReply(r)
@@ -160,6 +162,7 @@ func (t *fanoutTestSuite) TestConfigFromCorefile() {
}

func (t *fanoutTestSuite) TestWorkerCountLessThenServers() {
defer goleak.VerifyNone(t.T())
const expected = 1
answerCount := 0
var mutex sync.Mutex
@@ -191,6 +194,7 @@ func (t *fanoutTestSuite) TestWorkerCountLessThenServers() {
logErrIfNotNil(w.WriteMsg(&msg))
}
})
defer correctServer.close()

f.addClient(NewClient(correctServer.addr, t.network))
f.workerCount = 1
@@ -205,6 +209,7 @@ func (t *fanoutTestSuite) TestWorkerCountLessThenServers() {
t.Equal(answerCount, expected)
}
func (t *fanoutTestSuite) TestTwoServersUnsuccessfulResponse() {
defer goleak.VerifyNone(t.T())
rcode := 1
rcodeMutex := sync.Mutex{}
s1 := newServer(t.network, func(w dns.ResponseWriter, r *dns.Msg) {
@@ -249,11 +254,13 @@ func (t *fanoutTestSuite) TestTwoServersUnsuccessfulResponse() {
}

func (t *fanoutTestSuite) TestCanReturnUnsuccessfulRepose() {
defer goleak.VerifyNone(t.T())
s := newServer(t.network, func(w dns.ResponseWriter, r *dns.Msg) {
msg := nxdomainMsg()
msg.SetRcode(r, msg.Rcode)
logErrIfNotNil(w.WriteMsg(msg))
})
defer s.close()
f := New()
f.net = t.network
f.from = "."
@@ -269,6 +276,7 @@ func (t *fanoutTestSuite) TestCanReturnUnsuccessfulRepose() {
}

func (t *fanoutTestSuite) TestBusyServer() {
defer goleak.VerifyNone(t.T())
var requestNum, answerCount int32
totalRequestNum := int32(5)
s := newServer(t.network, func(w dns.ResponseWriter, r *dns.Msg) {
@@ -284,6 +292,7 @@ func (t *fanoutTestSuite) TestBusyServer() {
}
atomic.AddInt32(&requestNum, 1)
})
defer s.close()
c := NewClient(s.addr, t.network)
f := New()
f.net = t.network
@@ -300,6 +309,7 @@ func (t *fanoutTestSuite) TestBusyServer() {
}

func (t *fanoutTestSuite) TestTwoServers() {
defer goleak.VerifyNone(t.T())
const expected = 1
var mutex sync.Mutex
answerCount1 := 0
@@ -316,6 +326,7 @@ func (t *fanoutTestSuite) TestTwoServers() {
logErrIfNotNil(w.WriteMsg(&msg))
}
})
defer s1.close()
s2 := newServer(t.network, func(w dns.ResponseWriter, r *dns.Msg) {
if r.Question[0].Name == "example2." {
msg := dns.Msg{
@@ -328,7 +339,6 @@ func (t *fanoutTestSuite) TestTwoServers() {
logErrIfNotNil(w.WriteMsg(&msg))
}
})
defer s1.close()
defer s2.close()

c1 := NewClient(s1.addr, t.network)
3 changes: 3 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
@@ -10,4 +10,7 @@ require (
github.com/pkg/errors v0.9.1
github.com/prometheus/client_golang v1.5.0
github.com/stretchr/testify v1.5.1
go.uber.org/goleak v1.0.0
golang.org/x/lint v0.0.0-20200302205851-738671d3881b // indirect
golang.org/x/tools v0.0.0-20200413015812-1f08ef6002a8 // indirect
)
18 changes: 18 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -354,13 +354,16 @@ github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ=
github.com/xeipuuv/gojsonschema v1.1.0/go.mod h1:5yf86TLmAcydyeJq5YvxkGPE2fm/u4myDekKRoLuqhs=
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
go.etcd.io/etcd v0.5.0-alpha.5.0.20190917205325-a14579fbfb1a/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg=
go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk=
go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk=
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
go.uber.org/goleak v1.0.0 h1:qsup4IcBdlmsnGfqyLl4Ntn3C2XCCuKAE7DwHpScyUo=
go.uber.org/goleak v1.0.0/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A=
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
go.uber.org/ratelimit v0.0.0-20180316092928-c15da0234277/go.mod h1:2X8KaoNd1J0lZV+PxJk/5+DGbO/tpwLR1m++a7FnB/Y=
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
@@ -385,8 +388,14 @@ golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvx
golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/lint v0.0.0-20190930215403-16217165b5de h1:5hukYrvBGR8/eNkX5mdUezrA6JiaEZDtJb9Ei+1LlBs=
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/lint v0.0.0-20200302205851-738671d3881b h1:Wh+f8QHJXR411sJR8/vRBTZ7YapZaRvUcLFFJhusH0k=
golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
golang.org/x/mod v0.2.0 h1:KU7oHjnv3XNWfa5COkzUifxZmxp1TyI7ImMXqFxLwvQ=
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/net v0.0.0-20170114055629-f2499483f923/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180611182652-db08ff08e862/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@@ -412,6 +421,8 @@ golang.org/x/net v0.0.0-20191004110552-13f9640d40b9/go.mod h1:z5CRVTTTmAJ677TzLL
golang.org/x/net v0.0.0-20191027093000-83d349e8ac1a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553 h1:efeOvDhwQ29Dj3SdAV/MJf8oukgn+8D8WgaCaRMchF8=
golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b h1:0mm1VjtFUOIlE1SbDlwjYaDxZVDP2S5ou6y0gSgXHu8=
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
@@ -473,7 +484,14 @@ golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBn
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190624190245-7f2218787638/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20191108193012-7d206e10da11/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191216052735-49a3e744a425 h1:VvQyQJN0tSuecqgcIxMWnnfG5kSmgy9KZR9sW3W5QeA=
golang.org/x/tools v0.0.0-20191216052735-49a3e744a425/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200413015812-1f08ef6002a8 h1:1TnYi6m8UoNpEKS1wxgR8GcHPe2YDgYoDjAedVuX+Q0=
golang.org/x/tools v0.0.0-20200413015812-1f08ef6002a8/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
2 changes: 1 addition & 1 deletion setup.go
Original file line number Diff line number Diff line change
@@ -249,7 +249,7 @@ func parseProtocol(f *Fanout, c *caddyfile.Dispenser) error {
return c.ArgErr()
}
net := strings.ToLower(c.Val())
if net != tcp && net != "udp" && net != tcptlc {
if net != tcp && net != udp && net != tcptlc {
return errors.New("unknown network protocol")
}
f.net = net
38 changes: 32 additions & 6 deletions transport.go
Original file line number Diff line number Diff line change
@@ -17,14 +17,16 @@
package fanout

import (
"context"
"crypto/tls"
"net"

"github.com/miekg/dns"
)

// Transport represent a solution to connect to remote DNS endpoint with specific network
type Transport interface {
Dial(net string) (*dns.Conn, error)
Dial(ctx context.Context, net string) (*dns.Conn, error)
SetTLSConfig(*tls.Config)
}

@@ -46,12 +48,36 @@ func (t *transportImpl) SetTLSConfig(c *tls.Config) {
}

// Dial dials the address configured in transportImpl, potentially reusing a connection or creating a new one.
func (t *transportImpl) Dial(net string) (*dns.Conn, error) {
func (t *transportImpl) Dial(ctx context.Context, network string) (*dns.Conn, error) {
if t.tlsConfig != nil {
net = tcptlc
network = tcptlc
}
if net == tcptlc {
return dns.DialTimeoutWithTLS("tcp", t.addr, t.tlsConfig, defaultTimeout)
if network == tcptlc {
return t.dial(ctx, &dns.Client{Net: network, Dialer: &net.Dialer{Timeout: maxTimeout}, TLSConfig: t.tlsConfig})
}
return dns.DialTimeout(net, t.addr, defaultTimeout)
return t.dial(ctx, &dns.Client{Net: network, Dialer: &net.Dialer{Timeout: maxTimeout}})
}

func (t *transportImpl) dial(ctx context.Context, c *dns.Client) (*dns.Conn, error) {
var d net.Dialer
if c.Dialer == nil {
d = net.Dialer{Timeout: maxTimeout}
} else {
d = *c.Dialer
}
network := c.Net
if network == "" {
network = "udp"
}
var conn = new(dns.Conn)
var err error
if network == tcptlc {
conn.Conn, err = tls.DialWithDialer(&d, network, t.addr, c.TLSConfig)
} else {
conn.Conn, err = d.DialContext(ctx, network, t.addr)
}
if err != nil {
return nil, err
}
return conn, nil
}

0 comments on commit 2c8032c

Please sign in to comment.