Bloque de robustez operativa + integracion de sistema + calidad:
Publisher como servicio (lib/mdns_tools/service.py):
- `mdns publish --daemon`: daemon singleton con lock PID en
~/.cache/mdns/publisher.pid. Un segundo intento es rechazado -> evita el
problema de "Termux SMB" duplicado (varios publishers compitiendo por el
mismo nombre, que zeroconf renombra a "-2").
- Re-anuncio automatico al cambiar la IP local (WiFi<->datos, roaming):
unregister + register con la nueva IP para que el registro no quede stale.
- Apagado limpio: maneja SIGTERM ademas de SIGINT (loop en ticks de 1s) y
envia goodbye packets para que los clientes borren la entrada al instante.
- `mdns status` (running/host/ip/servicios/desde) y `mdns stop`.
Integracion de sistema (lib/mdns_tools/hosts.py):
- `mdns sync-hosts [--dry-run]`: escribe un bloque gestionado en
$PREFIX/etc/hosts (o /etc/hosts) para que ping/curl/kubectl nativos
resuelvan .local sin el wrapper `resolve`. Solo toca su propio bloque.
Refactor publish.py: expone helpers reutilizables (local_ipv4, load_config,
build_infos, register_all, unregister_all) que consume el daemon.
Tests offline (tests/, pytest, 20 casos, sin red):
- construccion/parseo de queries A, seleccion de IP ante multi-homing
(rechazo de rangos virtuales), cache con TTL y familias, PTR reverse,
render/strip del bloque de hosts.
- pyproject.toml con metadata, deps, extras [test] y config de pytest.
README: seccion de daemon, sync-hosts y tests; tabla RFC ampliada.
bashrc.snippet: aliases mdns-up/status/down/hosts (consolidados).
install.sh: fix de backticks; symlinks ya cubren mdns + lib via resolve().
Nota: publish.py (109) y service.py (110) exceden levemente las 100 lineas;
se dejan como modulos cohesivos de responsabilidad unica, igual que el
dispatcher CLI, para no fragmentar.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Cierra el gap hacia una implementacion mDNS/DNS-SD completa (RFC 6762/6763).
CLI nuevo `bin/mdns` con subcomandos:
- resolve : hostname -> IP (IPv4 stdlib rapido, IPv6 via zeroconf), cache TTL.
- reverse : IP -> hostname (PTR multicast, IPv4/IPv6).
- browse : descubrimiento DNS-SD (--list-types o --type _ssh._tcp.local.).
- publish : anuncia hostname + servicios (SSH/SMB/HTTP) con probing y goodbye.
- cache : list/clear del cache con TTL.
Biblioteca lib/mdns_tools/ (cada modulo < 100 lineas):
- resolve.py: stdlib-first para IPv4, zeroconf fallback para IPv6/miss.
- _stdlib_resolve.py: resolver A puro stdlib, acumula todas las A del host.
- _pick.py: elige la IP mas alcanzable ante multi-homing. Descarta rangos
virtuales (libvirt 192.168.122/24, docker 172.17/16, link-local) devolviendo
None para que el caller caiga a Tailscale en vez de a una IP muerta.
- browse.py / publish.py: DNS-SD sobre zeroconf.
- reverse.py: PTR stdlib. cache.py: TTL-aware JSON en ~/.cache/mdns.
Mejoras de calidad:
- IP_ADD_MEMBERSHIP en todos los sockets multicast.
- Retries con backoff (timeout dividido).
- Imports lazy en el CLI (resolve/cache no cargan zeroconf -> ~1s vs ~4s).
Wrappers:
- resolve (bash): orden mdns -> mdns-resolve stdlib -> Tailscale -> cache plano.
- mdns-publish.py: shim compat sobre `mdns publish`, lee ~/.config/mdns/services.json.
- install.sh: symlinks bin/ (updates via git pull), siembra services.json.
- ssh_config.example: HostKeyAlias documentado (alias comparte known_hosts con
el nombre canonico; evita fallos de verificacion tras reinstalar un host).
- bashrc.snippet: aliases mdns-types/ssh/smb/http, mdns-cache, whor.
Validado E2E en LAN: browse detecta 13 tipos; dell/movil resuelven a IP LAN
real; lenovo (solo publica virbr0 192.168.122.1) cae correctamente a Tailscale;
IPv6 de dell via zeroconf; reverse 192.168.1.17 -> dell-latitude3400.local;
publish visible desde otro browser. Modulos < 100 lineas salvo el dispatcher.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Scripts (bin/):
- mdns-resolve: resolver .local por multicast UDP (stdlib Python).
- mdns-publish.py: publicar este dispositivo como movil.local (zeroconf).
- ssh-mdns-proxy: ProxyCommand SSH con orden mDNS -> Tailscale -> cache.
- ssh-fallback: ProxyCommand con fallback Tailscale -> LAN.
- resolve: resolver genérico para cualquier comando (ping, curl, kubectl...).
Config (config/):
- bashrc.snippet: aliases r/pingr/curlr/sshr + auto-arranque publisher.
- ssh_config.example: entradas ProxyCommand para .local y hostnames cortos.
Docs y setup:
- README.md standalone con guía de uso, comportamiento por red y gotchas
(getent ausente en Bionic, shebang bash-only, mDNS no cruza redes,
zeroconf no sobrevive tar-backups, no silenciar logs).
- install.sh independiente con --dry-run.
Origen: extraído de andresgarcia0313/claude-code-termux para reutilizarse
sin acoplar a Claude Code.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>