diff options
author | Galen Guyer <galen@galenguyer.com> | 2022-07-25 22:50:05 -0400 |
---|---|---|
committer | Galen Guyer <galen@galenguyer.com> | 2022-07-26 09:39:20 -0400 |
commit | ffb96165c3b3c8c24551c8b0c04d372b2fa15301 (patch) | |
tree | 68059ae9c85dd68585f921f96e4987283d41e30b | |
parent | bff76b1ba1a842cd36cd24b85a43163f64af3bfe (diff) |
Use postgres crate instead of sqlx for speed improvements
-rw-r--r-- | Cargo.lock | 255 | ||||
-rw-r--r-- | Cargo.toml | 4 | ||||
-rw-r--r-- | Dockerfile | 2 | ||||
-rw-r--r-- | src/main.rs | 64 |
4 files changed, 260 insertions, 65 deletions
@@ -136,9 +136,9 @@ checksum = "2d0165d2900ae6778e36e80bbc4da3b5eefccee9ba939761f9c2882a5d9af3ff" [[package]] name = "crossbeam-queue" -version = "0.3.5" +version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f25d8400f4a7a5778f0e4e52384a48cbd9b5c495d110786187fc750075277a2" +checksum = "1cd42583b04998a5363558e5f9291ee5a5ff6b49944332103f251e7479a82aa7" dependencies = [ "cfg-if", "crossbeam-utils", @@ -146,9 +146,9 @@ dependencies = [ [[package]] name = "crossbeam-utils" -version = "0.8.10" +version = "0.8.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d82ee10ce34d7bc12c2122495e7593a9c41347ecdd64185af4ecf72cb1a7f83" +checksum = "51887d4adc7b564537b15adcfb307936f8075dfcd5f00dde9a9f1d29383682bc" dependencies = [ "cfg-if", "once_cell", @@ -156,9 +156,9 @@ dependencies = [ [[package]] name = "crypto-common" -version = "0.1.3" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57952ca27b5e3606ff4dd79b0020231aaf9d6aa76dc05fd30137538c50bd3ce8" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" dependencies = [ "generic-array", "typenum", @@ -171,6 +171,40 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3ee2393c4a91429dffb4bedf19f4d6abf27d8a732c8ce4980305d782e5426d57" [[package]] +name = "deadpool" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "421fe0f90f2ab22016f32a9881be5134fdd71c65298917084b0c7477cbc3856e" +dependencies = [ + "async-trait", + "deadpool-runtime", + "num_cpus", + "retain_mut", + "tokio", +] + +[[package]] +name = "deadpool-postgres" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c668a58063c6331e3437e3146970943ad82b1b36169fd979bb2645ac2088209a" +dependencies = [ + "deadpool", + "log", + "tokio", + "tokio-postgres", +] + +[[package]] +name = "deadpool-runtime" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eaa37046cc0f6c3cc6090fbdbf73ef0b8ef4cfcc37f6befc0020f63e8cf121e1" +dependencies = [ + "tokio", +] + +[[package]] name = "digest" version = "0.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -203,8 +237,9 @@ dependencies = [ [[package]] name = "dns-server" -version = "0.1.6" +version = "0.1.9" dependencies = [ + "deadpool-postgres", "dotenvy", "env_logger", "futures-util", @@ -213,6 +248,7 @@ dependencies = [ "log", "sqlx", "tokio", + "tokio-postgres", "trust-dns-proto", ] @@ -269,6 +305,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "77f3309417938f28bf8228fcff79a4a37103981e3e186d2ccd19c74b38f4eb71" [[package]] +name = "fallible-iterator" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4443176a9f2c162692bd3d352d745ef9413eec5782a80d8fd6f8a1ac692a07f7" + +[[package]] name = "form_urlencoded" version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -279,6 +321,21 @@ dependencies = [ ] [[package]] +name = "futures" +version = "0.3.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f73fe65f54d1e12b726f517d3e2135ca3125a437b6d998caf1962961f7172d9e" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + +[[package]] name = "futures-channel" version = "0.3.21" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -295,6 +352,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0c09fd04b7e4073ac7156a9539b57a484a8ea920f79c7c675d05d289ab6110d3" [[package]] +name = "futures-executor" +version = "0.3.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9420b90cfa29e327d0429f19be13e7ddb68fa1cccb09d65e5706b8c7a749b8a6" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + +[[package]] name = "futures-intrusive" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -340,10 +408,13 @@ version = "0.3.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d8b7abd5d659d9b90c8cba917f6ec750a74e2dc23902ef9cd4cc8c8b22e6036a" dependencies = [ + "futures-channel", "futures-core", + "futures-io", "futures-macro", "futures-sink", "futures-task", + "memchr", "pin-project-lite", "pin-utils", "slab", @@ -372,9 +443,9 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.12.1" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db0d4cf898abf0081f964436dc980e96670a0f36863e4b83aaacdb65c9d7ccc3" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" dependencies = [ "ahash", ] @@ -506,9 +577,9 @@ checksum = "112c678d4050afce233f4f2852bb2eb519230b3cf12f33585275537d7e41578d" [[package]] name = "js-sys" -version = "0.3.58" +version = "0.3.59" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3fac17f7123a73ca62df411b1bf727ccc805daa070338fda671c86dac1bdc27" +checksum = "258451ab10b34f8af53416d1fdab72c22e805f0c92a1136d59470ec0b11138b2" dependencies = [ "wasm-bindgen", ] @@ -685,6 +756,24 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" [[package]] +name = "phf" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fabbf1ead8a5bcbc20f5f8b939ee3f5b0f6f281b6ad3468b84656b658b455259" +dependencies = [ + "phf_shared", +] + +[[package]] +name = "phf_shared" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6796ad771acdc0123d2a88dc428b5e38ef24456743ddb1744ed628f9815c096" +dependencies = [ + "siphasher", +] + +[[package]] name = "pin-project-lite" version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -697,6 +786,35 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] +name = "postgres-protocol" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "878c6cbf956e03af9aa8204b407b9cbf47c072164800aa918c516cd4b056c50c" +dependencies = [ + "base64", + "byteorder", + "bytes", + "fallible-iterator", + "hmac", + "md-5", + "memchr", + "rand", + "sha2", + "stringprep", +] + +[[package]] +name = "postgres-types" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebd6e8b7189a73169290e89bd24c771071f1012d8fe6f738f5226531f0b03d89" +dependencies = [ + "bytes", + "fallible-iterator", + "postgres-protocol", +] + +[[package]] name = "ppv-lite86" version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -788,6 +906,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49b3de9ec5dc0a3417da371aab17d729997c15010e7fd24ff707773a33bddb64" [[package]] +name = "retain_mut" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4389f1d5789befaf6029ebd9f7dac4af7f7e3d61b69d4f30e2ac02b57e7712b0" + +[[package]] name = "ring" version = "0.16.20" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -847,18 +971,18 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.137" +version = "1.0.140" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61ea8d54c77f8315140a05f4c7237403bf38b72704d031543aa1d16abbf517d1" +checksum = "fc855a42c7967b7c369eb5860f7164ef1f6f81c20c7cc1141f2a604e18723b03" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.137" +version = "1.0.140" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f26faba0c3959972377d3b2d306ee9f71faee9714294e41bb777f83f88578be" +checksum = "6f2122636b9fe3b81f1cb25099fcf2d3f542cdb1d45940d56c713158884a05da" dependencies = [ "proc-macro2", "quote", @@ -908,6 +1032,12 @@ dependencies = [ ] [[package]] +name = "siphasher" +version = "0.3.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7bd3e3206899af3f8b12af284fafc038cc1dc2b41d1b89dd17297221c5d225de" + +[[package]] name = "slab" version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -949,7 +1079,7 @@ dependencies = [ [[package]] name = "sqlx" version = "0.6.0" -source = "git+https://github.com/launchbadge/sqlx#bd40cc9a2fc4946bfb86d4947f915b16a13ec4b4" +source = "git+https://github.com/launchbadge/sqlx#58712ae55263857c60c0df5f1adac8a076a74fab" dependencies = [ "sqlx-core", "sqlx-macros", @@ -958,7 +1088,7 @@ dependencies = [ [[package]] name = "sqlx-core" version = "0.6.0" -source = "git+https://github.com/launchbadge/sqlx#bd40cc9a2fc4946bfb86d4947f915b16a13ec4b4" +source = "git+https://github.com/launchbadge/sqlx#58712ae55263857c60c0df5f1adac8a076a74fab" dependencies = [ "ahash", "atoi", @@ -1010,7 +1140,7 @@ dependencies = [ [[package]] name = "sqlx-macros" version = "0.6.0" -source = "git+https://github.com/launchbadge/sqlx#bd40cc9a2fc4946bfb86d4947f915b16a13ec4b4" +source = "git+https://github.com/launchbadge/sqlx#58712ae55263857c60c0df5f1adac8a076a74fab" dependencies = [ "dotenv", "either", @@ -1028,7 +1158,7 @@ dependencies = [ [[package]] name = "sqlx-rt" version = "0.6.0" -source = "git+https://github.com/launchbadge/sqlx#bd40cc9a2fc4946bfb86d4947f915b16a13ec4b4" +source = "git+https://github.com/launchbadge/sqlx#58712ae55263857c60c0df5f1adac8a076a74fab" dependencies = [ "once_cell", "tokio", @@ -1138,6 +1268,29 @@ dependencies = [ ] [[package]] +name = "tokio-postgres" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19c88a47a23c5d2dc9ecd28fb38fba5fc7e5ddc1fe64488ec145076b0c71c8ae" +dependencies = [ + "async-trait", + "byteorder", + "bytes", + "fallible-iterator", + "futures", + "log", + "parking_lot 0.12.1", + "percent-encoding", + "phf", + "pin-project-lite", + "postgres-protocol", + "postgres-types", + "socket2", + "tokio", + "tokio-util", +] + +[[package]] name = "tokio-rustls" version = "0.23.4" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1160,6 +1313,40 @@ dependencies = [ ] [[package]] +name = "tokio-util" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc463cd8deddc3770d20f9852143d50bf6094e640b485cb2e189a2099085ff45" +dependencies = [ + "bytes", + "futures-core", + "futures-sink", + "pin-project-lite", + "tokio", + "tracing", +] + +[[package]] +name = "tracing" +version = "0.1.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a400e31aa60b9d44a52a8ee0343b5b18566b03a8321e0d321f695cf56e940160" +dependencies = [ + "cfg-if", + "pin-project-lite", + "tracing-core", +] + +[[package]] +name = "tracing-core" +version = "0.1.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b7358be39f2f274f322d2aaed611acc57f382e8eb1e5b48cb9ae30933495ce7" +dependencies = [ + "once_cell", +] + +[[package]] name = "trust-dns-proto" version = "0.21.2" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1255,9 +1442,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.81" +version = "0.2.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c53b543413a17a202f4be280a7e5c62a1c69345f5de525ee64f8cfdbc954994" +checksum = "fc7652e3f6c4706c8d9cd54832c4a4ccb9b5336e2c3bd154d5cccfbf1c1f5f7d" dependencies = [ "cfg-if", "wasm-bindgen-macro", @@ -1265,13 +1452,13 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.81" +version = "0.2.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5491a68ab4500fa6b4d726bd67408630c3dbe9c4fe7bda16d5c82a1fd8c7340a" +checksum = "662cd44805586bd52971b9586b1df85cdbbd9112e4ef4d8f41559c334dc6ac3f" dependencies = [ "bumpalo", - "lazy_static", "log", + "once_cell", "proc-macro2", "quote", "syn", @@ -1280,9 +1467,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.81" +version = "0.2.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c441e177922bc58f1e12c022624b6216378e5febc2f0533e41ba443d505b80aa" +checksum = "b260f13d3012071dfb1512849c033b1925038373aea48ced3012c09df952c602" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -1290,9 +1477,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.81" +version = "0.2.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d94ac45fcf608c1f45ef53e748d35660f168490c10b23704c7779ab8f5c3048" +checksum = "5be8e654bdd9b79216c2929ab90721aa82faf65c48cdf08bdc4e7f51357b80da" dependencies = [ "proc-macro2", "quote", @@ -1303,15 +1490,15 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.81" +version = "0.2.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a89911bd99e5f3659ec4acf9c4d93b0a90fe4a2a11f15328472058edc5261be" +checksum = "6598dd0bd3c7d51095ff6531a5b23e02acdc81804e30d8f07afb77b7215a140a" [[package]] name = "web-sys" -version = "0.3.58" +version = "0.3.59" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2fed94beee57daf8dd7d51f2b15dc2bcde92d7a72304cdf662a4371008b71b90" +checksum = "ed055ab27f941423197eb86b2035720b1a3ce40504df082cac2ecc6ed73335a1" dependencies = [ "js-sys", "wasm-bindgen", @@ -1329,9 +1516,9 @@ dependencies = [ [[package]] name = "webpki-roots" -version = "0.22.3" +version = "0.22.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44d8de8415c823c8abd270ad483c6feeac771fad964890779f9a8cb24fbbc1bf" +checksum = "f1c760f0d366a6c24a02ed7816e23e691f5d92291f94d15e836006fd11b04daf" dependencies = [ "webpki", ] @@ -1,12 +1,13 @@ [package] name = "dns-server" -version = "0.1.6" +version = "0.1.9" edition = "2021" license = "MIT" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] +deadpool-postgres = "0.10.2" dotenvy = "0.15.1" env_logger = "0.9.0" futures-util = "0.3.21" @@ -15,4 +16,5 @@ lazy_static = "1.4.0" log = "0.4.17" sqlx = { git = "https://github.com/launchbadge/sqlx", features = ["postgres", "runtime-tokio-rustls", "ipnetwork"] } tokio = { version = "1.19.2", features = ["full"] } +tokio-postgres = "0.7.6" trust-dns-proto = "0.21.2" @@ -11,7 +11,7 @@ FROM scratch AS bin COPY --from=builder /src/target/release/dns-server /dns-server -FROM debian:buster AS deb-builder +FROM debian:bullseye AS deb-builder ARG VERSION WORKDIR /root/ COPY pkg/ /root/pkg/ diff --git a/src/main.rs b/src/main.rs index e37544e..4cf0976 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,14 +1,14 @@ +use deadpool_postgres::{Manager, ManagerConfig, Pool}; use futures_util::StreamExt; use lazy_static::lazy_static; use sqlx::postgres::PgPoolOptions; -use sqlx::FromRow; -use sqlx::{Pool, Postgres}; use std::env; use std::net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr}; use std::str::FromStr; use std::sync::{Arc, Mutex}; use std::time::Instant; use tokio::net::UdpSocket; +use tokio_postgres::NoTls; use trust_dns_proto::op::{Message, MessageType, ResponseCode}; use trust_dns_proto::rr::rdata::{SOA, TXT}; use trust_dns_proto::rr::{DNSClass, Name, RData, Record, RecordType}; @@ -26,10 +26,9 @@ lazy_static! { "INSERT INTO queries (ip, qname, qtype, rcode, duration_us, host) VALUES ($1, $2, $3, $4, $5, $6)"; } -#[derive(Clone, FromRow)] +#[derive(Clone)] pub struct FdnsRecord { pub name: String, - #[sqlx(rename = "type")] pub record_type: String, pub content: String, pub ttl: i32, @@ -60,13 +59,14 @@ async fn main() { option_env!("CARGO_PKG_VERSION").unwrap_or_else(|| "unknown") ); - let pg_pool = Arc::new( - PgPoolOptions::new() - .max_connections(12) - .connect(&env::var("DATABASE_URL").expect("DATABASE_URL not set")) - .await - .unwrap(), - ); + let pg_config = + tokio_postgres::Config::from_str(&env::var("DATABASE_URL").expect("DATABASE_URL not set")) + .unwrap(); + let mgr_config = ManagerConfig { + recycling_method: deadpool_postgres::RecyclingMethod::Fast, + }; + let mgr = Manager::from_config(pg_config, NoTls, mgr_config); + let pg_pool = Arc::new(Pool::builder(mgr).max_size(64).build().unwrap()); log::info!("Connected to data postgres"); let metrics_pool = Arc::new( @@ -143,11 +143,12 @@ async fn main() { async fn handle_message( raw_message: SerialMessage, - postgres: &Pool<Postgres>, + postgres: &Arc<Pool>, sender: Arc<Mutex<BufDnsStreamHandle>>, ) -> Result<Metrics, ()> { let src = raw_message.addr(); let start = Instant::now(); + let postgres_t = postgres.get(); log::debug!("Recieved packet from {src}"); let mut message = match Message::from_vec(raw_message.bytes()) { @@ -166,12 +167,18 @@ async fn handle_message( let qname = query.name().to_string().to_lowercase(); let qtype = query.query_type().to_string(); log::trace!("[{}] Querying for {qname}", message.id()); - - let records = sqlx::query_as::<_, FdnsRecord>(&GET_DOMAIN_SQL) - .bind(&qname) - .fetch_all(postgres) - .await - .unwrap(); + + let postgres = postgres_t.await.unwrap(); + let statement = postgres.prepare_cached(&GET_DOMAIN_SQL).await.unwrap(); + let rows = postgres.query(&statement, &[&qname]).await.unwrap(); + let records: Vec<FdnsRecord> = rows.iter().map(|r| { + FdnsRecord { + name: r.get(0), + record_type: r.get(1), + content: r.get(2), + ttl: r.get(3) + } + }).collect(); log::trace!("[{}] Query for {qname} completed", message.id()); // TODO: CNAME resolution @@ -216,9 +223,7 @@ async fn handle_message( None } }, - RecordType::TXT => { - Some(RData::TXT(TXT::new(vec![r.content.clone()]))) - } + RecordType::TXT => Some(RData::TXT(TXT::new(vec![r.content.clone()]))), RecordType::SOA => match parse_soa(&r.content) { Ok(soa) => Some(RData::SOA(soa)), Err(_) => { @@ -238,14 +243,15 @@ async fn handle_message( log::trace!("[{}] Answers set", message.id()); if message.answers().is_empty() { - log::debug!("[{}] No answers, querying to see if we're authoritative", message.id()); - let zone_count: (i64,) = sqlx::query_as(&GET_ZONE_SQL) - .bind(&qname) - .fetch_one(postgres) - .await - .unwrap(); - log::trace!("[{}] Query returned {} zones", message.id(), zone_count.0); - if zone_count.0 == 0 { + log::debug!( + "[{}] No answers, querying to see if we're authoritative", + message.id() + ); + let statement = postgres.prepare_cached(&GET_ZONE_SQL).await.unwrap(); + let count_row = postgres.query_one(&statement, &[&qname]).await.unwrap(); + let zone_count: i64 = count_row.get(0); + log::trace!("[{}] Query returned {} zones", message.id(), zone_count); + if zone_count == 0 { message.set_response_code(ResponseCode::Refused); } else if records.is_empty() { message.set_response_code(ResponseCode::NXDomain); |