iroh_http_core/endpoint/config.rs
1//! Node configuration types passed to [`super::IrohEndpoint::bind`].
2
3use crate::http::server::stack::CompressionOptions;
4
5/// Networking / QUIC transport configuration.
6#[derive(Debug, Clone, Default)]
7pub struct NetworkingOptions {
8 /// Relay server mode. `"default"`, `"staging"`, `"disabled"`, or `"custom"`. Default: `"default"`.
9 pub relay_mode: Option<String>,
10 /// Custom relay server URLs. Only used when `relay_mode` is `"custom"`.
11 pub relays: Vec<String>,
12 /// UDP socket addresses to bind. Empty means OS-assigned.
13 pub bind_addrs: Vec<String>,
14 /// Milliseconds before an idle QUIC connection is cleaned up.
15 pub idle_timeout_ms: Option<u64>,
16 /// HTTP proxy URL for relay traffic.
17 pub proxy_url: Option<String>,
18 /// Read `HTTP_PROXY` / `HTTPS_PROXY` env vars for proxy config.
19 pub proxy_from_env: bool,
20 /// Disable relay servers and DNS discovery entirely. Overrides `relay_mode`.
21 /// Useful for in-process tests where endpoints connect via direct addresses.
22 pub disabled: bool,
23}
24
25/// DNS-based peer discovery configuration.
26///
27/// Marked `#[non_exhaustive]` so future additive fields are not a
28/// source-compatibility break for downstream crates: construct it via
29/// [`DiscoveryOptions::new`] (or [`Default`]) and set optional fields on the
30/// returned value rather than with an exhaustive struct literal.
31#[derive(Debug, Clone)]
32#[non_exhaustive]
33pub struct DiscoveryOptions {
34 /// DNS discovery server URL. Uses n0 DNS defaults when `None`.
35 pub dns_server: Option<String>,
36 /// Whether to enable DNS discovery. Default: `true`.
37 pub enabled: bool,
38 /// Explicit ordinary-DNS nameservers for iroh's resolver.
39 ///
40 /// Accepts IPs such as `"8.8.8.8"` and numeric scoped IPv6 addresses such
41 /// as `"fe80::1%17"`. This setting is unrelated to DNS-SD/mDNS: it supplies
42 /// the resolver used for relay, pkarr, and DNS-discovery hostnames when the
43 /// platform's system DNS config is unavailable. Empty means use iroh's
44 /// default resolver.
45 pub dns_nameservers: Vec<String>,
46}
47
48impl DiscoveryOptions {
49 /// Construct a `DiscoveryOptions` with an empty `dns_nameservers` list.
50 ///
51 /// The forward-compatible constructor for downstream crates: since the
52 /// struct is `#[non_exhaustive]` they cannot use a struct literal. Set
53 /// `dns_nameservers` (or any future field) on the returned value.
54 pub fn new(dns_server: Option<String>, enabled: bool) -> Self {
55 Self {
56 dns_server,
57 enabled,
58 dns_nameservers: Vec::new(),
59 }
60 }
61}
62
63impl Default for DiscoveryOptions {
64 fn default() -> Self {
65 Self {
66 dns_server: None,
67 enabled: true,
68 dns_nameservers: Vec::new(),
69 }
70 }
71}
72
73/// Connection-pool tuning.
74#[derive(Debug, Clone, Default)]
75pub struct PoolOptions {
76 /// Maximum number of idle connections to keep in the pool.
77 pub max_connections: Option<usize>,
78 /// Milliseconds a pooled connection may remain idle before being evicted.
79 pub idle_timeout_ms: Option<u64>,
80}
81
82/// Body-streaming and handle-store configuration.
83#[derive(Debug, Clone, Default)]
84pub struct StreamingOptions {
85 /// Capacity (in chunks) of each body channel. Default: 32.
86 pub channel_capacity: Option<usize>,
87 /// Maximum byte length of a single chunk in `send_chunk`. Default: 65536.
88 pub max_chunk_size_bytes: Option<usize>,
89 /// Milliseconds to wait for a slow body reader. Default: 30000.
90 pub drain_timeout_ms: Option<u64>,
91 /// TTL in ms for slab handle entries. `0` disables sweeping. Default: 300000.
92 pub handle_ttl_ms: Option<u64>,
93 /// How often (in ms) the TTL sweep task runs. Default: 60000 (60 s).
94 /// Reducing this lowers the worst-case leaked-handle window at the cost of
95 /// more frequent write-lock acquisitions on every handle registry.
96 /// Useful for short-lived endpoints and test fixtures.
97 pub sweep_interval_ms: Option<u64>,
98}
99
100/// Configuration passed to [`super::IrohEndpoint::bind`].
101#[derive(Debug, Clone, Default)]
102pub struct NodeOptions {
103 /// 32-byte Ed25519 secret key. Generate a fresh one when `None`.
104 pub key: Option<[u8; 32]>,
105 /// Networking / QUIC transport configuration.
106 pub networking: NetworkingOptions,
107 /// DNS-based peer discovery configuration.
108 pub discovery: DiscoveryOptions,
109 /// Connection-pool tuning.
110 pub pool: PoolOptions,
111 /// Body-streaming and handle-store configuration.
112 pub streaming: StreamingOptions,
113 /// ALPN capabilities to advertise.
114 ///
115 /// Valid values: [`ALPN_STR`](crate::ALPN_STR) (`"iroh-http/2"`) and
116 /// [`ALPN_DUPLEX_STR`](crate::ALPN_DUPLEX_STR) (`"iroh-http/2-duplex"`).
117 ///
118 /// When empty (the default), both protocols are advertised. When non-empty,
119 /// the base protocol (`iroh-http/2`) is automatically injected if not
120 /// already present. Unknown values cause [`super::IrohEndpoint::bind`] to
121 /// return an error.
122 pub capabilities: Vec<String>,
123 /// Write TLS session keys to $SSLKEYLOGFILE. Dev/debug only.
124 pub keylog: bool,
125 /// Maximum byte size of the HTTP/1.1 request or response head.
126 /// `None` = 65536. `Some(0)` is rejected.
127 pub max_header_size: Option<usize>,
128 /// Maximum decompressed response body bytes the client will accept per
129 /// outgoing `fetch()`. Default: 256 MiB. Protects against compression
130 /// bombs from malicious peers.
131 pub max_response_body_bytes: Option<usize>,
132 pub compression: Option<CompressionOptions>,
133}