diff --git a/nameserver/nameserver.go b/nameserver/nameserver.go index 635c2b94..167e668d 100644 --- a/nameserver/nameserver.go +++ b/nameserver/nameserver.go @@ -73,13 +73,6 @@ func handleRequest(ctx context.Context, w dns.ResponseWriter, request *dns.Msg) return nil } - // Return with server failure if offline. - if netenv.GetOnlineStatus() == netenv.StatusOffline && - !netenv.IsConnectivityDomain(q.FQDN) { - tracer.Debugf("nameserver: not resolving %s, device is offline", q.FQDN) - return reply(nsutil.ServerFailure("resolving disabled, device is offline")) - } - // Check the Query Class. if originalQuestion.Qclass != dns.ClassINET { // we only serve IN records, return nxdomain @@ -186,6 +179,14 @@ func handleRequest(ctx context.Context, w dns.ResponseWriter, request *dns.Msg) case errors.Is(err, resolver.ErrLocalhost): tracer.Tracef("nameserver: returning localhost records") return reply(nsutil.Localhost()) + case errors.Is(err, resolver.ErrOffline): + if rrCache == nil { + log.Tracer(ctx).Debugf("nameserver: not resolving %s, device is offline", q.ID()) + return reply(nsutil.ServerFailure(err.Error())) + } + // If an rrCache was returned, it's usable a backup. + rrCache.IsBackup = true + log.Tracer(ctx).Debugf("nameserver: device is offline, using backup cache for %s", q.ID()) default: tracer.Warningf("nameserver: failed to resolve %s: %s", q.ID(), err) return reply(nsutil.ServerFailure("internal error: " + err.Error())) diff --git a/resolver/resolve.go b/resolver/resolve.go index 22f2fe23..631bcb03 100644 --- a/resolver/resolve.go +++ b/resolver/resolve.go @@ -317,9 +317,8 @@ func resolveAndCache(ctx context.Context, q *Query, oldCache *RRCache) (rrCache // check if we are online if netenv.GetOnlineStatus() == netenv.StatusOffline { if !netenv.IsConnectivityDomain(q.FQDN) { - log.Tracer(ctx).Debugf("resolver: not resolving %s, device is offline", q.FQDN) // we are offline and this is not an online check query - return nil, ErrOffline + return oldCache, ErrOffline } log.Tracer(ctx).Debugf("resolver: permitting online status test domain %s to resolve even though offline", q.FQDN) } @@ -356,9 +355,8 @@ resolveLoop: return nil, err case netenv.GetOnlineStatus() == netenv.StatusOffline && !netenv.IsConnectivityDomain(q.FQDN): - log.Tracer(ctx).Debugf("resolver: not resolving %s, device is offline", q.FQDN) // we are offline and this is not an online check query - return nil, ErrOffline + return oldCache, ErrOffline case errors.Is(err, ErrContinue): continue case errors.Is(err, ErrTimeout): diff --git a/resolver/rrcache.go b/resolver/rrcache.go index a2af8f27..50e51545 100644 --- a/resolver/rrcache.go +++ b/resolver/rrcache.go @@ -324,7 +324,7 @@ func (rrCache *RRCache) GetExtraRRs(ctx context.Context, query *dns.Msg) (extra extra = addExtra(ctx, extra, "async request to refresh the cache has been started") } if rrCache.IsBackup { - extra = addExtra(ctx, extra, "this record is served because a fresh request failed") + extra = addExtra(ctx, extra, "this record is served because a fresh request was unsuccessful") } // Add information about filtered entries.