Skip to content
This repository has been archived by the owner on Apr 26, 2024. It is now read-only.

Commit

Permalink
cleanup: docs and module structure
Browse files Browse the repository at this point in the history
  • Loading branch information
Frando committed Apr 10, 2024
1 parent 2b500da commit 319f770
Show file tree
Hide file tree
Showing 14 changed files with 359 additions and 313 deletions.
33 changes: 30 additions & 3 deletions iroh-dns-server/src/config.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
//! Configuration for the server

use anyhow::{anyhow, Context, Result};
use serde::{Deserialize, Serialize};
use std::{
Expand All @@ -13,21 +15,42 @@ use crate::{

const DEFAULT_METRICS_ADDR: SocketAddr = SocketAddr::new(IpAddr::V4(Ipv4Addr::LOCALHOST), 9117);

/// Server configuration
///
/// The config is usually loaded from a file with [`Self::load`].
///
/// The struct also implements [`Default`] which creates a config suitable for local development
/// and testing.
#[derive(Debug, Serialize, Deserialize)]
pub struct Config {
/// Config for the HTTP server
///
/// If set to `None` no HTTP server will be started.
pub http: Option<HttpConfig>,
/// Config for the HTTPS server
///
/// If set to `None` no HTTPS server will be started.
pub https: Option<HttpsConfig>,
/// Config for the DNS server.
pub dns: DnsConfig,
/// Config for the metrics server.
///
/// The metrics server is started by default. To disable the metrics server, set to
/// `Some(MetricsConfig::disabled())`.
pub metrics: Option<MetricsConfig>,
}

/// The config for the metrics server.
#[derive(Debug, Serialize, Deserialize)]
pub struct MetricsConfig {
disabled: bool,
bind_addr: Option<SocketAddr>,
/// Set to true to disable the metrics server.
pub disabled: bool,
/// Optionally set a custom address to bind to.
pub bind_addr: Option<SocketAddr>,
}

impl MetricsConfig {
/// Disable the metrics server.
pub fn disabled() -> Self {
Self {
disabled: true,
Expand All @@ -37,6 +60,7 @@ impl MetricsConfig {
}

impl Config {
/// Load the config from a file.
pub async fn load(path: impl AsRef<Path>) -> Result<Config> {
let s = tokio::fs::read_to_string(path.as_ref())
.await
Expand All @@ -45,6 +69,7 @@ impl Config {
Ok(config)
}

/// Get the data directory.
pub fn data_dir() -> Result<PathBuf> {
let dir = if let Some(val) = env::var_os("IROH_DNS_DATA_DIR") {
PathBuf::from(val)
Expand All @@ -57,11 +82,13 @@ impl Config {
Ok(dir)
}

/// Get the path to the store database file.
pub fn signed_packet_store_path() -> Result<PathBuf> {
Ok(Self::data_dir()?.join("signed-packets-1.db"))
}

pub fn metrics_addr(&self) -> Option<SocketAddr> {
/// Get the address where the metrics server should be bound, if set.
pub(crate) fn metrics_addr(&self) -> Option<SocketAddr> {
match &self.metrics {
None => Some(DEFAULT_METRICS_ADDR),
Some(conf) => match conf.disabled {
Expand Down
17 changes: 12 additions & 5 deletions iroh-dns-server/src/dns.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,15 +34,15 @@ use tokio::{
sync::broadcast,
};

use crate::{metrics::Metrics, state::ZoneStore};
use crate::{metrics::Metrics, store::ZoneStore};

use self::node_authority::NodeAuthority;

mod node_authority;

pub const DEFAULT_NS_TTL: u32 = 60 * 60 * 12; // 12h
pub const DEFAULT_SOA_TTL: u32 = 60 * 60 * 24 * 14; // 14d
pub const DEFAULT_A_TTL: u32 = 60 * 60; // 1h
const DEFAULT_NS_TTL: u32 = 60 * 60 * 12; // 12h
const DEFAULT_SOA_TTL: u32 = 60 * 60 * 24 * 14; // 14d
const DEFAULT_A_TTL: u32 = 60 * 60; // 1h

/// DNS server settings
#[derive(Clone, Debug, Serialize, Deserialize)]
Expand All @@ -67,12 +67,14 @@ pub struct DnsConfig {
pub rr_ns: Option<String>,
}

/// A DNS server that serves pkarr signed packets.
pub struct DnsServer {
local_addr: SocketAddr,
server: hickory_server::ServerFuture<DnsHandler>,
}

impl DnsServer {
/// Spawn the server.
pub async fn spawn(config: DnsConfig, dns_handler: DnsHandler) -> Result<Self> {
const TCP_TIMEOUT: Duration = Duration::from_millis(1000);
let mut server = hickory_server::ServerFuture::new(dns_handler);
Expand All @@ -96,15 +98,20 @@ impl DnsServer {
})
}

/// Get the local address of the UDP/TCP socket.
pub fn local_addr(&self) -> SocketAddr {
self.local_addr
}

/// Shutdown the server an wait for all tasks to complete.
pub async fn shutdown(mut self) -> Result<()> {
self.server.shutdown_gracefully().await?;
Ok(())
}

/// Wait for all tasks to complete.
///
/// Runs forever unless tasks fail.
pub async fn run_until_done(mut self) -> Result<()> {
self.server.block_until_done().await?;
Ok(())
Expand All @@ -115,7 +122,7 @@ impl DnsServer {
#[derive(Clone, derive_more::Debug)]
pub struct DnsHandler {
#[debug("Catalog")]
pub catalog: Arc<Catalog>,
catalog: Arc<Catalog>,
}

impl DnsHandler {
Expand Down
6 changes: 4 additions & 2 deletions iroh-dns-server/src/dns/node_authority.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,10 @@ use hickory_server::{

use tracing::{debug, trace};

use crate::util::PublicKeyBytes;
use crate::{state::ZoneStore, util::record_set_append_origin};
use crate::{
store::ZoneStore,
util::{record_set_append_origin, PublicKeyBytes},
};

#[derive(derive_more::Debug)]
pub struct NodeAuthority {
Expand Down
24 changes: 23 additions & 1 deletion iroh-dns-server/src/http.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
//! HTTP server part of iroh-dns-server

use std::{
net::{IpAddr, Ipv4Addr, SocketAddr},
time::Instant,
Expand Down Expand Up @@ -33,29 +35,41 @@ use crate::{config::Config, metrics::Metrics};

pub use self::tls::CertMode;

/// Config for the HTTP server
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct HttpConfig {
/// Port to bind to
pub port: u16,
/// Optionally set a custom bind address (will use 0.0.0.0 if unset)
pub bind_addr: Option<IpAddr>,
}

/// Config for the HTTPS server
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct HttpsConfig {
/// Port to bind to
pub port: u16,
/// Optionally set a custom bind address (will use 0.0.0.0 if unset)
pub bind_addr: Option<IpAddr>,
/// The list of domains for which SSL certificates should be created.
pub domains: Vec<String>,
/// The mode of SSL certificate creation
pub cert_mode: CertMode,
/// Letsencrypt contact email address (required if using [`CertMode::LetsEncrypt`])
pub letsencrypt_contact: Option<String>,
/// Whether to use the letsenrypt production servers (only applies to [`CertMode::LetsEncrypt`])
pub letsencrypt_prod: Option<bool>,
}

/// The HTTP(S) server part of iroh-dns-server
pub struct HttpServer {
tasks: JoinSet<std::io::Result<()>>,
http_addr: Option<SocketAddr>,
https_addr: Option<SocketAddr>,
}

impl HttpServer {
/// Spawn the server
pub async fn spawn(
http_config: Option<HttpConfig>,
https_config: Option<HttpsConfig>,
Expand Down Expand Up @@ -130,20 +144,28 @@ impl HttpServer {
https_addr,
})
}

/// Get the bound address of the HTTP socket.
pub fn http_addr(&self) -> Option<SocketAddr> {
self.http_addr
}

/// Get the bound address of the HTTPS socket.
pub fn https_addr(&self) -> Option<SocketAddr> {
self.https_addr
}

/// Shutdown the server and wait for all tasks to complete.
pub async fn shutdown(mut self) -> Result<()> {
// TODO: Graceful cancellation.
self.tasks.abort_all();
self.run_until_done().await?;
Ok(())
}

/// Wait for all tasks to complete.
///
/// Runs forever unless tasks fail.
pub async fn run_until_done(mut self) -> Result<()> {
let mut final_res: anyhow::Result<()> = Ok(());
while let Some(res) = self.tasks.join_next().await {
Expand All @@ -164,7 +186,7 @@ impl HttpServer {
}
}

pub fn create_app(state: AppState) -> Router {
pub(crate) fn create_app(state: AppState) -> Router {
// configure cors middleware
let cors = CorsLayer::new()
// allow `GET` and `POST` when accessing the resource
Expand Down
2 changes: 1 addition & 1 deletion iroh-dns-server/src/http/pkarr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ use http::{header, StatusCode};

use tracing::info;

use crate::state::{AppState, PacketSource};
use crate::util::PublicKeyBytes;
use crate::{state::AppState, store::PacketSource};

use super::error::AppError;

Expand Down
5 changes: 5 additions & 0 deletions iroh-dns-server/src/http/tls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,20 @@ use tokio_rustls_acme::{axum::AxumAcceptor, caches::DirCache, AcmeConfig};
use tokio_stream::StreamExt;
use tracing::{debug, error, info_span, Instrument};

/// The mode how SSL certificates should be created.
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, strum::Display)]
#[serde(rename_all = "snake_case")]
pub enum CertMode {
/// Certs are loaded from a the `cert_cache` path
Manual,
/// ACME with LetsEncrypt servers
LetsEncrypt,
/// Create self-signed certificates and store them in the `cert_cache` path
SelfSigned,
}

impl CertMode {
/// Build the [`TlsAcceptor`] for this mode.
pub async fn build(
&self,
domains: Vec<String>,
Expand Down
12 changes: 8 additions & 4 deletions iroh-dns-server/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
//! A DNS server and pkarr relay

#![deny(missing_docs, rustdoc::broken_intra_doc_links)]

pub mod config;
pub mod dns;
pub mod http;
pub mod metrics;
pub mod run;
pub mod server;
pub mod state;
pub mod store;
pub mod util;
mod store;
mod util;

#[cfg(test)]
mod tests {
Expand All @@ -26,7 +30,7 @@ mod tests {
};
use url::Url;

use crate::run::Server;
use crate::server::Server;

#[tokio::test]
async fn integration_smoke() -> Result<()> {
Expand Down
9 changes: 3 additions & 6 deletions iroh-dns-server/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,9 @@ use anyhow::Result;
use axum::{routing::get, Router};
use clap::Parser;
use futures::{Future, FutureExt};
use iroh_dns_server::{self as server, config::Config, dns::DnsHandler, state::AppState};
use iroh_metrics::metrics::start_metrics_server;
use server::metrics::init_metrics;
use server::run::run_with_config_until_ctrl_c;
use server::state::ZoneStore;
use server::store::SignedPacketStore;
use iroh_dns_server::{
config::Config, metrics::init_metrics, server::run_with_config_until_ctrl_c,
};
use std::net::{Ipv4Addr, SocketAddr};
use std::path::PathBuf;
use tokio::task::JoinSet;
Expand Down
5 changes: 5 additions & 0 deletions iroh-dns-server/src/metrics.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
//! Metrics support for the server

use iroh_metrics::core::{Core, Counter, Metric};
use struct_iterable::Iterable;

/// Metrics for iroh-dns-server
#[derive(Debug, Clone, Iterable)]
#[allow(missing_docs)]
pub struct Metrics {
pub pkarr_publish_update: Counter,
pub pkarr_publish_noop: Counter,
Expand Down Expand Up @@ -52,6 +56,7 @@ impl Metric for Metrics {
}
}

/// Init the metrics collection core.
pub fn init_metrics() {
Core::init(|reg, metrics| {
metrics.insert(Metrics::new(reg));
Expand Down
6 changes: 5 additions & 1 deletion iroh-dns-server/src/run.rs → iroh-dns-server/src/server.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
//! The main server which combines the DNS and HTTP(S) servers.

use anyhow::Result;
use iroh_metrics::metrics::start_metrics_server;
use tracing::info;
Expand All @@ -6,7 +8,8 @@ use crate::{
config::Config,
dns::{DnsHandler, DnsServer},
http::HttpServer,
state::{AppState, ZoneStore},
state::AppState,
store::ZoneStore,
};

/// Spawn the server and run until the `Ctrl-C` signal is received, then shutdown.
Expand All @@ -19,6 +22,7 @@ pub async fn run_with_config_until_ctrl_c(config: Config) -> Result<()> {
Ok(())
}

/// The iroh-dns server.
pub struct Server {
http_server: HttpServer,
dns_server: DnsServer,
Expand Down
Loading

0 comments on commit 319f770

Please sign in to comment.