model

package
v0.1.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 12, 2026 License: MIT Imports: 1 Imported by: 0

Documentation

Overview

Package model defines the measurement and report data structures shared by probes, the classifier, renderers and the submission format.

Everything here is serialised to JSON; field names are part of the public report format (schema prosvet.report/v1) and must stay backwards compatible.

Index

Constants

View Source
const (
	VariantReal   = "real"
	VariantNone   = "none"
	VariantRandom = "random"
	VariantECH    = "ech"
)

TLS probe variants.

View Source
const (
	WhitelistActive         = "active"
	WhitelistNormal         = "normal"
	WhitelistNoConnectivity = "no_connectivity"
	WhitelistDegraded       = "degraded"
)

Whitelist verdicts.

View Source
const ReportSchema = "prosvet.report/v1"

ReportSchema identifies the JSON report format.

Variables

AllKinds lists every verdict kind in display priority order.

Functions

This section is empty.

Types

type Baseline

type Baseline struct {
	Kbps   float64 `json:"kbps"`
	Source string  `json:"source"`
}

Baseline is the domestic throughput reference used for throttling detection.

type CertInfo

type CertInfo struct {
	Subject          string    `json:"subject,omitempty"`
	Issuer           string    `json:"issuer,omitempty"`
	ValidForHost     bool      `json:"valid_for_host"`
	TrustedSystem    bool      `json:"trusted_system"`
	RussianTrustedCA bool      `json:"russian_trusted_ca,omitempty"`
	NotAfter         time.Time `json:"not_after,omitempty"`
}

CertInfo summarises the certificate presented during a TLS handshake.

type Confidence

type Confidence string

Confidence of a verdict.

const (
	High   Confidence = "high"
	Medium Confidence = "medium"
	Low    Confidence = "low"
)

Confidence levels.

func (Confidence) Lower

func (c Confidence) Lower() Confidence

Lower returns the next lower confidence level.

func (Confidence) Rank

func (c Confidence) Rank() int

Rank orders confidence levels (higher is more confident).

type DNSAnswer

type DNSAnswer struct {
	Resolver string   `json:"resolver"`
	Outcome  Outcome  `json:"outcome"`
	Addrs    []string `json:"addrs,omitempty"`
	Stub     string   `json:"stub,omitempty"` // fingerprint id when the answer is a known block stub
	Bogon    bool     `json:"bogon,omitempty"`
	RTTMs    int64    `json:"rtt_ms,omitempty"`
	Error    string   `json:"error,omitempty"`
	Agree    int      `json:"agree,omitempty"`
	Runs     int      `json:"runs,omitempty"`
}

DNSAnswer is the result of resolving a name through one resolver.

type DNSFinding

type DNSFinding struct {
	Kind       string     `json:"kind"` // dns_interception | doh_blocked | dot_blocked | udp_blocked | nsdi_divergence
	Resolvers  []string   `json:"resolvers,omitempty"`
	Domains    []string   `json:"domains,omitempty"`
	Confidence Confidence `json:"confidence"`
}

DNSFinding is a conclusion drawn from the DNS checks.

type DNSReport

type DNSReport struct {
	Resolvers    []ResolverStatus    `json:"resolvers"`
	Domains      []DomainCheck       `json:"domains"`
	Interception []InterceptionCheck `json:"interception"`
	Findings     []DNSFinding        `json:"findings,omitempty"`
}

DNSReport is the output of the resolver matrix and interception checks.

type DNSResult

type DNSResult struct {
	System    DNSAnswer  `json:"system"`
	NSDI      *DNSAnswer `json:"nsdi,omitempty"`
	Reference *DNSAnswer `json:"reference,omitempty"`
}

DNSResult groups the answers gathered for one endpoint.

type DomainCheck

type DomainCheck struct {
	Name    string      `json:"name"`
	Role    string      `json:"role,omitempty"`
	Answers []DNSAnswer `json:"answers"`
}

DomainCheck compares answers for one probe domain across resolvers.

type EndpointResult

