Skip to content

config: fix yaml tags for FrontingSNIs / SNIConfig#8

Merged
myleshorton merged 2 commits into
mainfrom
fisk/fix-frontingsnis-yaml-tags
May 26, 2026
Merged

config: fix yaml tags for FrontingSNIs / SNIConfig#8
myleshorton merged 2 commits into
mainfrom
fisk/fix-frontingsnis-yaml-tags

Conversation

@myleshorton
Copy link
Copy Markdown
Contributor

Summary

Config.Providers[*].FrontingSNIs has been silently empty for every consumer that parses fronted.yaml.gz with this library — a yaml-tag mismatch the linter doesn't catch.

The upstream generator (lantern-cloud/cmd/update_masquerades) writes the file using the older getlantern/fronted types, which carry no yaml struct tags. yaml.v3 falls back to lowercased-concatenated field names there, producing:

frontingsnis:
    ir:
        usearbitrarysnis: true
        arbitrarysnis:
            - python.org

This package's tags expected the snake_case form (fronting_snis, use_arbitrary_snis, arbitrary_snis), so yaml.Unmarshal silently leaves the fields zero-valued. The runtime fronting client's arbitrary-SNI cover code path has been dead for every client.

Fix

Aligns the tags with the wire format. Three tags change in config.go:

-FrontingSNIs map[string]*SNIConfig `yaml:"fronting_snis"`
+FrontingSNIs map[string]*SNIConfig `yaml:"frontingsnis"`

-UseArbitrarySNIs bool     `yaml:"use_arbitrary_snis"`
-ArbitrarySNIs    []string `yaml:"arbitrary_snis"`
+UseArbitrarySNIs bool     `yaml:"usearbitrarysnis"`
+ArbitrarySNIs    []string `yaml:"arbitrarysnis"`

No migration cost: the older format is the only one ever produced.

Verification

Parsing the live fronted.yaml.gz from getlantern/fronted/main with the fixed library:

provider=akamai FrontingSNIs groups: 3 Masquerades: 1000
  cn:      useArbitrary=false count=2570
  default: useArbitrary=true  count=4638
  ir:      useArbitrary=true  count=0
provider=cloudfront FrontingSNIs groups: 0 Masquerades: 1000

Before the fix all three groups parsed as empty (FrontingSNIs map was nil because the top-level key didn't match either).

Consumer impact

  • Runtime fronting client (domainfront.ExpandedProvider) now sees arbitrary-SNI cover groups — this is the user-visible behavior change.
  • radiance#488's scanner now reads these via SNIsForProvider's new FrontingSNIs union, so the new IR-validated SNIs (queued in lantern-cloud#2799) make it into the scanner pool.

🤖 Generated with Claude Code

The upstream generator (lantern-cloud/cmd/update_masquerades) uses
the older getlantern/fronted Go types which carry no yaml struct
tags, so yaml.Marshal writes lowercased Go field names with no
separator:

    frontingsnis:
        ir:
            usearbitrarysnis: true
            arbitrarysnis:
                - python.org

This domainfront package's tags expected snake_case
(`fronting_snis`, `use_arbitrary_snis`, `arbitrary_snis`), which
yaml.v3 silently fails to match, so every consumer of the parsed
Config saw FrontingSNIs as empty. The runtime fronting client's
arbitrary-SNI cover path was disabled across all clients.

Aligns the tags with the wire format. Adds no migration cost since
the older format was the only one ever produced.

Local verification against the live fronted.yaml.gz from
getlantern/fronted/main:

    akamai.frontingsnis.cn:      useArbitrary=false count=2570
    akamai.frontingsnis.default: useArbitrary=true  count=4638
    akamai.frontingsnis.ir:      useArbitrary=true  count=0
Copilot AI review requested due to automatic review settings May 26, 2026 18:18
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes a YAML tag mismatch so Config.Providers[*].FrontingSNIs (and nested SNIConfig fields) correctly unmarshals from the fronted.yaml.gz wire format, restoring the arbitrary-SNI cover configuration path for consumers.

Changes:

  • Update Provider.FrontingSNIs YAML tag to match the lowercase-concatenated key emitted upstream (frontingsnis).
  • Update SNIConfig YAML tags to match the upstream-emitted keys (usearbitrarysnis, arbitrarysnis).
  • Add an in-code comment documenting why these tags must match the wire format exactly.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread config.go
Comment thread config.go
Addresses PR review:

- README documented the snake_case form (fronting_snis /
  use_arbitrary_snis / arbitrary_snis) that never actually parsed —
  the upstream generator only ever emits the lowercase-concatenated
  form. Corrected the example to the real wire format so consumers
  don't copy keys that silently parse as zero values.

- TestParseConfigYAML now includes a frontingsnis section with
  usearbitrarysnis/arbitrarysnis and asserts the fields populate,
  guarding the tag spelling against silent regression.

No dual-key support added: there is no snake_case config in the wild
to be compatible with (the format never changed; the tags were just
wrong).
@myleshorton myleshorton merged commit fdc839b into main May 26, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants