- Rewrite README.md with overview, features, installation (go install +
build from source), quick start, full CLI flag reference table,
output section descriptions, project structure, and development guide
- Add package-level doc comments to all five internal packages:
config, dns, fingerprint, output, traverse (via doc.go or existing
package-declaration files)
- Add GoDoc comments on every exported type, constant, function, and
method across all packages:
- internal/config: Config struct fields, all Parse*/Default/Validate
- internal/dns: QueryConfig, Resolver, BasicResolver, CachingResolver,
ExchangeFunc, RootServer, RootDiscoveryConfig, DecodedResponse,
ResponseClassification, all exported helpers
- internal/fingerprint: Fingerprinter, New, NewWithTimeout, Query,
FingerprintAll
- internal/traverse: Traverser, TraverserConfig, TraversalResult,
Referral, ResolutionState, Response, ResponseType, InfoCache,
Stack, TraverserHooks, EventStage, TraversalEvent, EventHandler,
CircularReferralError, UnresolvableNameserverError
- internal/output: Format, Config, Formatter, SummaryStats,
NewFormatter, AttachHooks, RunTraversal, DefaultConfig,
ComputeSummary
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
fe1afe2a97
commit
9aa85d8e5d
@@ -7,19 +7,21 @@ import (
|
||||
miekgdns "github.com/miekg/dns"
|
||||
)
|
||||
|
||||
// ResponseType classifies the outcome of querying a single Referral.
|
||||
type ResponseType int
|
||||
|
||||
// Response type constants used to drive traversal logic.
|
||||
const (
|
||||
RespReferral ResponseType = iota
|
||||
RespAnswer
|
||||
RespCNAMEFollow
|
||||
RespNODATA
|
||||
RespNXDOMAIN
|
||||
RespSERVFAIL
|
||||
RespREFUSED
|
||||
RespNOTIMPL
|
||||
RespCNAMELoop
|
||||
RespError
|
||||
RespReferral ResponseType = iota // server returned an NS referral
|
||||
RespAnswer // server returned a final answer
|
||||
RespCNAMEFollow // answer contains a CNAME requiring further traversal
|
||||
RespNODATA // NOERROR with no matching records
|
||||
RespNXDOMAIN // name does not exist
|
||||
RespSERVFAIL // server failure
|
||||
RespREFUSED // query refused
|
||||
RespNOTIMPL // query type not implemented
|
||||
RespCNAMELoop // CNAME chain revisits a name already in the chain
|
||||
RespError // transport or decoding error
|
||||
)
|
||||
|
||||
func (rt ResponseType) String() string {
|
||||
@@ -49,15 +51,25 @@ func (rt ResponseType) String() string {
|
||||
}
|
||||
}
|
||||
|
||||
// Response is the result of querying a single Referral against a specific
|
||||
// nameserver. It contains the decoded DNS message, the classified ResponseType,
|
||||
// and any error message for display.
|
||||
type Response struct {
|
||||
Referral *Referral
|
||||
Server net.IP
|
||||
Cache *InfoCache
|
||||
Decoded *dns.DecodedResponse
|
||||
Type ResponseType
|
||||
// Referral is the query this response corresponds to.
|
||||
Referral *Referral
|
||||
// Server is the nameserver IP that was queried.
|
||||
Server net.IP
|
||||
// Cache is the InfoCache used during processing (for glue resolution).
|
||||
Cache *InfoCache
|
||||
// Decoded holds the structured DNS response fields.
|
||||
Decoded *dns.DecodedResponse
|
||||
// Type is the high-level classification of this response.
|
||||
Type ResponseType
|
||||
// ErrorMessage is a human-readable description when Type is RespError or RespCNAMELoop.
|
||||
ErrorMessage string
|
||||
}
|
||||
|
||||
// NewResponse creates a Response for the given Referral and server.
|
||||
func NewResponse(ref *Referral, server net.IP, cache *InfoCache) *Response {
|
||||
return &Response{
|
||||
Referral: ref,
|
||||
@@ -66,6 +78,9 @@ func NewResponse(ref *Referral, server net.IP, cache *InfoCache) *Response {
|
||||
}
|
||||
}
|
||||
|
||||
// Process decodes msg, classifies it, and populates r.Type and r.Decoded.
|
||||
// Synthesises CNAME records from DNAME mappings when no explicit CNAME is present.
|
||||
// Returns r for chaining.
|
||||
func (r *Response) Process(msg *miekgdns.Msg) *Response {
|
||||
if msg == nil {
|
||||
r.Type = RespError
|
||||
@@ -133,6 +148,10 @@ func (r *Response) hasFinalAnswer() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// ChildReferrals returns the set of child Referrals implied by a referral
|
||||
// response. It extracts nameservers from the authority section, resolves
|
||||
// any glue from the additional section, and sets Prob proportionally.
|
||||
// Returns nil when Type != RespReferral.
|
||||
func (r *Response) ChildReferrals() []*Referral {
|
||||
if r.Type != RespReferral {
|
||||
return nil
|
||||
@@ -177,6 +196,8 @@ func (r *Response) ChildReferrals() []*Referral {
|
||||
return children
|
||||
}
|
||||
|
||||
// CNAMEFollowReferral constructs a follow-up Referral targeting the last CNAME
|
||||
// in the chain. Returns nil when Type != RespCNAMEFollow.
|
||||
func (r *Response) CNAMEFollowReferral() *Referral {
|
||||
if r.Type != RespCNAMEFollow || len(r.Decoded.CNAMEChain) == 0 {
|
||||
return nil
|
||||
@@ -229,6 +250,8 @@ func (r *Response) resolveGlue(child *Referral) {
|
||||
r.Cache.StoreGlue(nsName, child.Addresses)
|
||||
}
|
||||
|
||||
// IsTerminal reports whether this response ends a traversal branch (no further
|
||||
// referrals or CNAME follows are expected).
|
||||
func (r *Response) IsTerminal() bool {
|
||||
switch r.Type {
|
||||
case RespAnswer, RespNODATA, RespNXDOMAIN, RespSERVFAIL, RespREFUSED, RespNOTIMPL, RespCNAMELoop, RespError:
|
||||
|
||||
Reference in New Issue
Block a user