mirror of
https://github.com/netbirdio/netbird.git
synced 2026-08-29 19:11:28 +02:00
## Describe your changes
getIPsFromResolver passed a nil context to ExchangeWithFallback, which
net.Dialer.DialContext rejects with panic("nil context"). On iOS this
crashed the whole network extension (SIGABRT) ~2 seconds after connect
whenever the network map contained a domain-based (dynamic) route, as
the resolver goroutine panicked on its first DNS query.
Passing nil used to be a documented input of ExchangeWithFallback ("If
the passed context is nil, this will use Exchange instead of
ExchangeContext") since #3632. 9ed2e2a5b (#5971) removed the nil-context
branch, but this iOS-only caller was not updated — it never fails CI
since route_ios.go only builds with GOOS=ios. Broken since v0.71.1.
Pass a context bounded by the existing dialTimeout instead, matching the
dnsinterceptor pattern (context.Background() + timeout).
Captured panic (netbird.err):
panic: nil context
net.(*Dialer).DialContext -> miekg/dns ExchangeContext ->
nbdns.ExchangeWithFallback(nil, ...) ->
dynamic.(*Route).getIPsFromResolver
route_ios.go:35
## Issue ticket number and link
## Stack
<!-- branch-stack -->
### Checklist
- [x] Is it a bug fix
- [ ] Is a typo/documentation fix
- [ ] Is a feature enhancement
- [ ] It is a refactor
- [ ] Created tests that fail without the change (if possible)
- [ ] This change does **not** modify the public API, gRPC protocols,
functionality behavior, CLI / service flags, or introduce a new feature
— **OR** I have discussed it with the NetBird team beforehand (link the
issue / Slack thread in the description). See
[CONTRIBUTING.md](https://github.com/netbirdio/netbird/blob/main/CONTRIBUTING.md#discuss-changes-with-the-netbird-team-first).
> By submitting this pull request, you confirm that you have read and
agree to the terms of the [Contributor License
Agreement](https://github.com/netbirdio/netbird/blob/main/CONTRIBUTOR_LICENSE_AGREEMENT.md).
## Documentation
Select exactly one:
- [ ] I added/updated documentation for this change
- [x] Documentation is **not needed** for this change (explain why)
### Docs PR URL (required if "docs added" is checked)
Paste the PR link from https://github.com/netbirdio/docs here:
https://github.com/netbirdio/docs/pull/__
<!-- codesmith:footer -->
---
<a
href="https://app.blacksmith.sh/netbirdio/codesmith/netbird/pr/6848"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://pr-comments-assets.blacksmith.sh/codesmith/view-with-codesmith-dark-v2.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://pr-comments-assets.blacksmith.sh/codesmith/view-with-codesmith-light-v2.svg"><img
alt="View with Codesmith"
src="https://pr-comments-assets.blacksmith.sh/codesmith/view-with-codesmith-dark-v2.svg"></picture></a>
<a
href="https://backend.blacksmith.sh/track/enable-autofix?expires=1787223752&installation_model_id=427504&pr_number=6848&repository=netbirdio%2Fnetbird&return_to=https%3A%2F%2Fgithub.com%2Fnetbirdio%2Fnetbird%2Fpull%2F6848&signature=881d3b30aa4bd15001562ad417ff946b70c7c108856a1b3808b776c12b7022a9"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://pr-comments-assets.blacksmith.sh/codesmith/autofix-with-codesmith-dark.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://pr-comments-assets.blacksmith.sh/codesmith/autofix-with-codesmith-light.svg"><img
alt="Autofix with Codesmith"
src="https://pr-comments-assets.blacksmith.sh/codesmith/autofix-with-codesmith-dark.svg"></picture></a>
<sup>Need help on this PR? Tag <code>/codesmith</code> with what you
need. Autofix is disabled.</sup>
<!-- codesmith:autofix:disabled -->
<!-- /codesmith:footer -->
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Bug Fixes**
* Fixed iOS dynamic DNS resolution by ensuring DNS queries use a proper
resolver context instead of a nil one.
* Improved DNS resolution reliability by propagating
cancellation/timeouts through all domain IP lookups, including fallback
system resolver queries.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
67 lines
1.5 KiB
Go
67 lines
1.5 KiB
Go
//go:build ios
|
|
|
|
package dynamic
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"net"
|
|
"time"
|
|
|
|
"github.com/miekg/dns"
|
|
|
|
nbdns "github.com/netbirdio/netbird/client/internal/dns"
|
|
|
|
"github.com/netbirdio/netbird/shared/management/domain"
|
|
)
|
|
|
|
const dialTimeout = 10 * time.Second
|
|
|
|
func (r *Route) getIPsFromResolver(ctx context.Context, domain domain.Domain) ([]net.IP, error) {
|
|
privateClient, err := nbdns.GetClientPrivate(r.wgInterface, r.resolverAddr.Addr(), dialTimeout)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("error while creating private client: %s", err)
|
|
}
|
|
|
|
fqdn := dns.Fqdn(domain.PunycodeString())
|
|
startTime := time.Now()
|
|
|
|
var ips []net.IP
|
|
var queryErr error
|
|
|
|
for _, qtype := range []uint16{dns.TypeA, dns.TypeAAAA} {
|
|
msg := new(dns.Msg)
|
|
msg.SetQuestion(fqdn, qtype)
|
|
|
|
response, _, err := nbdns.ExchangeWithFallback(ctx, privateClient, msg, r.resolverAddr.String())
|
|
if err != nil {
|
|
if queryErr == nil {
|
|
queryErr = fmt.Errorf("DNS query for %s (type %d) after %s: %w", domain.SafeString(), qtype, time.Since(startTime), err)
|
|
}
|
|
continue
|
|
}
|
|
|
|
if response.Rcode != dns.RcodeSuccess {
|
|
continue
|
|
}
|
|
|
|
for _, answ := range response.Answer {
|
|
if aRecord, ok := answ.(*dns.A); ok {
|
|
ips = append(ips, aRecord.A)
|
|
}
|
|
if aaaaRecord, ok := answ.(*dns.AAAA); ok {
|
|
ips = append(ips, aaaaRecord.AAAA)
|
|
}
|
|
}
|
|
}
|
|
|
|
if len(ips) == 0 {
|
|
if queryErr != nil {
|
|
return nil, queryErr
|
|
}
|
|
return nil, fmt.Errorf("no A or AAAA records found for %s", domain.SafeString())
|
|
}
|
|
|
|
return ips, nil
|
|
}
|