type EndpointResult struct {
	Name      string        `json:"name"`
	Port      int           `json:"port"`
	IP        string        `json:"ip,omitempty"` // server address that was tested
	IPSource  string        `json:"ip_source,omitempty"`
	Note      string        `json:"note,omitempty"`
	DNS       *DNSResult    `json:"dns,omitempty"`
	TCP       *TLSResult    `json:"tcp,omitempty"` // connect-only endpoints
	TLS       []*TLSResult  `json:"tls,omitempty"`
	RefTLS    *TLSResult    `json:"ref_tls,omitempty"` // real-SNI handshake to the address from the reference resolver
	HTTP      *HTTPResult   `json:"http,omitempty"`
	HTTP80    *HTTPResult   `json:"http80,omitempty"`
	QUIC      []*QUICResult `json:"quic,omitempty"`
	ECH       *TLSResult    `json:"ech,omitempty"`
	Verdict   Verdict       `json:"verdict"`
	Secondary []Kind        `json:"secondary,omitempty"`
	// ProtocolFocus marks endpoints whose purpose is a protocol probe (QUIC,
	// ECH); their TCP/TLS handshake only serves as a control.
	ProtocolFocus bool `json:"protocol_focus,omitempty"`
}

EndpointResult aggregates all probes of one endpoint (after majority voting).

func (*EndpointResult) TLSVariant

func (e *EndpointResult) TLSVariant(v string) *TLSResult

TLSVariant returns the aggregated TLS result for a variant, or nil.

type Evidence

type Evidence struct {
	Key  string            `json:"key"`
	Args map[string]string `json:"args,omitempty"`
}

Evidence is one localisable line explaining a verdict.

type HTTPResult

type HTTPResult struct {
	Outcome          Outcome `json:"outcome"`
	Status           int     `json:"status,omitempty"`
	Bytes            int64   `json:"bytes"`                // body bytes
	RawBytes         int64   `json:"raw_bytes"`            // application bytes incl. headers
	WireBytes        int64   `json:"wire_bytes,omitempty"` // TCP payload bytes incl. TLS handshake
	ContentLength    int64   `json:"content_length"`
	Complete         bool    `json:"complete"`
	Truncated        bool    `json:"truncated,omitempty"`
	Stalled          bool    `json:"stalled,omitempty"`
	BytesBeforeStall int64   `json:"bytes_before_stall,omitempty"` // wire bytes when the transfer froze
	TTFBMs           int64   `json:"ttfb_ms,omitempty"`
	DurationMs       int64   `json:"duration_ms,omitempty"`
	ThroughputKbps   float64 `json:"throughput_kbps,omitempty"`
	Location         string  `json:"location,omitempty"`
	Blockpage        string  `json:"blockpage,omitempty"`
	Error            string  `json:"error,omitempty"`
	Agree            int     `json:"agree,omitempty"`
	Runs             int     `json:"runs,omitempty"`
	StallRuns        int     `json:"stall_runs,omitempty"`
}

HTTPResult is a single HTTP exchange.

type InterceptionCheck

type InterceptionCheck struct {
	ID       string  `json:"id"`
	Resolver string  `json:"resolver"`
	QName    string  `json:"qname"`
	Expect   string  `json:"expect"`
	Outcome  Outcome `json:"outcome"`
	Passed   bool    `json:"passed"`
	Detail   string  `json:"detail,omitempty"` // never contains the user's IP
}

InterceptionCheck is one transparent-DNS-proxy probe.

type Kind

type Kind string

Kind is the type of interference identified by the classifier.

const (
	KindOK             Kind = "ok"
	KindNoConnectivity Kind = "no_connectivity"
	KindTLSMITM        Kind = "tls_mitm"
	KindBlockpage      Kind = "blockpage"
	KindDNS            Kind = "dns"
	KindSNIDPI         Kind = "sni_dpi"
	KindIPBlock        Kind = "ip_block"
	KindTLSReset       Kind = "tls_reset"
	KindThrottleFreeze Kind = "throttle_freeze"
	KindThrottleRate   Kind = "throttle_rate"
	KindQUICSNI        Kind = "quic_sni"
	KindQUICBlocked    Kind = "quic_blocked"
	KindECHBlocked     Kind = "ech_blocked"
	KindTimeout        Kind = "timeout"
	KindUnknown        Kind = "unknown"
)

Verdict kinds. The order of the list is the display priority.

func (Kind) IsBlocking

func (k Kind) IsBlocking() bool

IsBlocking reports whether the kind means the resource is not usable.

