mirror of
https://github.com/netbirdio/netbird.git
synced 2026-04-16 07:16:38 +00:00
* Optimize Windows DNS performance with domain batching and batch mode Implement two-layer optimization to reduce Windows NRPT registry operations: 1. Domain Batching (host_windows.go): - Batch domains per NRPT - Reduces NRPT rules by ~97% (e.g., 184 domains: 184 rules → 4 rules) - Modified addDNSMatchPolicy() to create batched NRPT entries - Added comprehensive tests in host_windows_test.go 2. Batch Mode (server.go): - Added BeginBatch/EndBatch methods to defer DNS updates - Modified RegisterHandler/DeregisterHandler to skip applyHostConfig in batch mode - Protected all applyHostConfig() calls with batch mode checks - Updated route manager to wrap route operations with batch calls * Update tests * Fix log line * Fix NRPT rule index to ensure cleanup covers partially created rules * Ensure NRPT entry count updates even on errors to improve cleanup reliability * Switch DNS batch mode logging from Info to Debug level * Fix batch mode to not suppress critical DNS config updates Batch mode should only defer applyHostConfig() for RegisterHandler/ DeregisterHandler operations. Management updates and upstream nameserver failures (deactivate/reactivate callbacks) need immediate DNS config updates regardless of batch mode to ensure timely failover. Without this fix, if a nameserver goes down during a route update, the system DNS config won't be updated until EndBatch(), potentially delaying failover by several seconds. Or if you prefer a shorter version: Fix batch mode to allow immediate DNS updates for critical paths Batch mode now only affects RegisterHandler/DeregisterHandler. Management updates and nameserver failures always trigger immediate DNS config updates to ensure timely failover. * Add DNS batch cancellation to rollback partial changes on errors Introduces CancelBatch() method to the DNS server interface to handle error scenarios during batch operations. When route updates fail partway through, the DNS server can now discard accumulated changes instead of applying partial state. This prevents leaving the DNS configuration in an inconsistent state when route manager operations encounter errors. The changes add error-aware batch handling to prevent partial DNS configuration updates when route operations fail, which improves system reliability.
102 lines
2.7 KiB
Go
102 lines
2.7 KiB
Go
package dns
|
|
|
|
import (
|
|
"fmt"
|
|
"net/netip"
|
|
"net/url"
|
|
|
|
"github.com/miekg/dns"
|
|
|
|
dnsconfig "github.com/netbirdio/netbird/client/internal/dns/config"
|
|
nbdns "github.com/netbirdio/netbird/dns"
|
|
"github.com/netbirdio/netbird/shared/management/domain"
|
|
)
|
|
|
|
// MockServer is the mock instance of a dns server
|
|
type MockServer struct {
|
|
InitializeFunc func() error
|
|
StopFunc func()
|
|
UpdateDNSServerFunc func(serial uint64, update nbdns.Config) error
|
|
RegisterHandlerFunc func(domain.List, dns.Handler, int)
|
|
DeregisterHandlerFunc func(domain.List, int)
|
|
UpdateServerConfigFunc func(domains dnsconfig.ServerDomains) error
|
|
}
|
|
|
|
func (m *MockServer) RegisterHandler(domains domain.List, handler dns.Handler, priority int) {
|
|
if m.RegisterHandlerFunc != nil {
|
|
m.RegisterHandlerFunc(domains, handler, priority)
|
|
}
|
|
}
|
|
|
|
func (m *MockServer) DeregisterHandler(domains domain.List, priority int) {
|
|
if m.DeregisterHandlerFunc != nil {
|
|
m.DeregisterHandlerFunc(domains, priority)
|
|
}
|
|
}
|
|
|
|
// Initialize mock implementation of Initialize from Server interface
|
|
func (m *MockServer) Initialize() error {
|
|
if m.InitializeFunc != nil {
|
|
return m.InitializeFunc()
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// Stop mock implementation of Stop from Server interface
|
|
func (m *MockServer) Stop() {
|
|
if m.StopFunc != nil {
|
|
m.StopFunc()
|
|
}
|
|
}
|
|
|
|
func (m *MockServer) DnsIP() netip.Addr {
|
|
return netip.MustParseAddr("100.10.254.255")
|
|
}
|
|
|
|
func (m *MockServer) OnUpdatedHostDNSServer(addrs []netip.AddrPort) {
|
|
// TODO implement me
|
|
panic("implement me")
|
|
}
|
|
|
|
// UpdateDNSServer mock implementation of UpdateDNSServer from Server interface
|
|
func (m *MockServer) UpdateDNSServer(serial uint64, update nbdns.Config) error {
|
|
if m.UpdateDNSServerFunc != nil {
|
|
return m.UpdateDNSServerFunc(serial, update)
|
|
}
|
|
return fmt.Errorf("method UpdateDNSServer is not implemented")
|
|
}
|
|
|
|
func (m *MockServer) SearchDomains() []string {
|
|
return make([]string, 0)
|
|
}
|
|
|
|
// ProbeAvailability mocks implementation of ProbeAvailability from the Server interface
|
|
func (m *MockServer) ProbeAvailability() {
|
|
}
|
|
|
|
func (m *MockServer) UpdateServerConfig(domains dnsconfig.ServerDomains) error {
|
|
if m.UpdateServerConfigFunc != nil {
|
|
return m.UpdateServerConfigFunc(domains)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (m *MockServer) PopulateManagementDomain(mgmtURL *url.URL) error {
|
|
return nil
|
|
}
|
|
|
|
// BeginBatch mock implementation of BeginBatch from Server interface
|
|
func (m *MockServer) BeginBatch() {
|
|
// Mock implementation - no-op
|
|
}
|
|
|
|
// EndBatch mock implementation of EndBatch from Server interface
|
|
func (m *MockServer) EndBatch() {
|
|
// Mock implementation - no-op
|
|
}
|
|
|
|
// CancelBatch mock implementation of CancelBatch from Server interface
|
|
func (m *MockServer) CancelBatch() {
|
|
// Mock implementation - no-op
|
|
}
|