Skip to content

Commit

Permalink
Fix iOS DNS timeout (netbirdio#1504)
Browse files Browse the repository at this point in the history
  • Loading branch information
lixmal authored Jan 29, 2024
1 parent f6ffc31 commit 8b28781
Show file tree
Hide file tree
Showing 6 changed files with 19 additions and 29 deletions.
6 changes: 3 additions & 3 deletions client/internal/dns/file_parser_linux_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,11 @@ func Test_parseResolvConf(t *testing.T) {
expectedOther []string
}{
{
input: `domain chello.hu
search chello.hu
input: `domain example.org
search example.org
nameserver 192.168.0.1
`,
expectedSearch: []string{"chello.hu"},
expectedSearch: []string{"example.org"},
expectedNS: []string{"192.168.0.1"},
expectedOther: []string{},
},
Expand Down
2 changes: 1 addition & 1 deletion client/internal/dns/file_repair_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ func (f *repair) watchFileChanges(nbSearchDomains []string, nbNameserverIP strin

err = f.inotify.Add(f.watchDir)
if err != nil {
log.Errorf("failed to readd inotify watch for resolv.conf: %s", err)
log.Errorf("failed to re-add inotify watch for resolv.conf: %s", err)
return
}
}
Expand Down
16 changes: 11 additions & 5 deletions client/internal/dns/upstream.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,7 @@ const (
const testRecord = "."

type upstreamClient interface {
exchange(upstream string, r *dns.Msg) (*dns.Msg, time.Duration, error)
exchangeContext(ctx context.Context, upstream string, r *dns.Msg) (*dns.Msg, time.Duration, error)
exchange(ctx context.Context, upstream string, r *dns.Msg) (*dns.Msg, time.Duration, error)
}

type UpstreamResolver interface {
Expand Down Expand Up @@ -80,8 +79,15 @@ func (u *upstreamResolverBase) ServeDNS(w dns.ResponseWriter, r *dns.Msg) {
}

for _, upstream := range u.upstreamServers {

rm, t, err := u.upstreamClient.exchange(upstream, r)
var rm *dns.Msg
var t time.Duration
var err error

func() {
ctx, cancel := context.WithTimeout(u.ctx, u.upstreamTimeout)
defer cancel()
rm, t, err = u.upstreamClient.exchange(ctx, upstream, r)
}()

if err != nil {
if errors.Is(err, context.DeadlineExceeded) || isTimeout(err) {
Expand Down Expand Up @@ -259,6 +265,6 @@ func (u *upstreamResolverBase) testNameserver(server string) error {

r := new(dns.Msg).SetQuestion(testRecord, dns.TypeSOA)

_, _, err := u.upstreamClient.exchangeContext(ctx, server, r)
_, _, err := u.upstreamClient.exchange(ctx, server, r)
return err
}
6 changes: 1 addition & 5 deletions client/internal/dns/upstream_ios.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,7 @@ func newUpstreamResolver(parentCTX context.Context, interfaceName string, ip net
return ios, nil
}

func (u *upstreamResolverIOS) exchange(upstream string, r *dns.Msg) (rm *dns.Msg, t time.Duration, err error) {
return u.exchangeContext(context.Background(), upstream, r)
}

func (u *upstreamResolverIOS) exchangeContext(ctx context.Context, upstream string, r *dns.Msg) (rm *dns.Msg, t time.Duration, err error) {
func (u *upstreamResolverIOS) exchange(ctx context.Context, upstream string, r *dns.Msg) (rm *dns.Msg, t time.Duration, err error) {
client := &dns.Client{}
upstreamHost, _, err := net.SplitHostPort(upstream)
if err != nil {
Expand Down
9 changes: 1 addition & 8 deletions client/internal/dns/upstream_nonios.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,7 @@ func newUpstreamResolver(parentCTX context.Context, interfaceName string, ip net
return nonIOS, nil
}

func (u *upstreamResolverNonIOS) exchange(upstream string, r *dns.Msg) (rm *dns.Msg, t time.Duration, err error) {
// default upstream timeout
ctx, cancel := context.WithTimeout(u.ctx, u.upstreamTimeout)
defer cancel()
return u.exchangeContext(ctx, upstream, r)
}

func (u *upstreamResolverNonIOS) exchangeContext(ctx context.Context, upstream string, r *dns.Msg) (rm *dns.Msg, t time.Duration, err error) {
func (u *upstreamResolverNonIOS) exchange(ctx context.Context, upstream string, r *dns.Msg) (rm *dns.Msg, t time.Duration, err error) {
upstreamExchangeClient := &dns.Client{}
return upstreamExchangeClient.ExchangeContext(ctx, r, upstream)
}
9 changes: 2 additions & 7 deletions client/internal/dns/upstream_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -105,13 +105,8 @@ type mockUpstreamResolver struct {
err error
}

// Exchange mock implementation of Exchangefrom upstreamResolver
func (c mockUpstreamResolver) exchange(upstream string, r *dns.Msg) (*dns.Msg, time.Duration, error) {
return c.exchangeContext(context.Background(), upstream, r)
}

// ExchangeContext mock implementation of ExchangeContext from upstreamResolver
func (c mockUpstreamResolver) exchangeContext(_ context.Context, _ string, _ *dns.Msg) (*dns.Msg, time.Duration, error) {
// exchange mock implementation of exchange from upstreamResolver
func (c mockUpstreamResolver) exchange(_ context.Context, _ string, _ *dns.Msg) (*dns.Msg, time.Duration, error) {
return c.r, c.rtt, c.err
}

Expand Down

0 comments on commit 8b28781

Please sign in to comment.