func (Kind) IsProtocol

func (k Kind) IsProtocol() bool

IsProtocol reports whether the kind only concerns an alternative protocol (QUIC, ECH).

func (Kind) IsThrottling

func (k Kind) IsThrottling() bool

IsThrottling reports whether the kind is a slowdown rather than a block.

type NetworkInfo

type NetworkInfo struct {
	ASN          int    `json:"asn,omitempty"`
	ISP          string `json:"isp,omitempty"`
	Country      string `json:"country,omitempty"`
	Region       string `json:"region,omitempty"` // ISO 3166-2 code, e.g. RU-MOW
	RegionName   string `json:"region_name,omitempty"`
	Conn         string `json:"conn"` // mobile | fixed | unknown
	ConnSource   string `json:"conn_source,omitempty"`
	VPNSuspected bool   `json:"vpn_suspected,omitempty"`
	VPNReason    string `json:"vpn_reason,omitempty"`
	ProxyIgnored bool   `json:"proxy_ignored,omitempty"`
	Source       string `json:"source,omitempty"` // auto | manual | none
	Error        string `json:"error,omitempty"`
}

NetworkInfo describes the user's network. It never contains the user's IP address.

type Outcome

type Outcome string

Outcome is the result code of a single probe step.

const (
	OK          Outcome = "ok"
	Timeout     Outcome = "timeout"
	Reset       Outcome = "reset"
	Refused     Outcome = "refused"
	EOF         Outcome = "eof"
	Unreachable Outcome = "unreachable"
	NXDomain    Outcome = "nxdomain"
	ServFail    Outcome = "servfail"
	NoAnswer    Outcome = "no_answer"
	TLSAlert    Outcome = "tls_alert"
	Stall       Outcome = "stall"
	Responded   Outcome = "responded" // QUIC: the server answered but the handshake did not complete
	Unsupported Outcome = "unsupported"
	Error       Outcome = "error"
	Skipped     Outcome = "skipped"
)

Probe outcomes.

func (Outcome) Interfered

func (o Outcome) Interfered() bool

Interfered reports whether an outcome is a typical sign of on-path interference (as opposed to a normal server response).

func (Outcome) ServerAnswered

func (o Outcome) ServerAnswered() bool

ServerAnswered reports whether the remote server demonstrably answered.

type QUICResult

type QUICResult struct {
	Version int     `json:"version"`
	Variant string  `json:"variant"`
	Outcome Outcome `json:"outcome"`
	RTTMs   int64   `json:"rtt_ms,omitempty"`
	Error   string  `json:"error,omitempty"`
	Agree   int     `json:"agree,omitempty"`
	Runs    int     `json:"runs,omitempty"`
}

QUICResult is a QUIC handshake attempt.

type Report

type Report struct {
	Schema       string           `json:"schema"`
	Tool         ToolInfo         `json:"tool"`
	StartedAt    time.Time        `json:"started_at"`
	FinishedAt   time.Time        `json:"finished_at"`
	Options      ScanOptions      `json:"options"`
	Network      NetworkInfo      `json:"network"`
	Connectivity *Verdict         `json:"connectivity,omitempty"`
	Baseline     *Baseline        `json:"baseline,omitempty"`
	Targets      []TargetResult   `json:"targets"`
	DNS          *DNSReport       `json:"dns,omitempty"`
	Whitelist    *WhitelistResult `json:"whitelist,omitempty"`
	Summary      Summary          `json:"summary"`
}

Report is the complete result of a scan.

func (*Report) Recount

func (r *Report) Recount()

Recount recomputes the summary from target statuses. Baseline and control targets are excluded from the counts.

type ResolverStatus

type ResolverStatus struct {
	ID        string  `json:"id"`
	Name      string  `json:"name"`
	Transport string  `json:"transport"` // system | udp | dot | doh
	Endpoint  string  `json:"endpoint"`
	Outcome   Outcome `json:"outcome"`
	RTTMs     int64   `json:"rtt_ms,omitempty"`
	Error     string  `json:"error,omitempty"`
}

ResolverStatus is the reachability of one resolver transport.

type ScanOptions

type ScanOptions struct {
	Repeats    int      `json:"repeats"`
	Categories []string `json:"categories,omitempty"`
	Targets    []string `json:"targets,omitempty"`
	QUIC       bool     `json:"quic"`
	Demo       bool     `json:"demo,omitempty"`
}

