Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions modoh-lib/src/constants.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,12 @@ pub const UPSTREAM: &str = "8.8.8.8:53";
pub const ERROR_TTL: u32 = 2;
pub const MAX_TTL: u32 = 604800;
pub const MIN_TTL: u32 = 10;
pub const STALE_IF_ERROR_SECS: u32 = 86400;
pub const STALE_WHILE_REVALIDATE_SECS: u32 = 60;
pub const STALE_IF_ERROR_SECS: u32 = 300;
pub const STALE_WHILE_REVALIDATE_SECS: u32 = 5;
/// ODoH Config cache is expired after at least 10 seconds
pub const MAX_ODOH_CONFIG_TTL_SECS: u64 = 10;
/// HTTPSig Config cache is expired after at least 10 seconds
pub const MAX_HTTPSIG_CONFIG_TTL_SECS: u64 = 10;

/// Maximum ratio of TCP sessions to UDP sessions
pub const TARGET_UDP_TCP_RATIO: usize = 8;
Expand Down
43 changes: 35 additions & 8 deletions modoh-lib/src/target/target_main.rs
Original file line number Diff line number Diff line change
@@ -1,18 +1,19 @@
use super::odoh::ODoHPublicKey;
use crate::{
constants::{
HTTPSIG_CONFIGS_PATH, ODOH_CONFIGS_PATH, ODOH_KEY_ROTATION_SECS, STALE_IF_ERROR_SECS, STALE_WHILE_REVALIDATE_SECS,
HTTPSIG_CONFIGS_PATH, MAX_HTTPSIG_CONFIG_TTL_SECS, MAX_ODOH_CONFIG_TTL_SECS, ODOH_CONFIGS_PATH, ODOH_KEY_ROTATION_SECS,
STALE_IF_ERROR_SECS, STALE_WHILE_REVALIDATE_SECS,
},
count::RequestCount,
error::*,
globals::Globals,
httpsig_handler::HttpSigKeyRotationState,
hyper_body::{full, BoxBody},
hyper_body::{BoxBody, full},
message_util::inspect_host,
trace::*,
};
use futures::{select, FutureExt};
use http::{header, Method, Request, Response};
use futures::{FutureExt, select};
use http::{Method, Request, Response, header};
use hyper::body::Bytes;
use std::{net::SocketAddr, sync::Arc, time::Duration};
use tokio::{
Expand All @@ -21,6 +22,23 @@ use tokio::{
};
use tracing::instrument;

#[instrument(level = "debug", skip_all)]
/// build http response from given packet
pub(super) fn build_http_response_no_store(packet: &[u8], content_type: &str, cors: bool) -> HttpResult<Response<BoxBody>> {
let packet_len = packet.len();
let mut response_builder = Response::builder()
.header(header::CONTENT_LENGTH, packet_len)
.header(header::CONTENT_TYPE, content_type)
.header(header::CACHE_CONTROL, "no-store, no-cache, must-revalidate, max-age=0")
.header(header::PRAGMA, "no-cache")
.header(header::EXPIRES, "0");
if cors {
response_builder = response_builder.header(hyper::header::ACCESS_CONTROL_ALLOW_ORIGIN, "*");
}
let body = full(Bytes::copy_from_slice(packet));
response_builder.body(body).map_err(|_| HttpError::InvalidODoHConfig)
}

#[instrument(level = "debug", skip_all)]
/// build http response from given packet
pub(super) fn build_http_response(packet: &[u8], ttl: u64, content_type: &str, cors: bool) -> HttpResult<Response<BoxBody>> {
Expand All @@ -30,8 +48,7 @@ pub(super) fn build_http_response(packet: &[u8], ttl: u64, content_type: &str, c
.header(header::CONTENT_TYPE, content_type)
.header(
header::CACHE_CONTROL,
format!("max-age={ttl}, stale-if-error={STALE_IF_ERROR_SECS}, stale-while-revalidate={STALE_WHILE_REVALIDATE_SECS}")
.as_str(),
format!("max-age={ttl}, stale-if-error={STALE_IF_ERROR_SECS}, stale-while-revalidate={STALE_WHILE_REVALIDATE_SECS}, must-revalidate").as_str(),
);
if cors {
response_builder = response_builder.header(hyper::header::ACCESS_CONTROL_ALLOW_ORIGIN, "*");
Expand Down Expand Up @@ -98,7 +115,12 @@ impl InnerTarget {
let lock = self.odoh_configs.read().await;
let configs = lock.as_config().to_owned();
drop(lock);
build_http_response(&configs, ODOH_KEY_ROTATION_SECS, "application/octet-stream", true)
build_http_response(
&configs,
ODOH_KEY_ROTATION_SECS.min(MAX_ODOH_CONFIG_TTL_SECS),
"application/octet-stream",
true,
)
}

/// Serve httpsig config via GET method
Expand All @@ -123,7 +145,12 @@ impl InnerTarget {
let configs = lock.as_config().to_owned();
let rotation_period = httpsig_state.rotation_period.as_secs();
drop(lock);
build_http_response(&configs, rotation_period, "application/octet-stream", true)
build_http_response(
&configs,
rotation_period.min(MAX_HTTPSIG_CONFIG_TTL_SECS),
"application/octet-stream",
true,
)
}

/// Start odoh config rotation service
Expand Down
11 changes: 6 additions & 5 deletions modoh-lib/src/target/target_serve_query.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use super::{target_main::build_http_response, InnerTarget};
use super::{InnerTarget, target_main::build_http_response};
use crate::{
constants::{
DNS_QUERY_PARAM, DOH_CONTENT_TYPE, MAX_DNS_QUESTION_LEN, MAX_DNS_RESPONSE_LEN, MIN_DNS_PACKET_LEN, ODOH_CONTENT_TYPE,
Expand All @@ -7,10 +7,11 @@ use crate::{
dns,
error::*,
hyper_body::BoxBody,
message_util::{check_content_type, inspect_host, read_request_body, RequestType},
message_util::{RequestType, check_content_type, inspect_host, read_request_body},
target::target_main::build_http_response_no_store,
trace::*,
};
use base64::{engine::general_purpose, Engine as _};
use base64::{Engine as _, engine::general_purpose};
use byteorder::{BigEndian, ByteOrder};
use futures::TryFutureExt;
use http::{Method, Request, Response};
Expand All @@ -21,7 +22,7 @@ use tokio::{
net::{TcpSocket, UdpSocket},
time::timeout,
};
use tracing::{instrument, Instrument as _};
use tracing::{Instrument as _, instrument};

#[derive(Debug)]
/// Dns response object
Expand Down Expand Up @@ -96,7 +97,7 @@ impl InnerTarget {
self.log_dns_message(_peer_addr, &res.packet, &req_headers);

let encrypted_body = context.encrypt_response(res.packet)?;
let resp = build_http_response(&encrypted_body, 0u64, ODOH_CONTENT_TYPE, false)?;
let resp = build_http_response_no_store(&encrypted_body, ODOH_CONTENT_TYPE, false)?;
Ok(resp)
}
}
Expand Down