# v2.2 task 02: several broadcast addresses per wake target **Branch:** `v2.2` (`git switch v2.2`; `git status --short` must be empty, otherwise stop) **Commit subject:** `Wake: a target may list several broadcast addresses` ## Goal Titan roams between two Wi-Fi networks; hyperborea sits on both segments. A wake target can therefore name **several** broadcast addresses and the magic packet goes to all of them. Config keeps `broadcast = "host:port"` (one) and adds `broadcasts = ["host:port", …]` (a list); exactly one of the two must be present. ## Files - Copy: `internal/wake/broadcasts_test.go` (`internal/config/config_v22_test.go` was copied in task 01 and its `TestWakeBroadcasts` becomes green here) - Modify: `internal/config/config.go`, `internal/wake/wake.go`, `cmd/crossbar/main.go`, `example.toml` (show the list form, commented), `docs/implementer-log.md` ## Interfaces ```go package config type Wake struct { MAC string `toml:"mac"` Broadcast string `toml:"broadcast"` Broadcasts []string `toml:"broadcasts"` Wait Duration `toml:"wait"` } // Addresses is Broadcast (when set) followed by Broadcasts: the list to send to, never empty // for a parsed config. func (w *Wake) Addresses() []string package wake type Target struct { MAC string Broadcast string // one address, as before Broadcasts []string // more addresses; Send goes to Broadcast (if set) and then each of these Wait time.Duration } ``` Rules: 1. Validation (`hosts..wake…` fields): `broadcast` and `broadcasts` both set → error on `hosts..wake.broadcasts`; neither, or an empty list → error on `hosts..wake.broadcast`; every entry must be `host:port` (same check as `broadcast` today) → error on `hosts..wake.broadcasts`. 2. `Waker.Wake` sends one packet to every address in order. An address that fails to resolve or send is logged (or ignored) and does **not** stop the remaining addresses; `Wake` returns false only if *no* address could be sent to (or on the existing timeout/ctx rules). 3. `main.go` fills `Target.Broadcasts` from `Wake.Addresses()`. ## Steps - [ ] **1.** `git switch v2.2`; copy `broadcasts_test.go`. - [ ] **2. See it fail** (compile). **3.** `config.go`, then `wake.go`, then `main.go`, `example.toml`. - [ ] **4.** `go test -race -count=3 ./internal/wake/ ./internal/config/` → `ok`. **5.** `go test -race -count=1 ./...`; `make smoke`. - [ ] **6.** `make gate`. **7.** Row `v2.2/02-broadcasts`; commit. ```sh git add internal/config internal/wake cmd/crossbar example.toml docs/implementer-log.md git commit ``` ## Done when - All given tests pass; the v2 `wake_test.go` and `config_v2_test.go` are untouched and green; gate and smoke ok; given files byte-identical.