@@ -2,6 +2,7 @@ package dns
2
2
3
3
import (
4
4
"context"
5
+ "errors"
5
6
"fmt"
6
7
"net/netip"
7
8
"runtime"
@@ -59,8 +60,10 @@ type hostManagerWithOriginalNS interface {
59
60
60
61
// DefaultServer dns server object
61
62
type DefaultServer struct {
62
- ctx context.Context
63
- ctxCancel context.CancelFunc
63
+ ctx context.Context
64
+ ctxCancel context.CancelFunc
65
+ // disableSys disables system DNS management (e.g., /etc/resolv.conf updates) while keeping the DNS service running.
66
+ // This is different from ServiceEnable=false from management which completely disables the DNS service.
64
67
disableSys bool
65
68
mux sync.Mutex
66
69
service service
@@ -187,6 +190,7 @@ func newDefaultServer(
187
190
statusRecorder : statusRecorder ,
188
191
stateManager : stateManager ,
189
192
hostsDNSHolder : newHostsDNSHolder (),
193
+ hostManager : & noopHostConfigurator {},
190
194
}
191
195
192
196
// register with root zone, handler chain takes care of the routing
@@ -258,7 +262,8 @@ func (s *DefaultServer) Initialize() (err error) {
258
262
s .mux .Lock ()
259
263
defer s .mux .Unlock ()
260
264
261
- if s .hostManager != nil {
265
+ if ! s .isUsingNoopHostManager () {
266
+ // already initialized
262
267
return nil
263
268
}
264
269
@@ -271,19 +276,19 @@ func (s *DefaultServer) Initialize() (err error) {
271
276
272
277
s .stateManager .RegisterState (& ShutdownState {})
273
278
274
- // use noop host manager if requested or running in netstack mode.
279
+ // Keep using noop host manager if dns off requested or running in netstack mode.
275
280
// Netstack mode currently doesn't have a way to receive DNS requests.
276
281
// TODO: Use listener on localhost in netstack mode when running as root.
277
282
if s .disableSys || netstack .IsEnabled () {
278
283
log .Info ("system DNS is disabled, not setting up host manager" )
279
- s .hostManager = & noopHostConfigurator {}
280
284
return nil
281
285
}
282
286
283
- s . hostManager , err = s .initialize ()
287
+ hostManager , err : = s .initialize ()
284
288
if err != nil {
285
289
return fmt .Errorf ("initialize: %w" , err )
286
290
}
291
+ s .hostManager = hostManager
287
292
return nil
288
293
}
289
294
@@ -297,26 +302,40 @@ func (s *DefaultServer) DnsIP() netip.Addr {
297
302
298
303
// Stop stops the server
299
304
func (s * DefaultServer ) Stop () {
305
+ s .ctxCancel ()
306
+
300
307
s .mux .Lock ()
301
308
defer s .mux .Unlock ()
302
- s .ctxCancel ()
303
309
304
- if s .hostManager != nil {
305
- if srvs , ok := s .hostManager .(hostManagerWithOriginalNS ); ok && len (srvs .getOriginalNameservers ()) > 0 {
306
- log .Debugf ("deregistering original nameservers as fallback handlers" )
307
- s .deregisterHandler ([]string {nbdns .RootZone }, PriorityFallback )
308
- }
310
+ if err := s .disableDNS (); err != nil {
311
+ log .Errorf ("failed to disable DNS: %v" , err )
312
+ }
309
313
310
- if err := s .hostManager .restoreHostDNS (); err != nil {
311
- log .Error ("failed to restore host DNS settings: " , err )
312
- } else if err := s .stateManager .DeleteState (& ShutdownState {}); err != nil {
313
- log .Errorf ("failed to delete shutdown dns state: %v" , err )
314
- }
314
+ maps .Clear (s .extraDomains )
315
+ }
316
+
317
+ func (s * DefaultServer ) disableDNS () error {
318
+ defer s .service .Stop ()
319
+
320
+ if s .isUsingNoopHostManager () {
321
+ return nil
315
322
}
316
323
317
- s .service .Stop ()
324
+ // Deregister original nameservers if they were registered as fallback
325
+ if srvs , ok := s .hostManager .(hostManagerWithOriginalNS ); ok && len (srvs .getOriginalNameservers ()) > 0 {
326
+ log .Debugf ("deregistering original nameservers as fallback handlers" )
327
+ s .deregisterHandler ([]string {nbdns .RootZone }, PriorityFallback )
328
+ }
318
329
319
- maps .Clear (s .extraDomains )
330
+ if err := s .hostManager .restoreHostDNS (); err != nil {
331
+ log .Errorf ("failed to restore host DNS settings: %v" , err )
332
+ } else if err := s .stateManager .DeleteState (& ShutdownState {}); err != nil {
333
+ log .Errorf ("failed to delete shutdown dns state: %v" , err )
334
+ }
335
+
336
+ s .hostManager = & noopHostConfigurator {}
337
+
338
+ return nil
320
339
}
321
340
322
341
// OnUpdatedHostDNSServer update the DNS servers addresses for root zones
@@ -357,10 +376,6 @@ func (s *DefaultServer) UpdateDNSServer(serial uint64, update nbdns.Config) erro
357
376
s .mux .Lock ()
358
377
defer s .mux .Unlock ()
359
378
360
- if s .hostManager == nil {
361
- return fmt .Errorf ("dns service is not initialized yet" )
362
- }
363
-
364
379
hash , err := hashstructure .Hash (update , hashstructure .FormatV2 , & hashstructure.HashOptions {
365
380
ZeroNil : true ,
366
381
IgnoreZeroValue : true ,
@@ -418,13 +433,14 @@ func (s *DefaultServer) ProbeAvailability() {
418
433
419
434
func (s * DefaultServer ) applyConfiguration (update nbdns.Config ) error {
420
435
// is the service should be Disabled, we stop the listener or fake resolver
421
- // and proceed with a regular update to clean up the handlers and records
422
436
if update .ServiceEnable {
423
- if err := s .service . Listen (); err != nil {
424
- log .Errorf ("failed to start DNS service : %v" , err )
437
+ if err := s .enableDNS (); err != nil {
438
+ log .Errorf ("failed to enable DNS: %v" , err )
425
439
}
426
440
} else if ! s .permanent {
427
- s .service .Stop ()
441
+ if err := s .disableDNS (); err != nil {
442
+ log .Errorf ("failed to disable DNS: %v" , err )
443
+ }
428
444
}
429
445
430
446
localMuxUpdates , localRecords , err := s .buildLocalHandlerUpdate (update .CustomZones )
@@ -469,11 +485,40 @@ func (s *DefaultServer) applyConfiguration(update nbdns.Config) error {
469
485
return nil
470
486
}
471
487
472
- func (s * DefaultServer ) applyHostConfig () {
473
- if s .hostManager == nil {
474
- return
488
+ func (s * DefaultServer ) isUsingNoopHostManager () bool {
489
+ _ , isNoop := s .hostManager .(* noopHostConfigurator )
490
+ return isNoop
491
+ }
492
+
493
+ func (s * DefaultServer ) enableDNS () error {
494
+ if err := s .service .Listen (); err != nil {
495
+ return fmt .Errorf ("start DNS service: %w" , err )
496
+ }
497
+
498
+ if ! s .isUsingNoopHostManager () {
499
+ return nil
500
+ }
501
+
502
+ if s .disableSys || netstack .IsEnabled () {
503
+ return nil
475
504
}
476
505
506
+ log .Info ("DNS service re-enabled, initializing host manager" )
507
+
508
+ if ! s .service .RuntimeIP ().IsValid () {
509
+ return errors .New ("DNS service runtime IP is invalid" )
510
+ }
511
+
512
+ hostManager , err := s .initialize ()
513
+ if err != nil {
514
+ return fmt .Errorf ("initialize host manager: %w" , err )
515
+ }
516
+ s .hostManager = hostManager
517
+
518
+ return nil
519
+ }
520
+
521
+ func (s * DefaultServer ) applyHostConfig () {
477
522
// prevent reapplying config if we're shutting down
478
523
if s .ctx .Err () != nil {
479
524
return
0 commit comments