| 文件 | 最后提交记录 | 最后更新时间 |
|---|---|---|
feat(wrt): identify unnamed devices by OS/vendor and retry silent mDNS lookups (#3623) * feat(wrt): label unnamed devices by MAC vendor instead of a placeholder Some clients never advertise a hostname through any source devices.list consults — ChromeOS deliberately sends no DHCP option 12 and answers no reverse-mDNS query, and many stripped-down IoT DHCP clients behave the same — so they surfaced as an opaque `device-3af2b1` placeholder. Add a vendor-label rung to the name resolution chain, just above the placeholder: look up the MAC's OUI in an embedded snapshot of the IEEE registries (MA-L/MA-M/MA-S, longest-prefix match) and render e.g. "Apple device (3af2b1)", keeping the stable MAC suffix so identical unnamed devices stay distinguishable. Labels are derived, not learned: recomputed each poll, never written to the name cache, so any real hostname that later appears — or a user-assigned name — outranks them. Randomized (locally-administered) MACs are skipped — they have no registry entry by construction; on Ethernet, where MACs are burned in, the lookup essentially always resolves. "IEEE Registration Authority" parent rows and "Private" registrations are excluded at generation time so an unassigned sub-block falls through to the placeholder rather than yielding a meaningless label. The snapshot (52,889 entries, ~490 KB gzipped) is generated by build/gen-oui-table.sh; the registry is append-mostly, so the asset only ever develops misses on brand-new vendors — refresh it opportunistically by re-running the script. Version bumped to 1.1.0 (feature tier). * feat(wrt): recognize unnamed devices' OS via DHCP fingerprinting Layer an OS-recognition rung above the OUI vendor label: the order of a client's DHCP option-55 parameter-request list and its option-60 vendor class are characteristic of the OS's DHCP stack, ride the request itself (so they survive MAC randomization, where OUI lookup is blind), and cannot be withheld the way a hostname can. An unnamed Windows laptop now shows "Windows device (3af2b1)" rather than falling to the NIC vendor or the placeholder. Capture: a hook script sourced by dnsmasq's dhcp-script wrapper appends "MAC|options|vendor class" lines on every DHCP add/old event. The wrapper sources the script inside the dnsmasq ujail, which dictates the design: no `exit` (it would abort the wrapper's ubus hotplug notify), shell builtins only (the jail mounts no coreutils), and the output lands in /var/run/dnsmasq/ — the jail's only writable directory (/tmp is silently unwritable there). The daemon parses the file defensively (it is the validation layer for client-controlled bytes) and compacts it when it outgrows 64 KiB. Wiring: the daemon provisions the hook at every boot — writes the script, points every `config dnsmasq` section's `dhcpscript` at it via a minimal partial TypedSection (preserving all other options), and reloads dnsmasq only on change — so OTA-updated routers converge without a reflash; profile creation sets `dhcpscript` on new instances directly. Persistence: fingerprints are cached per-MAC in device_names.json (hostname becomes optional there — a Chromebook has a fingerprint but no name; legacy files load unchanged), so OS labels survive reboots even though the capture file is tmpfs. Labels themselves stay derived: recomputed each poll from fingerprint-else-OUI, never cached as names. The rule table is seeded from widely-documented signatures (MSFT/ android-dhcp/dhcpcd/udhcp vendor classes; Apple and Windows option-55 sequences) and is deliberately conservative — a miss falls through to the OUI rung. Live bench validation, documented in device_ident.rs: capture /var/run/dnsmasq/dhcp.fingerprints for Windows, macOS, iOS, Android, Debian, and above all ChromeOS (the client this feature exists for), whose vendor-class behavior is undocumented and decides whether it earns a dedicated rule or lands on "Linux"/the OUI rung. * fix(wrt): retry silent mDNS name lookups on a backoff schedule Reverse-mDNS name recovery attempted each device exactly once per daemon run: a silent device went into MDNS_ATTEMPTED and was never queried again until restart — potentially months. That single attempt is a bad sampler: it usually fires the moment the device first appears (before its mDNS responder is up) or in the reassociation chaos right after a router reboot, and sleeping phones/laptops don't answer at all, so devices that do have Bonjour names got stuck on the generic label. Replace the attempted-set with a per-MAC attempt history and retry still-unnamed devices on a bounded backoff schedule: 6 attempts total, gated at 1 min -> 10 min -> 1 h -> 6 h -> 24 h after the previous try, then done until restart (the old behavior becomes the end state instead of the first). The shape follows RFC 6762 §5.2, mDNS's own doubling retry for unanswered queries; unlike a standing query we cap attempts, since many devices genuinely have no responder and each attempt spawns avahi-resolve. The early rungs catch responder-startup lag and boot chaos (avahi-daemon also caches answers that arrive after our 1.5 s timeout kills the CLI, so a quick retry often hits the cache); the late rungs catch sleepers. A permanently silent device now costs 6 spawns per daemon run instead of 1 — still nothing. Backoff runs on Instant, not wall time: routers boot with a wrong clock and NTP-jump minutes later, which would garble a wall-clock schedule. Retries ride the existing devices.list polls, so nothing fires while no client is viewing the device list, and success still persists to the name cache, which gates any further attempts. devices.forget now also drops the attempt history, so a forgotten device that reconnects starts a fresh schedule (matching the "appears as a new entry" docs contract). * feat(wrt): recognize NetworkManager's DHCP fingerprint as Linux Bench capture 2026-08-03 (Ubuntu, NetworkManager internal client): option-55 list 1,2,6,12,15,26,28,121,3,33,40,41,42,119,249,252,17 with no vendor class — the default DHCP client on Ubuntu/Fedora desktops. Exact-match rule in the table's conservative style; a drifted list in a future NM version just falls through to the OUI rung as before. * style(wrt): satisfy rustfmt in device_ident tests * chore(wrt): move additions clear of master's edits so the PR automerges Master now inserts its own boot step and changelog entries at the exact lines this branch inserts at, which is what made PR #3623 conflict. Slide the fingerprint-hook call below apply_remote_access (the boot reconcilers are order-independent best-effort steps), append the mDNS changelog entry mid-list instead of at the top of Fixed, and drop the heading rename that master has since made itself. Verified conflict-free against origin/master with git merge-tree. | 1 个月前 | |
| 2 天前 | ||
fix(start-wrt): require authentication for every state-changing RPC (#4124) Drop the server-side loopback trust from the RPC auth middleware; local callers authenticate with the local auth cookie, as startwrt-cli already does. Remove no_auth from system.apply-remote-access, system.set-timezone, published-ports.reconcile and published-ports.wan-changed: their hotplug callers carry the local cookie, and the setup wizard sets the timezone after set-initial-password has issued a session. startwrt-cli now sends the local auth cookie to loopback hosts only, and defaults to the loopback daemon when it can read the token, so on-router callers keep authenticating without naming a host. Fixes #3665 | 2 天前 | |
| 1 个月前 |