2022-11-23 13:39:42 +01:00
package dns
import (
"fmt"
2024-01-30 09:58:56 +01:00
"net/netip"
2022-11-23 13:39:42 +01:00
"strings"
2023-02-13 15:25:11 +01:00
2024-10-24 10:53:46 +02:00
"github.com/netbirdio/netbird/client/internal/statemanager"
2023-02-13 15:25:11 +01:00
nbdns "github.com/netbirdio/netbird/dns"
2022-11-23 13:39:42 +01:00
)
2025-02-21 16:29:21 +01:00
var ErrRouteAllWithoutNameserverGroup = fmt . Errorf ( "unable to configure DNS for this peer using file manager without a nameserver group with all domains configured" )
2025-02-21 12:52:04 +01:00
const (
ipv4ReverseZone = ".in-addr.arpa"
ipv6ReverseZone = ".ip6.arpa"
)
2022-11-23 13:39:42 +01:00
type hostManager interface {
2024-10-24 10:53:46 +02:00
applyDNSConfig ( config HostDNSConfig , stateManager * statemanager . Manager ) error
2022-11-23 13:39:42 +01:00
restoreHostDNS ( ) error
2023-05-17 00:03:26 +02:00
supportCustomPort ( ) bool
2025-02-21 16:29:21 +01:00
string ( ) string
2022-11-23 13:39:42 +01:00
}
2024-07-18 16:39:41 +02:00
type SystemDNSSettings struct {
Domains [ ] string
ServerIP string
ServerPort int
}
2023-12-18 11:46:58 +01:00
type HostDNSConfig struct {
Domains [ ] DomainConfig ` json:"domains" `
RouteAll bool ` json:"routeAll" `
ServerIP string ` json:"serverIP" `
ServerPort int ` json:"serverPort" `
2022-11-23 13:39:42 +01:00
}
2023-12-18 11:46:58 +01:00
type DomainConfig struct {
Disabled bool ` json:"disabled" `
Domain string ` json:"domain" `
MatchOnly bool ` json:"matchOnly" `
2022-11-23 13:39:42 +01:00
}
type mockHostConfigurator struct {
2024-10-24 10:53:46 +02:00
applyDNSConfigFunc func ( config HostDNSConfig , stateManager * statemanager . Manager ) error
2024-01-30 09:58:56 +01:00
restoreHostDNSFunc func ( ) error
supportCustomPortFunc func ( ) bool
restoreUncleanShutdownDNSFunc func ( * netip . Addr ) error
2025-02-21 16:29:21 +01:00
stringFunc func ( ) string
2022-11-23 13:39:42 +01:00
}
2024-10-24 10:53:46 +02:00
func ( m * mockHostConfigurator ) applyDNSConfig ( config HostDNSConfig , stateManager * statemanager . Manager ) error {
2022-11-23 13:39:42 +01:00
if m . applyDNSConfigFunc != nil {
2024-10-24 10:53:46 +02:00
return m . applyDNSConfigFunc ( config , stateManager )
2022-11-23 13:39:42 +01:00
}
return fmt . Errorf ( "method applyDNSSettings is not implemented" )
}
func ( m * mockHostConfigurator ) restoreHostDNS ( ) error {
if m . restoreHostDNSFunc != nil {
return m . restoreHostDNSFunc ( )
}
return fmt . Errorf ( "method restoreHostDNS is not implemented" )
}
2023-05-17 00:03:26 +02:00
func ( m * mockHostConfigurator ) supportCustomPort ( ) bool {
if m . supportCustomPortFunc != nil {
return m . supportCustomPortFunc ( )
}
return false
}
2025-02-21 16:29:21 +01:00
func ( m * mockHostConfigurator ) string ( ) string {
if m . stringFunc != nil {
return m . stringFunc ( )
}
return "mock"
}
2022-11-23 13:39:42 +01:00
func newNoopHostMocker ( ) hostManager {
return & mockHostConfigurator {
2024-10-24 10:53:46 +02:00
applyDNSConfigFunc : func ( config HostDNSConfig , stateManager * statemanager . Manager ) error { return nil } ,
2024-01-30 09:58:56 +01:00
restoreHostDNSFunc : func ( ) error { return nil } ,
supportCustomPortFunc : func ( ) bool { return true } ,
restoreUncleanShutdownDNSFunc : func ( * netip . Addr ) error { return nil } ,
2022-11-23 13:39:42 +01:00
}
}
2023-12-18 11:46:58 +01:00
func dnsConfigToHostDNSConfig ( dnsConfig nbdns . Config , ip string , port int ) HostDNSConfig {
config := HostDNSConfig {
RouteAll : false ,
ServerIP : ip ,
ServerPort : port ,
2022-11-23 13:39:42 +01:00
}
for _ , nsConfig := range dnsConfig . NameServerGroups {
2023-02-13 15:25:11 +01:00
if len ( nsConfig . NameServers ) == 0 {
continue
}
2022-11-23 13:39:42 +01:00
if nsConfig . Primary {
2023-12-18 11:46:58 +01:00
config . RouteAll = true
2022-11-23 13:39:42 +01:00
}
for _ , domain := range nsConfig . Domains {
2023-12-18 11:46:58 +01:00
config . Domains = append ( config . Domains , DomainConfig {
Domain : strings . TrimSuffix ( domain , "." ) ,
MatchOnly : ! nsConfig . SearchDomainsEnabled ,
2022-11-23 13:39:42 +01:00
} )
}
}
for _ , customZone := range dnsConfig . CustomZones {
2025-02-21 12:52:04 +01:00
matchOnly := strings . HasSuffix ( customZone . Domain , ipv4ReverseZone ) || strings . HasSuffix ( customZone . Domain , ipv6ReverseZone )
2023-12-18 11:46:58 +01:00
config . Domains = append ( config . Domains , DomainConfig {
Domain : strings . TrimSuffix ( customZone . Domain , "." ) ,
2025-02-21 12:52:04 +01:00
MatchOnly : matchOnly ,
2022-11-23 13:39:42 +01:00
} )
}
return config
}
2025-01-07 20:38:18 +01:00
type noopHostConfigurator struct { }
func ( n noopHostConfigurator ) applyDNSConfig ( HostDNSConfig , * statemanager . Manager ) error {
return nil
}
func ( n noopHostConfigurator ) restoreHostDNS ( ) error {
return nil
}
func ( n noopHostConfigurator ) supportCustomPort ( ) bool {
return true
}
2025-02-21 16:29:21 +01:00
func ( n noopHostConfigurator ) string ( ) string {
return "noop"
}