- Exponential backoff retry logic (100ms, 200ms, 400ms... capped at 2s) replacing fixed 100ms delay between retries - Explicit REFUSED and NOTIMP response types (RespREFUSED, RespNOTIMPL) surfaced as terminal results with user-visible messages - CNAME loop detection: walking the ancestor referral chain before following a CNAME prevents infinite recursion; produces RespCNAMELoop - DNAME record support: synthesize CNAME target from DNAME mapping when the server omits the RFC 6672 synthesized CNAME record - ErrorMessage field on Response for surfacing error details to users - Fix resolveGlueViaSystem timeout bug: deadline.Sub(deadline) was always 0; replaced with time.Until(deadline) - DNAME records excluded from hasFinalAnswer so DNAME-only responses are correctly classified as RespCNAMEFollow - Text and JSON output updated with labels for all new response types - Tests: CNAME loop (2-step and direct), REFUSED, NOTIMP, graceful degradation (partial and total server failure), DNAME synthesis, IsNameInChain, backoffDelay, ResponseClassification strings Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: multica-agent <github@multica.ai>
This commit is contained in:
co-authored by
Copilot
multica-agent
parent
76f5010a5e
commit
368f200d23
@@ -138,6 +138,12 @@ func summaryTypeLabel(respType string) string {
|
||||
return "name does not exist"
|
||||
case "servfail":
|
||||
return "resulted in SERVFAIL"
|
||||
case "refused":
|
||||
return "query refused by server"
|
||||
case "notimp":
|
||||
return "query type not implemented by server"
|
||||
case "cname_loop":
|
||||
return "resulted in a CNAME loop"
|
||||
case "error":
|
||||
return "resulted in an error"
|
||||
case "referral":
|
||||
|
||||
+15
-1
@@ -210,8 +210,22 @@ func (f *textFormatter) formatResultLine(result traverse.TraversalResult) string
|
||||
return f.colorize(fmt.Sprintf("%s name does not exist", prob), colorYellow)
|
||||
case traverse.RespSERVFAIL:
|
||||
return f.colorize(fmt.Sprintf("%s resulted in SERVFAIL", prob), colorRed)
|
||||
case traverse.RespREFUSED:
|
||||
return f.colorize(fmt.Sprintf("%s query refused by server", prob), colorRed)
|
||||
case traverse.RespNOTIMPL:
|
||||
return f.colorize(fmt.Sprintf("%s query type not implemented by server", prob), colorRed)
|
||||
case traverse.RespCNAMELoop:
|
||||
msg := "CNAME loop detected"
|
||||
if result.Response.ErrorMessage != "" {
|
||||
msg = result.Response.ErrorMessage
|
||||
}
|
||||
return f.colorize(fmt.Sprintf("%s %s", prob, msg), colorRed)
|
||||
case traverse.RespError:
|
||||
return f.colorize(fmt.Sprintf("%s resulted in an error", prob), colorRed)
|
||||
msg := "resulted in an error"
|
||||
if result.Response.ErrorMessage != "" {
|
||||
msg = result.Response.ErrorMessage
|
||||
}
|
||||
return f.colorize(fmt.Sprintf("%s %s", prob, msg), colorRed)
|
||||
default:
|
||||
return fmt.Sprintf("%s %s", prob, result.Response.Type)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user