feat: DNS-over-HTTPS (DoH) upstream forwarding (#14)
* feat: DNS-over-HTTPS upstream forwarding Encrypt upstream queries via DoH — ISPs see HTTPS traffic on port 443, not plaintext DNS on port 53. URL scheme determines transport: https:// = DoH, bare IP = plain UDP. Falls back to Quad9 DoH when system resolver cannot be detected. - Upstream enum (Udp/Doh) with Display and PartialEq - BytePacketBuffer::from_bytes constructor - reqwest http2 feature for DoH server compatibility - network_watch_loop guards against DoH→UDP silent downgrade - 5 new tests (mock DoH server, HTTP errors, timeout) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * style: cargo fmt Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * docs: add DoH to README — Why Numa, comparison table, roadmap Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
12
src/ctx.rs
12
src/ctx.rs
@@ -12,7 +12,7 @@ use crate::blocklist::BlocklistStore;
|
||||
use crate::buffer::BytePacketBuffer;
|
||||
use crate::cache::DnsCache;
|
||||
use crate::config::ZoneMap;
|
||||
use crate::forward::forward_query;
|
||||
use crate::forward::{forward_query, Upstream};
|
||||
use crate::header::ResultCode;
|
||||
use crate::lan::PeerStore;
|
||||
use crate::override_store::OverrideStore;
|
||||
@@ -35,7 +35,7 @@ pub struct ServerCtx {
|
||||
pub services: Mutex<ServiceStore>,
|
||||
pub lan_peers: Mutex<PeerStore>,
|
||||
pub forwarding_rules: Vec<ForwardingRule>,
|
||||
pub upstream: Mutex<SocketAddr>,
|
||||
pub upstream: Mutex<Upstream>,
|
||||
pub upstream_auto: bool,
|
||||
pub upstream_port: u16,
|
||||
pub lan_ip: Mutex<std::net::Ipv4Addr>,
|
||||
@@ -143,9 +143,11 @@ pub async fn handle_query(
|
||||
(resp, QueryPath::Cached)
|
||||
} else {
|
||||
let upstream =
|
||||
crate::system_dns::match_forwarding_rule(&qname, &ctx.forwarding_rules)
|
||||
.unwrap_or_else(|| *ctx.upstream.lock().unwrap());
|
||||
match forward_query(&query, upstream, ctx.timeout).await {
|
||||
match crate::system_dns::match_forwarding_rule(&qname, &ctx.forwarding_rules) {
|
||||
Some(addr) => Upstream::Udp(addr),
|
||||
None => ctx.upstream.lock().unwrap().clone(),
|
||||
};
|
||||
match forward_query(&query, &upstream, ctx.timeout).await {
|
||||
Ok(resp) => {
|
||||
ctx.cache.lock().unwrap().insert(&qname, qtype, &resp);
|
||||
(resp, QueryPath::Forwarded)
|
||||
|
||||
Reference in New Issue
Block a user