- 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
@@ -0,0 +1,14 @@
|
||||
// Package output formats ExploreDNS traversal results for human-readable text
|
||||
// and machine-readable JSON output.
|
||||
//
|
||||
// The Formatter interface is the single point of contact for the traversal
|
||||
// engine. Two implementations are provided:
|
||||
//
|
||||
// - text formatter (default) — coloured, human-readable output.
|
||||
// - JSON formatter (--json flag) — structured JSON suitable for piping.
|
||||
//
|
||||
// NewFormatter selects the right implementation based on Config.Format.
|
||||
// RunTraversal is the high-level entry point: it attaches event hooks,
|
||||
// executes the traversal, fingerprints encountered servers, and writes the
|
||||
// final summary and flush.
|
||||
package output
|
||||
@@ -8,34 +8,53 @@ import (
|
||||
"github.com/hits/ExploreDNS/internal/traverse"
|
||||
)
|
||||
|
||||
// Format selects the output format.
|
||||
type Format int
|
||||
|
||||
// Output format constants.
|
||||
const (
|
||||
FormatText Format = iota
|
||||
FormatJSON
|
||||
FormatText Format = iota // human-readable coloured text (default)
|
||||
FormatJSON // machine-readable JSON
|
||||
)
|
||||
|
||||
// Config carries settings that control what the formatter emits.
|
||||
type Config struct {
|
||||
Format Format
|
||||
Domain string
|
||||
QueryType string
|
||||
ShowProgress bool
|
||||
ShowResolves bool
|
||||
ShowServers bool
|
||||
ShowVersions bool
|
||||
ShowAllStats bool
|
||||
ShowResults bool
|
||||
// Format selects text or JSON output.
|
||||
Format Format
|
||||
// Domain is the queried domain name, included in JSON output.
|
||||
Domain string
|
||||
// QueryType is the record type queried, included in JSON output.
|
||||
QueryType string
|
||||
// ShowProgress enables per-referral progress lines.
|
||||
ShowProgress bool
|
||||
// ShowResolves enables nameserver resolution detail lines.
|
||||
ShowResolves bool
|
||||
// ShowServers enables the server list section.
|
||||
ShowServers bool
|
||||
// ShowVersions enables version.bind fingerprint display alongside servers.
|
||||
ShowVersions bool
|
||||
// ShowAllStats enables per-result stats as they arrive (in text mode).
|
||||
ShowAllStats bool
|
||||
// ShowResults enables the terminal-results section.
|
||||
ShowResults bool
|
||||
// ShowSummaryResults enables the probability summary section.
|
||||
ShowSummaryResults bool
|
||||
Verbose bool
|
||||
Quiet bool
|
||||
Color bool
|
||||
Debug int
|
||||
// Verbose enables additional detail in progress lines.
|
||||
Verbose bool
|
||||
// Quiet suppresses the introductory banner line.
|
||||
Quiet bool
|
||||
// Color enables ANSI terminal colour codes in text output.
|
||||
Color bool
|
||||
// Debug controls debug verbosity for the formatter itself.
|
||||
Debug int
|
||||
|
||||
// Fingerprints maps server IP strings to their version.bind version strings.
|
||||
// Populated by RunTraversal when ShowVersions and ShowServers are both true.
|
||||
Fingerprints map[string]string
|
||||
}
|
||||
|
||||
// DefaultConfig returns a Config with all output sections enabled, text format,
|
||||
// and color determined by the NO_COLOR environment variable.
|
||||
func DefaultConfig() *Config {
|
||||
return &Config{
|
||||
Format: FormatText,
|
||||
@@ -50,14 +69,23 @@ func DefaultConfig() *Config {
|
||||
}
|
||||
}
|
||||
|
||||
// Formatter is the interface that both the text and JSON output backends implement.
|
||||
// Each method is called by the traversal hooks or by RunTraversal.
|
||||
type Formatter interface {
|
||||
// WriteProgress is called at EventStart for each Referral.
|
||||
WriteProgress(event traverse.TraversalEvent) error
|
||||
// WriteResolve is called at EventStart for nameserver resolution sub-steps.
|
||||
WriteResolve(event traverse.TraversalEvent) error
|
||||
// WriteResult is called at EventComplete for each TraversalResult.
|
||||
WriteResult(result traverse.TraversalResult) error
|
||||
// WriteSummary is called once after all results are collected.
|
||||
WriteSummary(results []traverse.TraversalResult) error
|
||||
// Flush finalises output (e.g. writes buffered JSON to the writer).
|
||||
Flush() error
|
||||
}
|
||||
|
||||
// NewFormatter returns the appropriate Formatter (text or JSON) based on cfg.Format.
|
||||
// A nil cfg uses DefaultConfig. A nil w uses os.Stdout.
|
||||
func NewFormatter(cfg *Config, w io.Writer) Formatter {
|
||||
if cfg == nil {
|
||||
cfg = DefaultConfig()
|
||||
@@ -71,6 +99,8 @@ func NewFormatter(cfg *Config, w io.Writer) Formatter {
|
||||
return newTextFormatter(cfg, w)
|
||||
}
|
||||
|
||||
// AttachHooks creates a TraverserHooks that routes traversal events to formatter
|
||||
// according to cfg visibility settings. Returns nil when cfg or formatter is nil.
|
||||
func AttachHooks(cfg *Config, formatter Formatter) *traverse.TraverserHooks {
|
||||
if cfg == nil || formatter == nil {
|
||||
return nil
|
||||
|
||||
@@ -9,6 +9,15 @@ import (
|
||||
"github.com/hits/ExploreDNS/internal/traverse"
|
||||
)
|
||||
|
||||
// RunTraversal is the high-level entry point that wires together a Traverser,
|
||||
// a Config, and a Formatter. It:
|
||||
//
|
||||
// 1. Attaches output hooks to traverser so events are formatted in real time.
|
||||
// 2. Calls traverser.Traverse(ctx, domain) to perform the traversal.
|
||||
// 3. Optionally fingerprints encountered servers (when ShowVersions && ShowServers).
|
||||
// 4. Writes the summary and flushes the formatter.
|
||||
//
|
||||
// Returns all TraversalResults and any error from the traversal or output.
|
||||
func RunTraversal(ctx context.Context, traverser *traverse.Traverser, cfg *Config, formatter Formatter, domain string) ([]traverse.TraversalResult, error) {
|
||||
if traverser == nil {
|
||||
return nil, fmt.Errorf("traverser is required")
|
||||
|
||||
@@ -21,11 +21,18 @@ type answerEntry struct {
|
||||
RRs []string
|
||||
}
|
||||
|
||||
// SummaryStats holds the aggregated probability statistics computed from a set
|
||||
// of traversal results.
|
||||
type SummaryStats struct {
|
||||
ByType map[string]float64
|
||||
// ByType maps ResponseType strings (e.g. "nxdomain", "servfail") to their
|
||||
// cumulative probability weight.
|
||||
ByType map[string]float64
|
||||
// Answers contains per-RDATA probability statistics for answer results.
|
||||
Answers []answerEntry
|
||||
}
|
||||
|
||||
// ComputeSummary aggregates terminal TraversalResults into a SummaryStats.
|
||||
// Returns nil when there are no terminal results to summarise.
|
||||
func ComputeSummary(results []traverse.TraversalResult) *SummaryStats {
|
||||
stats := &SummaryStats{
|
||||
ByType: make(map[string]float64),
|
||||
|
||||
Reference in New Issue
Block a user