diff --git a/.github/workflows/_rust.yml b/.github/workflows/_rust.yml
index 2ee2ba0f5..0f91bc668 100644
--- a/.github/workflows/_rust.yml
+++ b/.github/workflows/_rust.yml
@@ -114,7 +114,7 @@ jobs:
rg --count --no-ignore "Packet for Internet resource" $TESTCASES_DIR
rg --count --no-ignore "Performed IP-NAT46" $TESTCASES_DIR
rg --count --no-ignore "Performed IP-NAT64" $TESTCASES_DIR
- rg --count --no-ignore "Too big DNS response, truncating" $TESTCASES_DIR
+ rg --count --no-ignore "Truncating DNS response" $TESTCASES_DIR
rg --count --no-ignore "Destination is unreachable" $TESTCASES_DIR
rg --count --no-ignore "Forwarding query for DNS resource to corresponding site" $TESTCASES_DIR
rg --count --no-ignore "Expanded single-label query into FQDN using search-domain" $TESTCASES_DIR
diff --git a/rust/Cargo.lock b/rust/Cargo.lock
index 48efc1427..26a47d049 100644
--- a/rust/Cargo.lock
+++ b/rust/Cargo.lock
@@ -1044,6 +1044,7 @@ dependencies = [
"backoff",
"connlib-client-shared",
"connlib-model",
+ "dns-types",
"firezone-logging",
"firezone-telemetry",
"flume",
@@ -1075,6 +1076,7 @@ dependencies = [
"backoff",
"connlib-client-shared",
"connlib-model",
+ "dns-types",
"firezone-logging",
"firezone-telemetry",
"flume",
@@ -1107,6 +1109,7 @@ dependencies = [
"bimap",
"chrono",
"connlib-model",
+ "dns-types",
"firezone-logging",
"firezone-tunnel",
"ip_network",
@@ -1130,7 +1133,6 @@ name = "connlib-model"
version = "0.1.0"
dependencies = [
"boringtun",
- "domain",
"ip_network",
"itertools 0.13.0",
"serde",
@@ -1706,13 +1708,12 @@ name = "dns-over-tcp"
version = "0.1.0"
dependencies = [
"anyhow",
- "domain",
+ "dns-types",
"firezone-bin-shared",
"firezone-logging",
"futures",
"ip-packet",
"ip_network",
- "itertools 0.13.0",
"rand 0.8.5",
"smoltcp",
"tokio",
@@ -1720,6 +1721,15 @@ dependencies = [
"tun",
]
+[[package]]
+name = "dns-types"
+version = "0.1.0"
+dependencies = [
+ "domain",
+ "thiserror 1.0.69",
+ "tracing",
+]
+
[[package]]
name = "domain"
version = "0.10.3"
@@ -2013,7 +2023,7 @@ dependencies = [
"clap",
"connlib-model",
"dns-lookup",
- "domain",
+ "dns-types",
"either",
"firezone-bin-shared",
"firezone-logging",
@@ -2141,6 +2151,7 @@ dependencies = [
"connlib-client-shared",
"connlib-model",
"dirs 5.0.1",
+ "dns-types",
"firezone-bin-shared",
"firezone-logging",
"firezone-telemetry",
@@ -2274,7 +2285,7 @@ dependencies = [
"derive_more 1.0.0",
"divan",
"dns-over-tcp",
- "domain",
+ "dns-types",
"firezone-logging",
"firezone-relay",
"futures",
@@ -3514,7 +3525,7 @@ name = "l4-tcp-dns-server"
version = "0.1.0"
dependencies = [
"anyhow",
- "domain",
+ "dns-types",
"futures",
"tokio",
"tracing",
@@ -3525,7 +3536,7 @@ name = "l4-udp-dns-server"
version = "0.1.0"
dependencies = [
"anyhow",
- "domain",
+ "dns-types",
"futures",
"tokio",
"tracing",
diff --git a/rust/Cargo.toml b/rust/Cargo.toml
index 0adbe9eb8..6de2df915 100644
--- a/rust/Cargo.toml
+++ b/rust/Cargo.toml
@@ -10,6 +10,7 @@ members = [
"connlib/snownet",
"connlib/tunnel",
"dns-over-tcp",
+ "dns-types",
"gateway",
"gui-client/src-common",
"gui-client/src-tauri",
@@ -50,7 +51,6 @@ difference = "2.0.0"
dirs = "5.0.1"
divan = "0.1.17"
dns-lookup = "2.0"
-domain = { version = "0.10", features = ["serde"] }
either = "1"
env_logger = "0.11.6"
etherparse = "0.16"
@@ -164,6 +164,7 @@ snownet = { path = "connlib/snownet" }
l4-udp-dns-server = { path = "connlib/l4-udp-dns-server" }
l4-tcp-dns-server = { path = "connlib/l4-tcp-dns-server" }
dns-over-tcp = { path = "dns-over-tcp" }
+dns-types = { path = "dns-types" }
firezone-relay = { path = "relay" }
connlib-model = { path = "connlib/model" }
firezone-tunnel = { path = "connlib/tunnel" }
diff --git a/rust/connlib/clients/android/Cargo.toml b/rust/connlib/clients/android/Cargo.toml
index d3ee7d7b8..be9b73529 100644
--- a/rust/connlib/clients/android/Cargo.toml
+++ b/rust/connlib/clients/android/Cargo.toml
@@ -15,6 +15,7 @@ anyhow = { workspace = true }
backoff = { workspace = true }
connlib-client-shared = { workspace = true }
connlib-model = { workspace = true }
+dns-types = { workspace = true }
firezone-logging = { workspace = true }
firezone-telemetry = { workspace = true }
flume = { workspace = true }
diff --git a/rust/connlib/clients/android/src/lib.rs b/rust/connlib/clients/android/src/lib.rs
index 63a929be3..4865487cd 100644
--- a/rust/connlib/clients/android/src/lib.rs
+++ b/rust/connlib/clients/android/src/lib.rs
@@ -9,7 +9,8 @@ use crate::tun::Tun;
use anyhow::{Context as _, Result};
use backoff::ExponentialBackoffBuilder;
use connlib_client_shared::{Callbacks, DisconnectError, Session, V4RouteList, V6RouteList};
-use connlib_model::{DomainName, ResourceView};
+use connlib_model::ResourceView;
+use dns_types::DomainName;
use firezone_logging::{err_with_src, sentry_layer};
use firezone_telemetry::{Telemetry, ANDROID_DSN};
use ip_network::{Ipv4Network, Ipv6Network};
diff --git a/rust/connlib/clients/apple/Cargo.toml b/rust/connlib/clients/apple/Cargo.toml
index 186f1d134..e1db51a5e 100644
--- a/rust/connlib/clients/apple/Cargo.toml
+++ b/rust/connlib/clients/apple/Cargo.toml
@@ -13,6 +13,7 @@ anyhow = { workspace = true }
backoff = { workspace = true }
connlib-client-shared = { workspace = true }
connlib-model = { workspace = true }
+dns-types = { workspace = true }
firezone-logging = { workspace = true }
firezone-telemetry = { workspace = true }
flume = { workspace = true }
diff --git a/rust/connlib/clients/apple/src/lib.rs b/rust/connlib/clients/apple/src/lib.rs
index 2c4598254..0b9e8f86a 100644
--- a/rust/connlib/clients/apple/src/lib.rs
+++ b/rust/connlib/clients/apple/src/lib.rs
@@ -9,8 +9,8 @@ use anyhow::Context;
use anyhow::Result;
use backoff::ExponentialBackoffBuilder;
use connlib_client_shared::{Callbacks, DisconnectError, Session, V4RouteList, V6RouteList};
-use connlib_model::DomainName;
use connlib_model::ResourceView;
+use dns_types::DomainName;
use firezone_logging::err_with_src;
use firezone_logging::sentry_layer;
use firezone_telemetry::Telemetry;
diff --git a/rust/connlib/clients/shared/Cargo.toml b/rust/connlib/clients/shared/Cargo.toml
index 9b4220be7..4661c391a 100644
--- a/rust/connlib/clients/shared/Cargo.toml
+++ b/rust/connlib/clients/shared/Cargo.toml
@@ -9,6 +9,7 @@ anyhow = { workspace = true }
backoff = { workspace = true }
bimap = { workspace = true }
connlib-model = { workspace = true }
+dns-types = { workspace = true }
firezone-logging = { workspace = true }
firezone-tunnel = { workspace = true }
ip_network = { workspace = true }
diff --git a/rust/connlib/clients/shared/src/callbacks.rs b/rust/connlib/clients/shared/src/callbacks.rs
index 3d4002aff..3704d8b65 100644
--- a/rust/connlib/clients/shared/src/callbacks.rs
+++ b/rust/connlib/clients/shared/src/callbacks.rs
@@ -1,4 +1,5 @@
-use connlib_model::{DomainName, ResourceView};
+use connlib_model::ResourceView;
+use dns_types::DomainName;
use ip_network::{Ipv4Network, Ipv6Network};
use std::{
net::{IpAddr, Ipv4Addr, Ipv6Addr},
diff --git a/rust/connlib/l4-tcp-dns-server/Cargo.toml b/rust/connlib/l4-tcp-dns-server/Cargo.toml
index e26842e82..9e51d950f 100644
--- a/rust/connlib/l4-tcp-dns-server/Cargo.toml
+++ b/rust/connlib/l4-tcp-dns-server/Cargo.toml
@@ -9,7 +9,7 @@ path = "lib.rs"
[dependencies]
anyhow = { workspace = true }
-domain = { workspace = true }
+dns-types = { workspace = true }
futures = { workspace = true }
tokio = { workspace = true, features = ["net", "io-util"] }
tracing = { workspace = true }
diff --git a/rust/connlib/l4-tcp-dns-server/lib.rs b/rust/connlib/l4-tcp-dns-server/lib.rs
index 2a05d41e5..d843ea3e8 100644
--- a/rust/connlib/l4-tcp-dns-server/lib.rs
+++ b/rust/connlib/l4-tcp-dns-server/lib.rs
@@ -2,8 +2,7 @@
#![cfg_attr(test, allow(clippy::unwrap_used))]
-use anyhow::{anyhow, Context as _, Result};
-use domain::base::Message;
+use anyhow::{Context as _, Result};
use futures::{
future::BoxFuture, stream::FuturesUnordered, task::AtomicWaker, FutureExt, StreamExt as _,
};
@@ -31,7 +30,7 @@ pub struct Server {
/// A set of futures that read DNS queries from TCP streams.
#[expect(clippy::type_complexity, reason = "We don't care.")]
reading_tcp_queries: FuturesUnordered<
- BoxFuture<'static, Result