$ show pradt2/always-online-stun
This is a Rust application that periodically tests a curated list of STUN (Session Traversal Utilities for NAT) servers to verify their availability and correct behavior. The system sends STUN Binding Requests over UDP and TCP to each candidate server, compares the returned mapped address against a reference server's result to detect NAT-induced mapping changes, and optionally checks for the OTHER-ADDRESS attribute to identify servers that support NAT behavior testing (RFC 5780). Healthy servers are written to several text files (hostnames, IPv4 addresses, IPv6 addresses) with and without the NAT-testing capability filter. The output lists are shuffled hourly to distribute load across servers. The architecture is a single binary built with Tokio async runtime, modularized into server loading, STUN query logic, output formatting, and a GeoIP caching layer. It is not a library; it is a self-contained service intended to run as a GitHub Actions cron job. The code is clean, idiomatic Rust with proper error handling and logging.
The LLM identified 2 files worth highlighting for reuse:
Implements a generic GeoIP client with a trait `GeoIpClient` and two implementations: `IpGeolocationIoClient` (requires API key) and `GeolocationDbClient` (free). A caching wrapper `CachedIpGeolocationIpClient` persists resolved coordinates to a JSON file using `BTreeMap`, reducing API calls. The caching layer is generic over the client implementation via trait bounds, making it reusable for any GeoIP provider. The async trait pattern and error handling are well-structured.
Provides two utilities: `join_all_with_semaphore` limits concurrent async futures to a maximum number of permits using `tokio::sync::Semaphore`, preventing resource exhaustion. `ReduceToString` is a trait extending iterators with a `reduce_to_string` method that concatenates Display items. Both are small, self-contained, and applicable to any async Rust project needing rate-limited futures or string joining.