ScanOptions records how a scan was run.

type Status

type Status string

Status is the user-facing state of a target.

const (
	StatusOK          Status = "ok"
	StatusThrottled   Status = "throttled"
	StatusPartial     Status = "partial"
	StatusBlocked     Status = "blocked"
	StatusUnreachable Status = "unreachable" // the whole network is down, nothing can be said
	StatusUnknown     Status = "unknown"
)

Target statuses.

type Summary

type Summary struct {
	Total       int `json:"total"`
	OK          int `json:"ok"`
	Throttled   int `json:"throttled"`
	Partial     int `json:"partial"`
	Blocked     int `json:"blocked"`
	Unreachable int `json:"unreachable"`
	Unknown     int `json:"unknown"`
}

Summary counts targets by status.

type TLSResult

type TLSResult struct {
	Variant     string    `json:"variant"`
	Stage       string    `json:"stage"` // "connect" or "handshake"
	Outcome     Outcome   `json:"outcome"`
	ConnectMs   int64     `json:"connect_ms,omitempty"`
	HandshakeMs int64     `json:"handshake_ms,omitempty"`
	Version     string    `json:"version,omitempty"`
	ECHAccepted bool      `json:"ech_accepted,omitempty"`
	Cert        *CertInfo `json:"cert,omitempty"`
	Error       string    `json:"error,omitempty"`
	Agree       int       `json:"agree,omitempty"`
	Runs        int       `json:"runs,omitempty"`
}

TLSResult is a single TLS attempt (TCP connect + handshake).

func (*TLSResult) Key

func (r *TLSResult) Key() string

Key is the value used for majority voting.

func (*TLSResult) Succeeded

func (r *TLSResult) Succeeded() bool

Succeeded reports whether the handshake completed.

type TargetResult

type TargetResult struct {
	ID          string           `json:"id"`
	Name        string           `json:"name"`
	Category    string           `json:"category"`
	Role        string           `json:"role,omitempty"`
	Expect      string           `json:"expect,omitempty"`
	Since       string           `json:"since,omitempty"`
	Status      Status           `json:"status"`
	Verdict     Verdict          `json:"verdict"`
	Secondary   []Kind           `json:"secondary,omitempty"`
	Endpoints   []EndpointResult `json:"endpoints"`
	ThrottleURL string           `json:"throttle_url,omitempty"`
	Throttle    *HTTPResult      `json:"throttle,omitempty"`
	DurationMs  int64            `json:"duration_ms"`
}

TargetResult is the outcome for one target (service).

type ToolInfo

type ToolInfo struct {
	Name    string `json:"name"`
	Version string `json:"version"`
	Commit  string `json:"commit,omitempty"`
	OS      string `json:"os"`
	Arch    string `json:"arch"`
}

ToolInfo identifies the producing tool.

type Verdict

type Verdict struct {
	Kind       Kind       `json:"kind"`
	Subtype    string     `json:"subtype,omitempty"`
	Confidence Confidence `json:"confidence"`
	Evidence   []Evidence `json:"evidence,omitempty"`
}

Verdict is the classifier output for an endpoint or a target.

type WhitelistCheck

type WhitelistCheck struct {
	Host    string  `json:"host"`
	Org     string  `json:"org,omitempty"`
	Stage   string  `json:"stage"` // dns | connect | handshake | ok
	Outcome Outcome `json:"outcome"`
	CA      string  `json:"ca,omitempty"`
}

WhitelistCheck is one host checked in whitelist mode.

type WhitelistResult

type WhitelistResult struct {
	Verdict       string           `json:"verdict"`
	Confidence    Confidence       `json:"confidence"`
	DomesticOK    int              `json:"domestic_ok"`
	DomesticTotal int              `json:"domestic_total"`
	ForeignOK     int              `json:"foreign_ok"`
	ForeignTotal  int              `json:"foreign_total"`
	FailureLevel  string           `json:"failure_level,omitempty"` // dns | connect | handshake | mixed
	Domestic      []WhitelistCheck `json:"domestic"`
	Foreign       []WhitelistCheck `json:"foreign"`
}

WhitelistResult is the outcome of `prosvet whitelist`.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL