2026-07-20 01:53:44 +00:00
|
|
|
#!/data/data/com.termux/files/usr/bin/bash
|
|
|
|
|
# install.sh - Install mdns-termux scripts to ~/.local/bin
|
|
|
|
|
# Usage: bash install.sh [--dry-run]
|
|
|
|
|
set -euo pipefail
|
|
|
|
|
|
|
|
|
|
DRY_RUN=0
|
|
|
|
|
[[ "${1:-}" == "--dry-run" ]] && DRY_RUN=1
|
|
|
|
|
|
|
|
|
|
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
|
|
|
|
BIN_DIR="$HOME/.local/bin"
|
|
|
|
|
|
|
|
|
|
run() {
|
|
|
|
|
if [[ $DRY_RUN -eq 1 ]]; then
|
|
|
|
|
echo "[dry-run] $*"
|
|
|
|
|
else
|
|
|
|
|
eval "$@"
|
|
|
|
|
fi
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
step() { echo ""; echo ">>> Step $1: $2"; }
|
|
|
|
|
|
|
|
|
|
# 1. Verify Termux
|
|
|
|
|
step 1 "Verifying Termux environment..."
|
|
|
|
|
if [[ -z "${PREFIX:-}" || "$PREFIX" != *"com.termux"* ]]; then
|
|
|
|
|
echo "ERROR: This installer targets Termux. \$PREFIX not set as expected." >&2
|
|
|
|
|
exit 1
|
|
|
|
|
fi
|
|
|
|
|
echo " Termux detected: $PREFIX"
|
|
|
|
|
|
|
|
|
|
# 2. Base packages
|
|
|
|
|
step 2 "Installing required packages (pkg + pip)..."
|
|
|
|
|
run "pkg install -y python proot"
|
|
|
|
|
run "pip install --upgrade zeroconf"
|
|
|
|
|
|
feat: CLI unificado mdns con browse/reverse/IPv6/cache-TTL
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>
2026-07-20 12:06:53 +00:00
|
|
|
# 3. Symlink CLI scripts (bin/) and library (lib/) — symlinks keep git-pull updates live
|
|
|
|
|
step 3 "Linking scripts into $BIN_DIR..."
|
2026-07-20 01:53:44 +00:00
|
|
|
run "mkdir -p '$BIN_DIR'"
|
feat: CLI unificado mdns con browse/reverse/IPv6/cache-TTL
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>
2026-07-20 12:06:53 +00:00
|
|
|
for script in mdns mdns-resolve mdns-publish.py ssh-mdns-proxy ssh-fallback resolve; do
|
|
|
|
|
run "ln -sf '$SCRIPT_DIR/bin/$script' '$BIN_DIR/$script'"
|
2026-07-20 01:53:44 +00:00
|
|
|
done
|
|
|
|
|
|
feat: CLI unificado mdns con browse/reverse/IPv6/cache-TTL
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>
2026-07-20 12:06:53 +00:00
|
|
|
# 4. Sample services config
|
|
|
|
|
step 4 "Sample services config for `mdns publish`..."
|
|
|
|
|
CFG_DIR="$HOME/.config/mdns"
|
|
|
|
|
run "mkdir -p '$CFG_DIR'"
|
|
|
|
|
if [[ ! -f "$CFG_DIR/services.json" ]]; then
|
|
|
|
|
run "cp '$SCRIPT_DIR/config/services.example.json' '$CFG_DIR/services.json'"
|
|
|
|
|
echo " Wrote $CFG_DIR/services.json (edit before running mdns publish)."
|
|
|
|
|
else
|
|
|
|
|
echo " $CFG_DIR/services.json already exists, keeping it."
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
# 5. Reminders
|
|
|
|
|
step 5 "Manual steps remaining:"
|
2026-07-20 01:53:44 +00:00
|
|
|
cat <<EOF
|
|
|
|
|
|
|
|
|
|
a) Append aliases to ~/.bashrc:
|
|
|
|
|
cat $SCRIPT_DIR/config/bashrc.snippet >> ~/.bashrc
|
|
|
|
|
Then edit TAILSCALE_DOMAIN inside your ~/.bashrc.
|
|
|
|
|
|
|
|
|
|
b) (Optional) Merge SSH config for .local + short-name resolution:
|
|
|
|
|
cat $SCRIPT_DIR/config/ssh_config.example >> ~/.ssh/config
|
|
|
|
|
Adjust User and hostnames.
|
|
|
|
|
|
feat: CLI unificado mdns con browse/reverse/IPv6/cache-TTL
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>
2026-07-20 12:06:53 +00:00
|
|
|
c) Try it:
|
|
|
|
|
mdns browse --list-types # discover service types on the LAN
|
|
|
|
|
mdns browse --type _ssh._tcp.local. # list SSH hosts
|
|
|
|
|
mdns resolve <host> # host -> IP (v4 by default)
|
|
|
|
|
mdns resolve <host> --family v6 # IPv6
|
|
|
|
|
mdns reverse <ip> # IP -> hostname
|
|
|
|
|
mdns publish # advertise this device + services
|
|
|
|
|
resolve <host> # bash wrapper (any command)
|
2026-07-20 01:53:44 +00:00
|
|
|
|
|
|
|
|
EOF
|
|
|
|
|
echo "Done."
|