#!/bin/sh /etc/rc.common

START=95
STOP=10
USE_PROCD=1

TURN_CONF=/var/run/turnserver.conf

generate_config() {
	local enabled realm listening_port tls_port min_port max_port
	local external_ip use_auth_secret static_auth_secret verbose
	local cert_path key_path
	local total_quota bps_capacity user_quota max_bps
	local log_file syslog

	config_load turn

	config_get enabled main enabled '0'
	[ "$enabled" != "1" ] && return 1

	config_get realm main realm 'turn.secubox.in'
	config_get listening_port main listening_port '3478'
	config_get tls_port main tls_port '5349'
	config_get min_port main min_port '49152'
	config_get max_port main max_port '65535'
	config_get external_ip main external_ip ''
	config_get use_auth_secret main use_auth_secret '1'
	config_get static_auth_secret main static_auth_secret ''
	config_get verbose main verbose '0'

	config_get cert_path ssl cert_path '/etc/ssl/turn/cert.pem'
	config_get key_path ssl key_path '/etc/ssl/turn/key.pem'

	config_get total_quota limits total_quota '100'
	config_get bps_capacity limits bps_capacity '0'
	config_get user_quota limits user_quota '0'
	config_get max_bps limits max_bps '0'

	config_get log_file log log_file '/var/log/turnserver.log'
	config_get syslog log syslog '1'

	# Auto-detect external IP if not set
	if [ -z "$external_ip" ]; then
		external_ip=$(curl -s -4 https://ifconfig.me 2>/dev/null || curl -s -4 https://api.ipify.org 2>/dev/null)
	fi

	# Generate secret if not set
	if [ -z "$static_auth_secret" ]; then
		static_auth_secret=$(head -c 32 /dev/urandom | base64 | tr -d '/+=' | head -c 32)
		uci set turn.main.static_auth_secret="$static_auth_secret"
		uci commit turn
		logger -t turn "Generated new static auth secret"
	fi

	cat > "$TURN_CONF" <<EOF
# SecuBox TURN Server Configuration
# Generated by /etc/init.d/turn

listening-port=$listening_port
tls-listening-port=$tls_port
realm=$realm
fingerprint
lt-cred-mech
EOF

	# Auth secret
	if [ "$use_auth_secret" = "1" ]; then
		echo "use-auth-secret" >> "$TURN_CONF"
		echo "static-auth-secret=$static_auth_secret" >> "$TURN_CONF"
	fi

	# External IP
	[ -n "$external_ip" ] && echo "external-ip=$external_ip" >> "$TURN_CONF"

	# Port range
	echo "min-port=$min_port" >> "$TURN_CONF"
	echo "max-port=$max_port" >> "$TURN_CONF"

	# TLS certificates
	if [ -f "$cert_path" ] && [ -f "$key_path" ]; then
		echo "cert=$cert_path" >> "$TURN_CONF"
		echo "pkey=$key_path" >> "$TURN_CONF"
	fi

	# Limits
	[ "$total_quota" != "0" ] && echo "total-quota=$total_quota" >> "$TURN_CONF"
	[ "$bps_capacity" != "0" ] && echo "bps-capacity=$bps_capacity" >> "$TURN_CONF"
	[ "$user_quota" != "0" ] && echo "user-quota=$user_quota" >> "$TURN_CONF"
	[ "$max_bps" != "0" ] && echo "max-bps=$max_bps" >> "$TURN_CONF"

	# Logging
	[ "$syslog" = "1" ] && echo "syslog" >> "$TURN_CONF"
	[ -n "$log_file" ] && echo "log-file=$log_file" >> "$TURN_CONF"
	[ "$verbose" = "1" ] && echo "verbose" >> "$TURN_CONF"

	# Additional hardening
	cat >> "$TURN_CONF" <<EOF
no-multicast-peers
no-cli
denied-peer-ip=0.0.0.0-0.255.255.255
denied-peer-ip=10.0.0.0-10.255.255.255
denied-peer-ip=100.64.0.0-100.127.255.255
denied-peer-ip=127.0.0.0-127.255.255.255
denied-peer-ip=169.254.0.0-169.254.255.255
denied-peer-ip=172.16.0.0-172.31.255.255
denied-peer-ip=192.0.0.0-192.0.0.255
denied-peer-ip=192.0.2.0-192.0.2.255
denied-peer-ip=192.88.99.0-192.88.99.255
denied-peer-ip=192.168.0.0-192.168.255.255
denied-peer-ip=198.18.0.0-198.19.255.255
denied-peer-ip=198.51.100.0-198.51.100.255
denied-peer-ip=203.0.113.0-203.0.113.255
denied-peer-ip=240.0.0.0-255.255.255.255
EOF

	return 0
}

start_service() {
	generate_config || {
		logger -t turn "TURN server disabled or config error"
		return 0
	}

	procd_open_instance
	procd_set_param command /usr/bin/turnserver -c "$TURN_CONF"
	procd_set_param respawn
	procd_set_param stderr 1
	procd_set_param stdout 1
	procd_set_param pidfile /var/run/turnserver.pid
	procd_close_instance

	logger -t turn "TURN server started"
}

stop_service() {
	logger -t turn "TURN server stopped"
}

reload_service() {
	stop
	start
}

service_triggers() {
	procd_add_reload_trigger "turn"
}
