nextdnsEndpointManager returns a endpoint.Manager configured to connect to NextDNS using different steering techniques.
(log host.Logger, debug bool, canFallback func() bool)
| 559 | // nextdnsEndpointManager returns a endpoint.Manager configured to connect to |
| 560 | // NextDNS using different steering techniques. |
| 561 | func nextdnsEndpointManager(log host.Logger, debug bool, canFallback func() bool) *endpoint.Manager { |
| 562 | m := &endpoint.Manager{ |
| 563 | Providers: []endpoint.Provider{ |
| 564 | // Prefer unicast routing. |
| 565 | &endpoint.SourceHTTPSSVCProvider{ |
| 566 | Hostname: "dns.nextdns.io", |
| 567 | Source: endpoint.MustNew("https://dns.nextdns.io#45.90.28.0,2a07:a8c0::,45.90.30.0,2a07:a8c1::"), |
| 568 | }, |
| 569 | // Try routing without anycast bootstrap. |
| 570 | // TOFIX: this creates circular dependency if the /etc/resolv.conf is setup to localhost. |
| 571 | // &endpoint.SourceHTTPSSVCProvider{ |
| 572 | // Hostname: "dns.nextdns.io", |
| 573 | // Source: endpoint.MustNew("https://dns.nextdns.io"), |
| 574 | // }, |
| 575 | // Fallback on anycast. |
| 576 | endpoint.StaticProvider([]endpoint.Endpoint{ |
| 577 | endpoint.MustNew("https://dns1.nextdns.io#45.90.28.0,2a07:a8c0::"), |
| 578 | endpoint.MustNew("https://dns2.nextdns.io#45.90.30.0,2a07:a8c1::"), |
| 579 | }), |
| 580 | }, |
| 581 | InitEndpoint: endpoint.MustNew("https://dns.nextdns.io#45.90.28.0,2a07:a8c0::,45.90.30.0,2a07:a8c1::"), |
| 582 | OnError: func(e endpoint.Endpoint, err error) { |
| 583 | log.Warningf("Endpoint failed: %v: %v", e, err) |
| 584 | }, |
| 585 | OnProviderError: func(p endpoint.Provider, err error) { |
| 586 | log.Warningf("Endpoint provider failed: %v: %v", p, err) |
| 587 | }, |
| 588 | OnConnect: func(ci *endpoint.ConnectInfo) { |
| 589 | log.Infof("Connected %s (con=%dms tls=%dms, %s, %s)", |
| 590 | ci.ServerAddr, |
| 591 | ci.ConnectTimes[ci.ServerAddr]/time.Millisecond, |
| 592 | ci.TLSTime/time.Millisecond, |
| 593 | ci.Protocol, |
| 594 | ci.TLSVersion) |
| 595 | }, |
| 596 | OnChange: func(e endpoint.Endpoint) { |
| 597 | log.Infof("Switching endpoint: %s", e) |
| 598 | }, |
| 599 | } |
| 600 | // Fallback on system DNS and set a short min test interval for when plain |
| 601 | // DNS protocol is used so we go back on safe DoH as soon as possible. This |
| 602 | // allows automatic handling of captive portals as well as NTP / DNS |
| 603 | // inter-dependency on some routers, when NTP needs DNS to sync the time, |
| 604 | // and DoH needs time properly set to establish a TLS session. |
| 605 | m.Providers = append(m.Providers, endpoint.ProviderFunc(func(ctx context.Context) ([]endpoint.Endpoint, error) { |
| 606 | if !canFallback() { |
| 607 | // Fallback disabled. |
| 608 | return nil, nil |
| 609 | } |
| 610 | ips := host.DNS() |
| 611 | endpoints := make([]endpoint.Endpoint, 0, len(ips)+1) |
| 612 | for _, ip := range ips { |
| 613 | endpoints = append(endpoints, &endpoint.DNSEndpoint{ |
| 614 | Addr: net.JoinHostPort(ip, "53"), |
| 615 | }) |
| 616 | } |
| 617 | // Add NextDNS anycast IP in case none of the system DNS works or we did |
| 618 | // not find any. |
no test coverage detected
searching dependent graphs…