#!/bin/sh /etc/rc.common
# Il DNS dei televisori (spec 2026-09-15 porting, §14; blocco per nome §4.1):
# quattro istanze di dnsmasq, una per modalità, su 10.42.0.1:5301-5304, e il
# registro DNS unico (velmo-guardiano -registro-dns). La leggibile fa anche il
# DHCP del ponte. Il firewall devia la 53 di ogni televisore sulla porta della
# sua modalità.

START=60
STOP=40
USE_PROCD=1

. /etc/velmo/router.conf
CARTELLA=/tmp/velmo-dns
CONF=/var/run/velmo/dns
FILTRI=/etc/velmo/dns

scrivi_conf() { # istanza porta
	n=$1; p=$2
	{
		echo "# Scritto da /etc/init.d/velmo-dns a ogni avvio: istanza $n."
		echo "interface=$VELMO_PONTE"
		echo "bind-interfaces"
		echo "except-interface=lo"
		echo "listen-address=$VELMO_INDIRIZZO"
		echo "port=$p"
		echo "user=dnsmasq"
		echo "pid-file=$CARTELLA/$n.pid"
		echo "log-facility=$CARTELLA/$n.log"
		echo "log-queries=extra"
		echo "log-async=25"
		echo "no-hosts"
		echo "no-resolv"
		echo "domain-needed"
		echo "bogus-priv"
		echo "max-cache-ttl=3000"
		echo "local=/use-application-dns.net/"
		echo "local=/$VELMO_BACHECA_NOME/"
		echo "host-record=$VELMO_BACHECA_NOME,$VELMO_INDIRIZZO"
		# Il reverse privato e' dichiarato locale: bogus-priv resta attivo per
		# gli altri PTR, ma non scarta quello della bacheca.
		echo "local=/42.10.in-addr.arpa/"
		echo "ptr-record=1.0.42.10.in-addr.arpa,$VELMO_BACHECA_NOME."
		# In dnsmasq 2.80 address=/#/ dell'aggressiva vince su host-record: il nome
		# della bacheca si scrive anche come address=, più lungo di /#/.
		echo "address=/$VELMO_BACHECA_NOME/$VELMO_INDIRIZZO"
		echo "ipset=/#/velmo_risolti"
		echo "ipset=/$(echo $VELMO_DOH_NOMI | tr ' ' '/')/velmo_doh_nomi"
		case $n in
		bloccata)
			# Non esce niente, e il televisore lo sa subito. Zero invece del
			# silenzio: tacere lo farebbe aspettare il timeout a ogni domanda,
			# e un apparecchio lentissimo sembra rotto invece che fermato.
			# Nessuna whitelist da leggere: qui non c'è niente da ammettere,
			# tranne il nome della bacheca, che è scritto sopra per tutte le
			# istanze ed è l'unica cosa che chi guarda il televisore può
			# ancora aprire.
			echo "address=/#/0.0.0.0"
			echo "address=/#/::"
			echo "local=/#/"
			;;
		aggressiva)
			# Passa solo la whitelist: server=/nome/ e ipset= per i nomi in
			# velmo-ammessi.conf (velmo-applica-ammessi), più lunghi di /#/.
			echo "address=/#/0.0.0.0"
			echo "address=/#/::"
			echo "local=/#/"
			echo "conf-dir=$FILTRI/aggressiva.d,*.conf"
			;;
		*)
			for r in $VELMO_RESOLVER; do echo "server=$r"; done
			# Leggibile e protetta leggono lo stesso filtro (velmo-applica-blocco).
			echo "conf-dir=$FILTRI/protetta.d,*.conf"
			;;
		esac
		if [ $n = leggibile ]; then
			# La fine del pool discende dal tetto: tanti indirizzi quanti
			# apparecchi si accettano, a partire dal primo. Cosi' il numero sta
			# scritto in un posto solo, e cambiarlo cambia davvero chi entra.
			# Il tetto scelto da chi ci abita vince su quello di fabbrica:
			# router.conf dice come esce dalla scatola, il file dice cosa ha
			# deciso chi la usa.
			dns_tetto=$VELMO_APPARECCHI_MAX
			[ -r /etc/velmo/apparecchi-max ] &&
				dns_tetto=$(tr -cd '0-9' < /etc/velmo/apparecchi-max)
			dns_tetto=${dns_tetto:-8}
			# «3 significa 3 in tutto» (committente, 20 settembre 2026). Un
			# televisore dichiarato ha un indirizzo riservato, che sta fuori dal
			# pool: se il pool fosse comunque grande quanto il tetto, un tetto di
			# 3 con due televisori lascerebbe entrare cinque apparecchi. Le
			# riserve contano, e il pool è quello che avanza.
			dns_riservati=$(grep -c '^dhcp-host=' "$FILTRI/televisori.conf" 2>/dev/null)
			[ -n "$dns_riservati" ] || dns_riservati=0
			dns_liberi=$((dns_tetto - dns_riservati))
			if [ "$dns_liberi" -le 0 ]; then
				# Il tetto è pieno di soli dichiarati: la rete resta dichiarata a
				# dnsmasq - serve a dare gli indirizzi alle riserve - e nessun
				# altro ne riceve uno.
				echo "dhcp-range=$VELMO_DHCP_DA,static,$VELMO_DHCP_DURATA"
			else
				dns_ultimo=$(echo "$VELMO_DHCP_DA" | awk -F. -v n="$dns_liberi" \
					'{printf "%s.%s.%s.%d", $1, $2, $3, $4 + n - 1}')
				echo "dhcp-range=$VELMO_DHCP_DA,$dns_ultimo,$VELMO_DHCP_DURATA"
			fi
			echo "dhcp-option=option:dns-server,0.0.0.0"
			echo "dhcp-authoritative"
			echo "dhcp-leasefile=$CARTELLA/contratti"
			echo "conf-file=$FILTRI/televisori.conf"
			# Un indirizzo che passa a un altro apparecchio perde la sua modalità.
			echo "dhcp-script=/usr/lib/velmo/dhcp-evento.sh"
			echo "dhcp-scriptuser=root"
			# script-on-renewal non esiste in dnsmasq 2.80 (rifiuta tutta la
			# configurazione): il dhcp-script viene chiamato all'assegnazione e ai
			# cambi di contratto, non a ogni rinnovo.
		fi
	} > "$CONF/$n.conf"
}

