feat: implement M2 — multiple upstreams & config

- Failover strategy: try resolvers in order until one succeeds
- Env var overrides: DOH_LISTEN, DOH_UPSTREAM_STRATEGY, DOH_UPSTREAM_RESOLVERS
- Graceful shutdown on SIGINT/SIGTERM
- Strategy parsed from config string to enum
- 14 tests passing, clippy clean, fmt clean
This commit is contained in:
2026-07-06 17:13:45 +03:30
parent 3a5c0d2aba
commit 13bf8ba528
7 changed files with 205 additions and 18 deletions

View File

@@ -11,11 +11,10 @@ use base64::Engine;
use hickory_proto::op::{Message, Query, ResponseCode};
use hickory_proto::rr::{Name, RecordType};
use std::sync::Arc;
use tokio::net::TcpListener;
use tower::ServiceExt;
use doh_forwarder::routes::{dns_query_get, dns_query_post, AppState};
use doh_forwarder::upstream::doh_client::DohClient;
use doh_forwarder::upstream::doh_client::{DohClient, Strategy};
/// Build a minimal DNS query for the given domain and record type.
fn build_dns_query(name: &str, rtype: RecordType) -> Vec<u8> {
@@ -36,6 +35,7 @@ fn test_state() -> AppState {
AppState {
doh_client: DohClient::new(resolvers),
rr_counter: Arc::new(std::sync::atomic::AtomicUsize::new(0)),
strategy: Strategy::RoundRobin,
}
}