fix: track multiple hostnames per IP:port in port state
All checks were successful
check / check (push) Successful in 46s

Port state keys are ip:port with a single hostname field. When multiple
hostnames resolve to the same IP (shared hosting, CDN), only one hostname
was associated. This caused orphaned port state when that hostname removed
the IP from DNS while the IP remained valid for other hostnames.

Changes:
- PortState.Hostname (string) → PortState.Hostnames ([]string)
- Custom UnmarshalJSON for backward compatibility with old state files
  that have single 'hostname' field (migrated to single-element slice)
- Refactored checkAllPorts to build IP:port→hostname associations first,
  then check each unique IP:port once with all associated hostnames
- Port state entries are cleaned up when no hostnames reference them
- Port change notifications now list all associated hostnames
- Added DeletePortState and GetAllPortKeys methods to state
- Updated README state file format documentation

Closes #55
This commit is contained in:
clawbot
2026-03-01 15:18:27 -08:00
parent ee14bd01ae
commit 2410776fba
3 changed files with 152 additions and 22 deletions

View File

@@ -110,8 +110,8 @@ includes:
- **NS recoveries**: Which nameserver recovered, which hostname/domain.
- **NS inconsistencies**: Which nameservers disagree, what each one
returned, which hostname affected.
- **Port changes**: Which IP:port, old state, new state, associated
hostname.
- **Port changes**: Which IP:port, old state, new state, all associated
hostnames.
- **TLS expiry warnings**: Which certificate, days remaining, CN,
issuer, associated hostname and IP.
- **TLS certificate changes**: Old and new CN/issuer/SANs, associated
@@ -290,12 +290,12 @@ not as a merged view, to enable inconsistency detection.
"ports": {
"93.184.216.34:80": {
"open": true,
"hostname": "www.example.com",
"hostnames": ["www.example.com"],
"lastChecked": "2026-02-19T12:00:00Z"
},
"93.184.216.34:443": {
"open": true,
"hostname": "www.example.com",
"hostnames": ["www.example.com"],
"lastChecked": "2026-02-19T12:00:00Z"
}
},