istanza_dnsmasq() { # istanza porta
	scrivi_conf "$1" "$2"
	procd_open_instance "$1"
	procd_set_param command /usr/sbin/dnsmasq -k -C "$CONF/$1.conf"
	procd_set_param respawn 3600 5 0
	procd_set_param stderr 1
	procd_close_instance
}

start_service() {
	mkdir -p "$CARTELLA" "$CONF" "$FILTRI/protetta.d" "$FILTRI/aggressiva.d"
	chown dnsmasq:dnsmasq "$CARTELLA" 2>/dev/null
	[ -e "$FILTRI/televisori.conf" ] || : > "$FILTRI/televisori.conf"
	[ -e /etc/velmo/ammessi ] || : > /etc/velmo/ammessi
	istanza_dnsmasq leggibile "$VELMO_DNS_LEGGIBILE"
	istanza_dnsmasq protetta "$VELMO_DNS_PROTETTA"
	istanza_dnsmasq aggressiva "$VELMO_DNS_AGGRESSIVA"
	istanza_dnsmasq bloccata "$VELMO_DNS_BLOCCATA"
	. /var/run/velmo/dati 2>/dev/null
	procd_open_instance registro
	procd_set_param command /usr/sbin/velmo-guardiano -registro-dns \
		-dns-cartella "$CARTELLA" -dns-registro "$VELMO_DATI/dns.log" \
		-dns-blocco "$FILTRI/protetta.d/velmo-blocco.conf" -dns-lista /etc/velmo/ammessi
	# Dialix (spec 2026-09-30-dialix §13): le risposte DNS dei televisori sul
	# socket che velmod apre solo durante una partita, come fa il guardiano con
	# le connessioni. Il registro gira da root: la cartella velmo:velmo 0750 non
	# lo ferma. Senza ascoltatore non serializza niente. Il nome della bacheca
	# non va mai su Dialix: un tocco non deve poter bloccare la console.
	procd_append_param command -dialix /var/run/velmo/dialix/dialix.sock
	procd_append_param command -dns-locali "$VELMO_BACHECA_NOME"
	[ -n "$VELMO_FUSO" ] || VELMO_FUSO=$(uci -q get system.@system[0].zonename)
	procd_set_param env GOMAXPROCS=1 GOMEMLIMIT=4MiB ${VELMO_FUSO:+TZ=$VELMO_FUSO}
	procd_set_param respawn 3600 5 0
	procd_set_param stderr 1
	procd_close_instance
}
