## New Features - secubox-app-yggdrasil-discovery: Mesh peer discovery via gossip protocol - yggctl CLI: status, self, peers, announce, discover, bootstrap - Auto-peering with trust verification (master-link fingerprint) - Daemon for periodic announcements ## Bug Fixes - tor-shield: Fix opkg downloads failing when Tor active - DNS over Tor disabled by default - Auto-exclude public DNS servers from iptables rules - Excluded domains bypass list (openwrt.org, pool.ntp.org, etc.) - haproxy: Fix portal 503 "End of Internet" error - Corrected malformed vhost backend configuration - Regenerated HAProxy config from UCI - luci-app-nextcloud: Fix users list showing empty - RPC expect clause was extracting array, render expected object ## Updated - Bonus feed: All IPKs rebuilt - Documentation: HISTORY.md, WIP.md, TODO.md updated Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
125 lines
3.6 KiB
Bash
125 lines
3.6 KiB
Bash
#!/bin/sh
|
|
# Yggdrasil Discovery Gossip Handler
|
|
# Handles yggdrasil_peer messages from mirrornet gossip protocol
|
|
|
|
. /usr/lib/yggdrasil-discovery/core.sh
|
|
|
|
# Handle incoming yggdrasil_peer announcement
|
|
handle_peer_announce() {
|
|
local data="$1"
|
|
local origin="$2"
|
|
|
|
# Parse announcement data
|
|
local ipv6 pubkey hostname ml_fingerprint zkp_fingerprint timestamp
|
|
|
|
ipv6=$(echo "$data" | jsonfilter -e '@.ipv6' 2>/dev/null)
|
|
pubkey=$(echo "$data" | jsonfilter -e '@.pubkey' 2>/dev/null)
|
|
hostname=$(echo "$data" | jsonfilter -e '@.hostname' 2>/dev/null)
|
|
ml_fingerprint=$(echo "$data" | jsonfilter -e '@.ml_fingerprint' 2>/dev/null)
|
|
zkp_fingerprint=$(echo "$data" | jsonfilter -e '@.zkp_fingerprint' 2>/dev/null)
|
|
timestamp=$(echo "$data" | jsonfilter -e '@.timestamp' 2>/dev/null)
|
|
|
|
# Validate IPv6 is in Yggdrasil range (200::/7)
|
|
if ! echo "$ipv6" | grep -qE '^2[0-9a-f]{2}:'; then
|
|
logger -t yggdrasil-discovery "Rejected: Invalid Yggdrasil IPv6: $ipv6"
|
|
return 1
|
|
fi
|
|
|
|
# Don't add self
|
|
local my_ipv6
|
|
my_ipv6=$(get_ygg_ipv6)
|
|
if [ "$ipv6" = "$my_ipv6" ]; then
|
|
return 0
|
|
fi
|
|
|
|
# Add to peer cache
|
|
add_peer_to_cache "$ipv6" "$pubkey" "$hostname" "$ml_fingerprint" "$zkp_fingerprint" "$timestamp"
|
|
|
|
# Auto-peer if enabled and trusted
|
|
local auto_peer
|
|
auto_peer=$(uci -q get yggdrasil-discovery.main.auto_peer)
|
|
|
|
if [ "$auto_peer" = "1" ]; then
|
|
local require_trust
|
|
require_trust=$(uci -q get yggdrasil-discovery.main.require_trust)
|
|
|
|
local should_connect=0
|
|
|
|
if [ "$require_trust" = "1" ]; then
|
|
# Only connect if trusted
|
|
if is_peer_trusted "$ml_fingerprint"; then
|
|
should_connect=1
|
|
logger -t yggdrasil-discovery "Auto-peering with trusted node: $hostname ($ipv6)"
|
|
else
|
|
logger -t yggdrasil-discovery "Skipping untrusted peer: $hostname ($ipv6)"
|
|
fi
|
|
else
|
|
# Connect to all discovered peers
|
|
should_connect=1
|
|
fi
|
|
|
|
if [ "$should_connect" = "1" ] && command -v yggdrasilctl >/dev/null 2>&1; then
|
|
# Check if already connected
|
|
local already_connected=0
|
|
yggdrasilctl -json getPeers 2>/dev/null | grep -q "$ipv6" && already_connected=1
|
|
|
|
if [ "$already_connected" = "0" ]; then
|
|
# Try to connect
|
|
yggdrasilctl addPeer "tcp://[$ipv6]:0" 2>/dev/null && {
|
|
logger -t yggdrasil-discovery "Connected to: $hostname ($ipv6)"
|
|
} || {
|
|
logger -t yggdrasil-discovery "Failed to connect to: $hostname ($ipv6)"
|
|
}
|
|
fi
|
|
fi
|
|
fi
|
|
|
|
return 0
|
|
}
|
|
|
|
# Handle peer departure (when a node goes offline)
|
|
handle_peer_departure() {
|
|
local data="$1"
|
|
local origin="$2"
|
|
|
|
local ipv6
|
|
ipv6=$(echo "$data" | jsonfilter -e '@.ipv6' 2>/dev/null)
|
|
|
|
[ -z "$ipv6" ] && return 1
|
|
|
|
remove_peer_from_cache "$ipv6"
|
|
logger -t yggdrasil-discovery "Peer departed: $ipv6"
|
|
}
|
|
|
|
# Main handler entry point (called from gossip.sh)
|
|
handle() {
|
|
local action="$1"
|
|
local data="$2"
|
|
local origin="$3"
|
|
|
|
case "$action" in
|
|
announce)
|
|
handle_peer_announce "$data" "$origin"
|
|
;;
|
|
departure)
|
|
handle_peer_departure "$data" "$origin"
|
|
;;
|
|
*)
|
|
# Default to announce
|
|
handle_peer_announce "$data" "$origin"
|
|
;;
|
|
esac
|
|
}
|
|
|
|
# CLI entry point
|
|
case "${1:-}" in
|
|
handle)
|
|
shift
|
|
handle "$@"
|
|
;;
|
|
*)
|
|
# Called with just data (from gossip.sh)
|
|
handle "announce" "$1" "$2"
|
|
;;
|
|
esac
|