Skip to content

Commit

Permalink
Merge pull request #75 from junkurihara/develop
Browse files Browse the repository at this point in the history
0.4.2
junkurihara authored Jan 6, 2025

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
2 parents 8886889 + 3b2ebc9 commit ae3d77f
Showing 7 changed files with 45 additions and 42 deletions.
8 changes: 7 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -13,7 +13,13 @@
You should also include the user name that made the change.
-->

## 0.4.2 (Unreleased)
## 0.4.3 (Unreleased)

## 0.4.2

- Feat: Change the default hasher for hashmaps and hashsets from `FxHash` to `aHash` for better performance with string keys. Use `ArcSwap` instead of `RwLock` for internal ODoH config storage.
- Deps.
- Refactor: Various minor improvements.

## 0.4.1

6 changes: 3 additions & 3 deletions proxy-bin/Cargo.toml
Original file line number Diff line number Diff line change
@@ -19,9 +19,9 @@ doh-auth-proxy-lib = { path = "../proxy-lib/", default-features = false, feature
"anonymous-token",
] }

anyhow = "1.0.94"
anyhow = "1.0.95"
mimalloc = { version = "*", default-features = false }
serde = { version = "1.0.216", default-features = false, features = ["derive"] }
serde = { version = "1.0.217", default-features = false, features = ["derive"] }
derive_builder = "0.20.2"
tokio = { version = "1.42.0", default-features = false, features = [
"net",
@@ -30,7 +30,7 @@ tokio = { version = "1.42.0", default-features = false, features = [
"sync",
"macros",
] }
async-trait = "0.1.83"
async-trait = "0.1.84"

# config
clap = { version = "4.5.23", features = ["std", "cargo", "wrap_help"] }
17 changes: 10 additions & 7 deletions proxy-lib/Cargo.toml
Original file line number Diff line number Diff line change
@@ -28,15 +28,18 @@ futures = { version = "0.3.31", default-features = false, features = [
"std",
"async-await",
] }
anyhow = "1.0.94"
anyhow = "1.0.95"
tracing = "0.1.41"
thiserror = "2.0.8"
async-trait = "0.1.83"
serde = { version = "1.0.216", features = ["derive"] }
itertools = "0.13.0"
rustc-hash = "2.1.0"
thiserror = "2.0.9"
async-trait = "0.1.84"
serde = { version = "1.0.217", features = ["derive"] }
itertools = "0.14.0"
ahash = "0.8.11"
crossbeam-channel = "0.5.14"

# odoh config server
arc-swap = "1.7.1"

# doh and odoh client with cache and query manipulation plugins
odoh-rs = { git = "https://github.com/junkurihara/odoh-rs.git", branch = "master" }
bytes = "1.9.0"
@@ -50,7 +53,7 @@ regex = "1.11.1"
socket2 = "0.5.8"

# http client
reqwest = { version = "0.12.9", default-features = false, features = [
reqwest = { version = "0.12.12", default-features = false, features = [
"json",
"http2",
"hickory-dns",
7 changes: 5 additions & 2 deletions proxy-lib/src/doh_client/cache.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
use super::dns_message::{self, Request};
use crate::log::*;
use anyhow::anyhow;
use hashlink::{linked_hash_map::RawEntryMut, LinkedHashMap};
use hashlink::linked_hash_map::RawEntryMut;
use hickory_proto::op::Message;
use tokio::{
sync::Mutex,
time::{Duration, Instant},
};

/// Type alias for LinkedHashMap using ahash::RandomState as hasher
type LinkedHashMap<K, V> = hashlink::LinkedHashMap<K, V, ahash::RandomState>;

#[derive(Debug, Clone)]
/// Cache object
pub struct CacheObject {
@@ -75,7 +78,7 @@ impl Cache {
/// Create a new cache
pub fn new(max_size: usize) -> Self {
Cache {
cache: Mutex::new(LinkedHashMap::new()),
cache: Mutex::new(LinkedHashMap::default()),
max_size,
}
}
3 changes: 0 additions & 3 deletions proxy-lib/src/doh_client/doh_client_main.rs
Original file line number Diff line number Diff line change
@@ -325,9 +325,6 @@ impl DoHClient {
let Some(odoh_config) = self.odoh_configs.as_ref().unwrap().get(target_obj).await else {
return Err(DohClientError::ODoHNoClientConfig);
};
let Some(odoh_config) = odoh_config.as_ref() else {
return Err(DohClientError::ODoHNoClientConfig);
};

// encrypt query
let (odoh_plaintext_query, encrypted_query_body, secret) = odoh_config.encrypt_query(packet_buf)?;
2 changes: 1 addition & 1 deletion proxy-lib/src/doh_client/manipulation/domain_override.rs
Original file line number Diff line number Diff line change
@@ -8,10 +8,10 @@ use super::{
QueryManipulation, QueryManipulationResult,
};
use crate::{log::*, QueryManipulationConfig};
use ahash::HashMap;
use async_trait::async_trait;
use hickory_proto::{op::Message, rr};
use regex::Regex;
use rustc_hash::FxHashMap as HashMap;
use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};

#[async_trait]
44 changes: 19 additions & 25 deletions proxy-lib/src/doh_client/odoh_config_store.rs
Original file line number Diff line number Diff line change
@@ -4,7 +4,8 @@ use crate::{
http_client::HttpClientInner,
log::*,
};
use rustc_hash::FxHashMap as HashMap;
use ahash::HashMap;
use arc_swap::ArcSwap;
use std::sync::Arc;
use tokio::{
sync::{Notify, RwLock},
@@ -15,79 +16,72 @@ use url::Url;
#[allow(clippy::complexity)]
/// ODoH config store
pub struct ODoHConfigStore {
inner: Arc<RwLock<HashMap<Arc<DoHTarget>, Arc<Option<ODoHConfig>>>>>,
// inner: Arc<RwLock<HashMap<Arc<DoHTarget>, Arc<Option<ODoHConfig>>>>>,
inner: ArcSwap<HashMap<Arc<DoHTarget>, Option<Arc<ODoHConfig>>>>,
http_client: Arc<RwLock<HttpClientInner>>,
}

impl ODoHConfigStore {
/// Create a new ODoHConfigStore
pub async fn new(http_client: Arc<RwLock<HttpClientInner>>, targets: &[Arc<DoHTarget>]) -> Result<Self, DohClientError> {
let inner = targets
.iter()
.map(|target| (target.clone(), Arc::new(None as Option<ODoHConfig>)))
.collect::<HashMap<_, _>>();
let inner = targets.iter().map(|target| (target.clone(), None)).collect::<HashMap<_, _>>();
let res = Self {
inner: Arc::new(RwLock::new(inner)),
inner: ArcSwap::new(Arc::new(inner)),
http_client,
};
res.update_odoh_config_from_well_known().await?;
Ok(res)
}

/// Get a ODoHConfig for DoHTarget
pub async fn get(&self, target: &Arc<DoHTarget>) -> Option<Arc<Option<ODoHConfig>>> {
let inner_lock = self.inner.read().await;
let inner = inner_lock.get(target)?;
Some(inner.clone())
pub async fn get(&self, target: &Arc<DoHTarget>) -> Option<Arc<ODoHConfig>> {
self.inner.load().get(target).cloned().unwrap_or(None)
}

/// Fetch ODoHConfig from target
pub async fn update_odoh_config_from_well_known(&self) -> Result<(), DohClientError> {
// TODO: Add auth token when fetching config?
// fetch public key from odoh target (/.well-known)
let inner_lock = self.inner.read().await;
let inner = inner_lock.clone();
drop(inner_lock);
let inner = self.inner.load();

let futures = inner.keys().map(|target| async {
let mut destination = Url::parse(&format!("{}://{}", target.scheme(), target.authority())).unwrap();
destination.set_path(ODOH_CONFIG_PATH);
let lock = self.http_client.read().await;
debug!("Fetching ODoH config from {}", destination);
lock
let res = lock
.get(destination)
.header(reqwest::header::ACCEPT, "application/binary")
.send()
.await
.await;
(target.clone(), res)
});
let joined = futures::future::join_all(futures);
let update_futures = joined.await.into_iter().zip(inner).map(|(res, current)| async move {
let update_futures = joined.await.into_iter().map(|(target, res)| async move {
match res {
Ok(response) => {
if response.status() != reqwest::StatusCode::OK {
error!("Failed to fetch ODoH config!: {:?}", response.status());
return (current.0.clone(), Arc::new(None as Option<ODoHConfig>));
return (target.clone(), None);
}
let Ok(body) = response.bytes().await else {
error!("Failed to parse response body in ODoH config response");
return (current.0.clone(), Arc::new(None as Option<ODoHConfig>));
return (target.clone(), None);
};
let config = ODoHConfig::new(current.0.authority(), &body).ok();
(current.0.clone(), Arc::new(config))
let config = ODoHConfig::new(target.authority(), &body).ok();
(target.clone(), config.map(Arc::new))
}
Err(e) => {
error!("Failed to fetch ODoH config!: {:?}", e);
(current.0.clone(), Arc::new(None as Option<ODoHConfig>))
(target.clone(), None)
}
}
});
let update_joined = futures::future::join_all(update_futures)
.await
.into_iter()
.collect::<HashMap<_, _>>();
let mut inner_lock = self.inner.write().await;
*inner_lock = update_joined;
drop(inner_lock);
self.inner.store(Arc::new(update_joined));
Ok(())
}

0 comments on commit ae3d77f

Please sign in to comment.