hickory-dns-0.24.4/.cargo_vcs_info.json0000644000000001410000000000100133510ustar { "git": { "sha1": "b00cc1052cf769250063005e9fa268519522778f" }, "path_in_vcs": "bin" }hickory-dns-0.24.4/Cargo.lock0000644000001560750000000000100113460ustar # This file is automatically @generated by Cargo. # It is not intended for manual editing. version = 3 [[package]] name = "addr2line" version = "0.24.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1" dependencies = [ "gimli", ] [[package]] name = "adler2" version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" [[package]] name = "ahash" version = "0.8.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" dependencies = [ "cfg-if", "once_cell", "version_check", "zerocopy", ] [[package]] name = "aho-corasick" version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" dependencies = [ "memchr", ] [[package]] name = "anstyle" version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "55cc3b69f167a1ef2e161439aa98aed94e6028e5f9a59be9a6ffb47aef1651f9" [[package]] name = "async-recursion" version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3b43422f69d8ff38f95f1b2bb76517c91589a924d1559a0e935d7c8ce0274c11" dependencies = [ "proc-macro2", "quote", "syn", ] [[package]] name = "async-trait" version = "0.1.83" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "721cae7de5c34fbb2acd27e21e6d2cf7b886dce0c27388d46c4e6c47ea4318dd" dependencies = [ "proc-macro2", "quote", "syn", ] [[package]] name = "autocfg" version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" [[package]] name = "backtrace" version = "0.3.74" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8d82cb332cdfaed17ae235a638438ac4d4839913cc2af585c3c6746e8f8bee1a" dependencies = [ "addr2line", "cfg-if", "libc", "miniz_oxide", "object", "rustc-demangle", "windows-targets 0.52.6", ] [[package]] name = "base64" version = "0.21.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" [[package]] name = "basic-toml" version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "823388e228f614e9558c6804262db37960ec8821856535f5c3f59913140558f8" dependencies = [ "serde", ] [[package]] name = "bitflags" version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" [[package]] name = "bumpalo" version = "3.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec" [[package]] name = "byteorder" version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "325918d6fe32f23b19878fe4b34794ae41fc19ddbe53b10571a4874d44ffd39b" [[package]] name = "cc" version = "1.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "27f657647bcff5394bf56c7317665bbf790a137a50eaaa5c6bfbb9e27a518f2d" dependencies = [ "shlex", ] [[package]] name = "cfg-if" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "clap" version = "4.4.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e578d6ec4194633722ccf9544794b71b1385c3c027efe0c55db226fc880865c" dependencies = [ "clap_builder", "clap_derive", ] [[package]] name = "clap_builder" version = "4.4.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4df4df40ec50c46000231c914968278b1eb05098cf8f1b3a518a95030e71d1c7" dependencies = [ "anstyle", "clap_lex", "strsim", ] [[package]] name = "clap_derive" version = "4.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf9804afaaf59a91e75b022a30fb7229a7901f60c755489cc61c9b423b836442" dependencies = [ "heck 0.4.1", "proc-macro2", "quote", "syn", ] [[package]] name = "clap_lex" version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "702fc72eb24e5a1e48ce58027a675bc24edd52096d5397d4aea7c6dd9eca0bd1" [[package]] name = "core-foundation" version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" dependencies = [ "core-foundation-sys", "libc", ] [[package]] name = "core-foundation-sys" version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" [[package]] name = "data-encoding" version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e8566979429cf69b49a5c740c60791108e86440e8be149bbea4fe54d2c32d6e2" [[package]] name = "deranged" version = "0.3.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4" dependencies = [ "powerfmt", ] [[package]] name = "displaydoc" version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" dependencies = [ "proc-macro2", "quote", "syn", ] [[package]] name = "endian-type" version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c34f04666d835ff5d62e058c3995147c06f42fe86ff053337632bca83e42702d" [[package]] name = "enum-as-inner" version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a1e6a265c649f3f5979b601d26f1d05ada116434c87741c9493cb56218f76cbc" dependencies = [ "heck 0.5.0", "proc-macro2", "quote", "syn", ] [[package]] name = "equivalent" version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" [[package]] name = "errno" version = "0.3.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "33d852cb9b869c2a9b3df2f71a3074817f01e1844f839a144f5fcef059a4eb5d" dependencies = [ "libc", "windows-sys 0.59.0", ] [[package]] name = "fallible-iterator" version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2acce4a10f12dc2fb14a218589d4f1f62ef011b2d0cc4b3cb1bba8e94da14649" [[package]] name = "fallible-streaming-iterator" version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7360491ce676a36bf9bb3c56c1aa791658183a54d2744120f27285738d90465a" [[package]] name = "fastrand" version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" [[package]] name = "fnv" version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" [[package]] name = "foreign-types" version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" dependencies = [ "foreign-types-shared", ] [[package]] name = "foreign-types-shared" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" [[package]] name = "form_urlencoded" version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" dependencies = [ "percent-encoding", ] [[package]] name = "futures" version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "65bc07b1a8bc7c85c5f2e110c476c7389b4554ba72af57d8445ea63a576b0876" dependencies = [ "futures-channel", "futures-core", "futures-executor", "futures-io", "futures-sink", "futures-task", "futures-util", ] [[package]] name = "futures-channel" version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" dependencies = [ "futures-core", "futures-sink", ] [[package]] name = "futures-core" version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" [[package]] name = "futures-executor" version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e28d1d997f585e54aebc3f97d39e72338912123a67330d723fdbb564d646c9f" dependencies = [ "futures-core", "futures-task", "futures-util", ] [[package]] name = "futures-io" version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" [[package]] name = "futures-macro" version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" dependencies = [ "proc-macro2", "quote", "syn", ] [[package]] name = "futures-sink" version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" [[package]] name = "futures-task" version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" [[package]] name = "futures-util" version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" dependencies = [ "futures-channel", "futures-core", "futures-io", "futures-macro", "futures-sink", "futures-task", "memchr", "pin-project-lite", "pin-utils", "slab", ] [[package]] name = "getrandom" version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" dependencies = [ "cfg-if", "libc", "wasi", ] [[package]] name = "gimli" version = "0.31.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" [[package]] name = "h2" version = "0.3.26" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "81fe527a889e1532da5c525686d96d4c2e74cdd345badf8dfef9f6b39dd5f5e8" dependencies = [ "bytes", "fnv", "futures-core", "futures-sink", "futures-util", "http", "indexmap", "slab", "tokio", "tokio-util", "tracing", ] [[package]] name = "h3" version = "0.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b83e1915177ea624b5bbbdb16bc54f0c106c9664892c695f995e53f5c6793b80" dependencies = [ "bytes", "fastrand", "futures-util", "http", "pin-project-lite", "tokio", "tracing", ] [[package]] name = "h3-quinn" version = "0.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ac9675014d703c3d516a121757bbc02e53f1ee838e0729fc7534b35024a81ae4" dependencies = [ "bytes", "futures", "h3", "quinn", "quinn-proto", "tokio", "tokio-util", ] [[package]] name = "hashbrown" version = "0.14.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" dependencies = [ "ahash", ] [[package]] name = "hashbrown" version = "0.15.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" [[package]] name = "hashlink" version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6ba4ff7128dee98c7dc9794b6a411377e1404dba1c97deb8d1a55297bd25d8af" dependencies = [ "hashbrown 0.14.5", ] [[package]] name = "heck" version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" [[package]] name = "heck" version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" [[package]] name = "hickory-client" version = "0.24.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "156579a5cd8d1fc6f0df87cc21b6ee870db978a163a1ba484acd98a4eff5a6de" dependencies = [ "cfg-if", "data-encoding", "futures-channel", "futures-util", "hickory-proto", "once_cell", "radix_trie", "rand", "rustls", "thiserror", "tokio", "tracing", ] [[package]] name = "hickory-dns" version = "0.24.4" dependencies = [ "clap", "futures-util", "hickory-client", "hickory-proto", "hickory-resolver", "hickory-server", "native-tls", "regex", "rustls", "time", "tokio", "tracing", "tracing-subscriber", "webpki-roots", ] [[package]] name = "hickory-proto" version = "0.24.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "92652067c9ce6f66ce53cc38d1169daa36e6e7eb7dd3b63b5103bd9d97117248" dependencies = [ "async-trait", "bytes", "cfg-if", "data-encoding", "enum-as-inner", "futures-channel", "futures-io", "futures-util", "h2", "h3", "h3-quinn", "http", "idna", "ipnet", "native-tls", "once_cell", "openssl", "quinn", "rand", "ring 0.17.8", "rustls", "rustls-native-certs", "rustls-pemfile", "serde", "thiserror", "tinyvec", "tokio", "tokio-native-tls", "tokio-openssl", "tokio-rustls", "tracing", "url", "webpki-roots", ] [[package]] name = "hickory-recursor" version = "0.24.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c48355926bf44f366bf5212edea0db475e6f0ef9c59ae5ab9c6dc716434e12f" dependencies = [ "async-recursion", "async-trait", "bytes", "cfg-if", "enum-as-inner", "futures-util", "hickory-proto", "hickory-resolver", "lru-cache", "parking_lot", "serde", "thiserror", "tokio", "tracing", ] [[package]] name = "hickory-resolver" version = "0.24.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cbb117a1ca520e111743ab2f6688eddee69db4e0ea242545a604dce8a66fd22e" dependencies = [ "cfg-if", "futures-util", "hickory-proto", "ipconfig", "lru-cache", "once_cell", "parking_lot", "rand", "resolv-conf", "rustls", "rustls-native-certs", "serde", "smallvec", "thiserror", "tokio", "tokio-openssl", "tokio-rustls", "tracing", "webpki-roots", ] [[package]] name = "hickory-server" version = "0.24.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "090078aff4e305853f8ccfbc89e6a1eec8a189bcb842be46255a2b660dae9416" dependencies = [ "async-trait", "basic-toml", "bytes", "cfg-if", "enum-as-inner", "futures-util", "h2", "h3", "h3-quinn", "hickory-proto", "hickory-recursor", "hickory-resolver", "http", "openssl", "rusqlite", "rustls", "serde", "thiserror", "time", "tokio", "tokio-openssl", "tokio-rustls", "tokio-util", "tracing", ] [[package]] name = "hostname" version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3c731c3e10504cc8ed35cfe2f1db4c9274c3d35fa486e3b31df46f068ef3e867" dependencies = [ "libc", "match_cfg", "winapi", ] [[package]] name = "http" version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1" dependencies = [ "bytes", "fnv", "itoa", ] [[package]] name = "icu_collections" version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "db2fa452206ebee18c4b5c2274dbf1de17008e874b4dc4f0aea9d01ca79e4526" dependencies = [ "displaydoc", "yoke", "zerofrom", "zerovec", ] [[package]] name = "icu_locid" version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "13acbb8371917fc971be86fc8057c41a64b521c184808a698c02acc242dbf637" dependencies = [ "displaydoc", "litemap", "tinystr", "writeable", "zerovec", ] [[package]] name = "icu_locid_transform" version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "01d11ac35de8e40fdeda00d9e1e9d92525f3f9d887cdd7aa81d727596788b54e" dependencies = [ "displaydoc", "icu_locid", "icu_locid_transform_data", "icu_provider", "tinystr", "zerovec", ] [[package]] name = "icu_locid_transform_data" version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fdc8ff3388f852bede6b579ad4e978ab004f139284d7b28715f773507b946f6e" [[package]] name = "icu_normalizer" version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "19ce3e0da2ec68599d193c93d088142efd7f9c5d6fc9b803774855747dc6a84f" dependencies = [ "displaydoc", "icu_collections", "icu_normalizer_data", "icu_properties", "icu_provider", "smallvec", "utf16_iter", "utf8_iter", "write16", "zerovec", ] [[package]] name = "icu_normalizer_data" version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f8cafbf7aa791e9b22bec55a167906f9e1215fd475cd22adfcf660e03e989516" [[package]] name = "icu_properties" version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "93d6020766cfc6302c15dbbc9c8778c37e62c14427cb7f6e601d849e092aeef5" dependencies = [ "displaydoc", "icu_collections", "icu_locid_transform", "icu_properties_data", "icu_provider", "tinystr", "zerovec", ] [[package]] name = "icu_properties_data" version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "67a8effbc3dd3e4ba1afa8ad918d5684b8868b3b26500753effea8d2eed19569" [[package]] name = "icu_provider" version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6ed421c8a8ef78d3e2dbc98a973be2f3770cb42b606e3ab18d6237c4dfde68d9" dependencies = [ "displaydoc", "icu_locid", "icu_provider_macros", "stable_deref_trait", "tinystr", "writeable", "yoke", "zerofrom", "zerovec", ] [[package]] name = "icu_provider_macros" version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6" dependencies = [ "proc-macro2", "quote", "syn", ] [[package]] name = "idna" version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "686f825264d630750a544639377bae737628043f20d38bbc029e8f29ea968a7e" dependencies = [ "idna_adapter", "smallvec", "utf8_iter", ] [[package]] name = "idna_adapter" version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "daca1df1c957320b2cf139ac61e7bd64fed304c5040df000a745aa1de3b4ef71" dependencies = [ "icu_normalizer", "icu_properties", ] [[package]] name = "indexmap" version = "2.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "62f822373a4fe84d4bb149bf54e584a7f4abec90e072ed49cda0edea5b95471f" dependencies = [ "equivalent", "hashbrown 0.15.2", ] [[package]] name = "ipconfig" version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b58db92f96b720de98181bbbe63c831e87005ab460c1bf306eb2622b4707997f" dependencies = [ "socket2", "widestring", "windows-sys 0.48.0", "winreg", ] [[package]] name = "ipnet" version = "2.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ddc24109865250148c2e0f3d25d4f0f479571723792d3802153c60922a4fb708" [[package]] name = "itoa" version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d75a2a4b1b190afb6f5425f10f6a8f959d2ea0b9c2b1d79553551850539e4674" [[package]] name = "js-sys" version = "0.3.76" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6717b6b5b077764fb5966237269cb3c64edddde4b14ce42647430a78ced9e7b7" dependencies = [ "once_cell", "wasm-bindgen", ] [[package]] name = "lazy_static" version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" [[package]] name = "libc" version = "0.2.168" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5aaeb2981e0606ca11d79718f8bb01164f1d6ed75080182d3abf017e6d244b6d" [[package]] name = "libsqlite3-sys" version = "0.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0c10584274047cb335c23d3e61bcef8e323adae7c5c8c760540f73610177fc3f" dependencies = [ "cc", "pkg-config", "vcpkg", ] [[package]] name = "linked-hash-map" version = "0.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" [[package]] name = "linux-raw-sys" version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" [[package]] name = "litemap" version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4ee93343901ab17bd981295f2cf0026d4ad018c7c31ba84549a4ddbb47a45104" [[package]] name = "lock_api" version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" dependencies = [ "autocfg", "scopeguard", ] [[package]] name = "log" version = "0.4.22" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" [[package]] name = "lru-cache" version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "31e24f1ad8321ca0e8a1e0ac13f23cb668e6f5466c2c57319f6a5cf1cc8e3b1c" dependencies = [ "linked-hash-map", ] [[package]] name = "match_cfg" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ffbee8634e0d45d258acb448e7eaab3fce7a0a467395d4d9f228e3c1f01fb2e4" [[package]] name = "matchers" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558" dependencies = [ "regex-automata 0.1.10", ] [[package]] name = "memchr" version = "2.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" [[package]] name = "miniz_oxide" version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e2d80299ef12ff69b16a84bb182e3b9df68b5a91574d3d4fa6e41b65deec4df1" dependencies = [ "adler2", ] [[package]] name = "mio" version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2886843bf800fba2e3377cff24abf6379b4c4d5c6681eaf9ea5b0d15090450bd" dependencies = [ "libc", "wasi", "windows-sys 0.52.0", ] [[package]] name = "native-tls" version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a8614eb2c83d59d1c8cc974dd3f920198647674a0a035e1af1fa58707e317466" dependencies = [ "libc", "log", "openssl", "openssl-probe", "openssl-sys", "schannel", "security-framework", "security-framework-sys", "tempfile", ] [[package]] name = "nibble_vec" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "77a5d83df9f36fe23f0c3648c6bbb8b0298bb5f1939c8f2704431371f4b84d43" dependencies = [ "smallvec", ] [[package]] name = "nu-ansi-term" version = "0.46.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84" dependencies = [ "overload", "winapi", ] [[package]] name = "num-conv" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" [[package]] name = "object" version = "0.36.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "aedf0a2d09c573ed1d8d85b30c119153926a2b36dce0ab28322c09a117a4683e" dependencies = [ "memchr", ] [[package]] name = "once_cell" version = "1.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775" [[package]] name = "openssl" version = "0.10.70" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "61cfb4e166a8bb8c9b55c500bc2308550148ece889be90f609377e58140f42c6" dependencies = [ "bitflags", "cfg-if", "foreign-types", "libc", "once_cell", "openssl-macros", "openssl-sys", ] [[package]] name = "openssl-macros" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", "syn", ] [[package]] name = "openssl-probe" version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" [[package]] name = "openssl-sys" version = "0.9.105" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b22d5b84be05a8d6947c7cb71f7c849aa0f112acd4bf51c2a7c1c988ac0a9dc" dependencies = [ "cc", "libc", "pkg-config", "vcpkg", ] [[package]] name = "overload" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" [[package]] name = "parking_lot" version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" dependencies = [ "lock_api", "parking_lot_core", ] [[package]] name = "parking_lot_core" version = "0.9.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" dependencies = [ "cfg-if", "libc", "redox_syscall", "smallvec", "windows-targets 0.52.6", ] [[package]] name = "percent-encoding" version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" [[package]] name = "pin-project-lite" version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "915a1e146535de9163f3987b8944ed8cf49a18bb0056bcebcdcece385cece4ff" [[package]] name = "pin-utils" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] name = "pkg-config" version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "953ec861398dccce10c670dfeaf3ec4911ca479e9c02154b3a215178c5f566f2" [[package]] name = "powerfmt" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" [[package]] name = "ppv-lite86" version = "0.2.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04" dependencies = [ "zerocopy", ] [[package]] name = "proc-macro2" version = "1.0.92" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "37d3544b3f2748c54e147655edb5025752e2303145b5aefb3c3ea2c78b973bb0" dependencies = [ "unicode-ident", ] [[package]] name = "quick-error" version = "1.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" [[package]] name = "quinn" version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8cc2c5017e4b43d5995dcea317bc46c1e09404c0a9664d2908f7f02dfe943d75" dependencies = [ "bytes", "futures-io", "pin-project-lite", "quinn-proto", "quinn-udp", "rustc-hash", "rustls", "thiserror", "tokio", "tracing", ] [[package]] name = "quinn-proto" version = "0.10.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "141bf7dfde2fbc246bfd3fe12f2455aa24b0fbd9af535d8c86c7bd1381ff2b1a" dependencies = [ "bytes", "rand", "ring 0.16.20", "rustc-hash", "rustls", "slab", "thiserror", "tinyvec", "tracing", ] [[package]] name = "quinn-udp" version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "055b4e778e8feb9f93c4e439f71dc2156ef13360b432b799e179a8c4cdf0b1d7" dependencies = [ "bytes", "libc", "socket2", "tracing", "windows-sys 0.48.0", ] [[package]] name = "quote" version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" dependencies = [ "proc-macro2", ] [[package]] name = "radix_trie" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c069c179fcdc6a2fe24d8d18305cf085fdbd4f922c041943e203685d6a1c58fd" dependencies = [ "endian-type", "nibble_vec", ] [[package]] name = "rand" version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" dependencies = [ "libc", "rand_chacha", "rand_core", ] [[package]] name = "rand_chacha" version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" dependencies = [ "ppv-lite86", "rand_core", ] [[package]] name = "rand_core" version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" dependencies = [ "getrandom", ] [[package]] name = "redox_syscall" version = "0.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b6dfecf2c74bce2466cabf93f6664d6998a69eb21e39f4207930065b27b771f" dependencies = [ "bitflags", ] [[package]] name = "regex" version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" dependencies = [ "aho-corasick", "memchr", "regex-automata 0.4.9", "regex-syntax 0.8.5", ] [[package]] name = "regex-automata" version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" dependencies = [ "regex-syntax 0.6.29", ] [[package]] name = "regex-automata" version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908" dependencies = [ "aho-corasick", "memchr", "regex-syntax 0.8.5", ] [[package]] name = "regex-syntax" version = "0.6.29" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" [[package]] name = "regex-syntax" version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" [[package]] name = "resolv-conf" version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "52e44394d2086d010551b14b53b1f24e31647570cd1deb0379e2c21b329aba00" dependencies = [ "hostname", "quick-error", ] [[package]] name = "ring" version = "0.16.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc" dependencies = [ "cc", "libc", "once_cell", "spin 0.5.2", "untrusted 0.7.1", "web-sys", "winapi", ] [[package]] name = "ring" version = "0.17.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c17fa4cb658e3583423e915b9f3acc01cceaee1860e33d59ebae66adc3a2dc0d" dependencies = [ "cc", "cfg-if", "getrandom", "libc", "spin 0.9.8", "untrusted 0.9.0", "windows-sys 0.52.0", ] [[package]] name = "rusqlite" version = "0.31.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b838eba278d213a8beaf485bd313fd580ca4505a00d5871caeb1457c55322cae" dependencies = [ "bitflags", "fallible-iterator", "fallible-streaming-iterator", "hashlink", "libsqlite3-sys", "smallvec", "time", ] [[package]] name = "rustc-demangle" version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" [[package]] name = "rustc-hash" version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" [[package]] name = "rustix" version = "0.38.42" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f93dc38ecbab2eb790ff964bb77fa94faf256fd3e73285fd7ba0903b76bedb85" dependencies = [ "bitflags", "errno", "libc", "linux-raw-sys", "windows-sys 0.59.0", ] [[package]] name = "rustls" version = "0.21.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f56a14d1f48b391359b22f731fd4bd7e43c97f3c50eee276f3aa09c94784d3e" dependencies = [ "log", "ring 0.17.8", "rustls-webpki", "sct", ] [[package]] name = "rustls-native-certs" version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a9aace74cb666635c918e9c12bc0d348266037aa8eb599b5cba565709a8dff00" dependencies = [ "openssl-probe", "rustls-pemfile", "schannel", "security-framework", ] [[package]] name = "rustls-pemfile" version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c" dependencies = [ "base64", ] [[package]] name = "rustls-webpki" version = "0.101.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765" dependencies = [ "ring 0.17.8", "untrusted 0.9.0", ] [[package]] name = "schannel" version = "0.1.27" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1f29ebaa345f945cec9fbbc532eb307f0fdad8161f281b6369539c8d84876b3d" dependencies = [ "windows-sys 0.59.0", ] [[package]] name = "scopeguard" version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[package]] name = "sct" version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414" dependencies = [ "ring 0.17.8", "untrusted 0.9.0", ] [[package]] name = "security-framework" version = "2.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02" dependencies = [ "bitflags", "core-foundation", "core-foundation-sys", "libc", "security-framework-sys", ] [[package]] name = "security-framework-sys" version = "2.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fa39c7303dc58b5543c94d22c1766b0d31f2ee58306363ea622b10bbc075eaa2" dependencies = [ "core-foundation-sys", "libc", ] [[package]] name = "serde" version = "1.0.215" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6513c1ad0b11a9376da888e3e0baa0077f1aed55c17f50e7b2397136129fb88f" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" version = "1.0.215" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ad1e866f866923f252f05c889987993144fb74e722403468a4ebd70c3cd756c0" dependencies = [ "proc-macro2", "quote", "syn", ] [[package]] name = "sharded-slab" version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" dependencies = [ "lazy_static", ] [[package]] name = "shlex" version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" [[package]] name = "slab" version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" dependencies = [ "autocfg", ] [[package]] name = "smallvec" version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "socket2" version = "0.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c970269d99b64e60ec3bd6ad27270092a5394c4e309314b18ae3fe575695fbe8" dependencies = [ "libc", "windows-sys 0.52.0", ] [[package]] name = "spin" version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" [[package]] name = "spin" version = "0.9.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" [[package]] name = "stable_deref_trait" version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" [[package]] name = "strsim" version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" [[package]] name = "syn" version = "2.0.90" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "919d3b74a5dd0ccd15aeb8f93e7006bd9e14c295087c9896a110f490752bcf31" dependencies = [ "proc-macro2", "quote", "unicode-ident", ] [[package]] name = "synstructure" version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" dependencies = [ "proc-macro2", "quote", "syn", ] [[package]] name = "tempfile" version = "3.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "28cce251fcbc87fac86a866eeb0d6c2d536fc16d06f184bb61aeae11aa4cee0c" dependencies = [ "cfg-if", "fastrand", "once_cell", "rustix", "windows-sys 0.59.0", ] [[package]] name = "thiserror" version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote", "syn", ] [[package]] name = "thread_local" version = "1.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c" dependencies = [ "cfg-if", "once_cell", ] [[package]] name = "time" version = "0.3.37" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "35e7868883861bd0e56d9ac6efcaaca0d6d5d82a2a7ec8209ff492c07cf37b21" dependencies = [ "deranged", "itoa", "num-conv", "powerfmt", "serde", "time-core", "time-macros", ] [[package]] name = "time-core" version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" [[package]] name = "time-macros" version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2834e6017e3e5e4b9834939793b282bc03b37a3336245fa820e35e233e2a85de" dependencies = [ "num-conv", "time-core", ] [[package]] name = "tinystr" version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9117f5d4db391c1cf6927e7bea3db74b9a1c1add8f7eda9ffd5364f40f57b82f" dependencies = [ "displaydoc", "zerovec", ] [[package]] name = "tinyvec" version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "445e881f4f6d382d5f27c034e25eb92edd7c784ceab92a0937db7f2e9471b938" dependencies = [ "tinyvec_macros", ] [[package]] name = "tinyvec_macros" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" version = "1.42.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5cec9b21b0450273377fc97bd4c33a8acffc8c996c987a7c5b319a0083707551" dependencies = [ "backtrace", "bytes", "libc", "mio", "pin-project-lite", "socket2", "tokio-macros", "windows-sys 0.52.0", ] [[package]] name = "tokio-macros" version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752" dependencies = [ "proc-macro2", "quote", "syn", ] [[package]] name = "tokio-native-tls" version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2" dependencies = [ "native-tls", "tokio", ] [[package]] name = "tokio-openssl" version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "59df6849caa43bb7567f9a36f863c447d95a11d5903c9cc334ba32576a27eadd" dependencies = [ "openssl", "openssl-sys", "tokio", ] [[package]] name = "tokio-rustls" version = "0.24.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" dependencies = [ "rustls", "tokio", ] [[package]] name = "tokio-util" version = "0.7.13" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d7fcaa8d55a2bdd6b83ace262b016eca0d79ee02818c5c1bcdf0305114081078" dependencies = [ "bytes", "futures-core", "futures-sink", "pin-project-lite", "tokio", ] [[package]] name = "tracing" version = "0.1.41" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0" dependencies = [ "log", "pin-project-lite", "tracing-attributes", "tracing-core", ] [[package]] name = "tracing-attributes" version = "0.1.28" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "395ae124c09f9e6918a2310af6038fba074bcf474ac352496d5910dd59a2226d" dependencies = [ "proc-macro2", "quote", "syn", ] [[package]] name = "tracing-core" version = "0.1.33" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e672c95779cf947c5311f83787af4fa8fffd12fb27e4993211a84bdfd9610f9c" dependencies = [ "once_cell", "valuable", ] [[package]] name = "tracing-log" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3" dependencies = [ "log", "once_cell", "tracing-core", ] [[package]] name = "tracing-subscriber" version = "0.3.19" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e8189decb5ac0fa7bc8b96b7cb9b2701d60d48805aca84a238004d665fcc4008" dependencies = [ "matchers", "nu-ansi-term", "once_cell", "regex", "sharded-slab", "smallvec", "thread_local", "tracing", "tracing-core", "tracing-log", ] [[package]] name = "unicode-ident" version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83" [[package]] name = "untrusted" version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" [[package]] name = "untrusted" version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" [[package]] name = "url" version = "2.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32f8b686cadd1473f4bd0117a5d28d36b1ade384ea9b5069a1c40aefed7fda60" dependencies = [ "form_urlencoded", "idna", "percent-encoding", "serde", ] [[package]] name = "utf16_iter" version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c8232dd3cdaed5356e0f716d285e4b40b932ac434100fe9b7e0e8e935b9e6246" [[package]] name = "utf8_iter" version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" [[package]] name = "valuable" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" [[package]] name = "vcpkg" version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" [[package]] name = "version_check" version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" [[package]] name = "wasi" version = "0.11.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" version = "0.2.99" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a474f6281d1d70c17ae7aa6a613c87fce69a127e2624002df63dcb39d6cf6396" dependencies = [ "cfg-if", "once_cell", "wasm-bindgen-macro", ] [[package]] name = "wasm-bindgen-backend" version = "0.2.99" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5f89bb38646b4f81674e8f5c3fb81b562be1fd936d84320f3264486418519c79" dependencies = [ "bumpalo", "log", "proc-macro2", "quote", "syn", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-macro" version = "0.2.99" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2cc6181fd9a7492eef6fef1f33961e3695e4579b9872a6f7c83aee556666d4fe" dependencies = [ "quote", "wasm-bindgen-macro-support", ] [[package]] name = "wasm-bindgen-macro-support" version = "0.2.99" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "30d7a95b763d3c45903ed6c81f156801839e5ee968bb07e534c44df0fcd330c2" dependencies = [ "proc-macro2", "quote", "syn", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" version = "0.2.99" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "943aab3fdaaa029a6e0271b35ea10b72b943135afe9bffca82384098ad0e06a6" [[package]] name = "web-sys" version = "0.3.76" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "04dd7223427d52553d3702c004d3b2fe07c148165faa56313cb00211e31c12bc" dependencies = [ "js-sys", "wasm-bindgen", ] [[package]] name = "webpki-roots" version = "0.25.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5f20c57d8d7db6d3b86154206ae5d8fba62dd39573114de97c2cb0578251f8e1" [[package]] name = "widestring" version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7219d36b6eac893fa81e84ebe06485e7dcbb616177469b142df14f1f4deb1311" [[package]] name = "winapi" version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" dependencies = [ "winapi-i686-pc-windows-gnu", "winapi-x86_64-pc-windows-gnu", ] [[package]] name = "winapi-i686-pc-windows-gnu" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" [[package]] name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] name = "windows-sys" version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" dependencies = [ "windows-targets 0.48.5", ] [[package]] name = "windows-sys" version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [ "windows-targets 0.52.6", ] [[package]] name = "windows-sys" version = "0.59.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" dependencies = [ "windows-targets 0.52.6", ] [[package]] name = "windows-targets" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" dependencies = [ "windows_aarch64_gnullvm 0.48.5", "windows_aarch64_msvc 0.48.5", "windows_i686_gnu 0.48.5", "windows_i686_msvc 0.48.5", "windows_x86_64_gnu 0.48.5", "windows_x86_64_gnullvm 0.48.5", "windows_x86_64_msvc 0.48.5", ] [[package]] name = "windows-targets" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" dependencies = [ "windows_aarch64_gnullvm 0.52.6", "windows_aarch64_msvc 0.52.6", "windows_i686_gnu 0.52.6", "windows_i686_gnullvm", "windows_i686_msvc 0.52.6", "windows_x86_64_gnu 0.52.6", "windows_x86_64_gnullvm 0.52.6", "windows_x86_64_msvc 0.52.6", ] [[package]] name = "windows_aarch64_gnullvm" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" [[package]] name = "windows_aarch64_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" [[package]] name = "windows_aarch64_msvc" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" [[package]] name = "windows_aarch64_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" [[package]] name = "windows_i686_gnu" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" [[package]] name = "windows_i686_gnu" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" [[package]] name = "windows_i686_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" [[package]] name = "windows_i686_msvc" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" [[package]] name = "windows_i686_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" [[package]] name = "windows_x86_64_gnu" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" [[package]] name = "windows_x86_64_gnu" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" [[package]] name = "windows_x86_64_gnullvm" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" [[package]] name = "windows_x86_64_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" [[package]] name = "windows_x86_64_msvc" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" [[package]] name = "windows_x86_64_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] name = "winreg" version = "0.50.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1" dependencies = [ "cfg-if", "windows-sys 0.48.0", ] [[package]] name = "write16" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d1890f4022759daae28ed4fe62859b1236caebfc61ede2f63ed4e695f3f6d936" [[package]] name = "writeable" version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e9df38ee2d2c3c5948ea468a8406ff0db0b29ae1ffde1bcf20ef305bcc95c51" [[package]] name = "yoke" version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "120e6aef9aa629e3d4f52dc8cc43a015c7724194c97dfaf45180d2daf2b77f40" dependencies = [ "serde", "stable_deref_trait", "yoke-derive", "zerofrom", ] [[package]] name = "yoke-derive" version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2380878cad4ac9aac1e2435f3eb4020e8374b5f13c296cb75b4620ff8e229154" dependencies = [ "proc-macro2", "quote", "syn", "synstructure", ] [[package]] name = "zerocopy" version = "0.7.35" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" dependencies = [ "byteorder", "zerocopy-derive", ] [[package]] name = "zerocopy-derive" version = "0.7.35" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" dependencies = [ "proc-macro2", "quote", "syn", ] [[package]] name = "zerofrom" version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cff3ee08c995dee1859d998dea82f7374f2826091dd9cd47def953cae446cd2e" dependencies = [ "zerofrom-derive", ] [[package]] name = "zerofrom-derive" version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "595eed982f7d355beb85837f651fa22e90b3c044842dc7f2c2842c086f295808" dependencies = [ "proc-macro2", "quote", "syn", "synstructure", ] [[package]] name = "zerovec" version = "0.10.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "aa2b893d79df23bfb12d5461018d408ea19dfafe76c2c7ef6d4eba614f8ff079" dependencies = [ "yoke", "zerofrom", "zerovec-derive", ] [[package]] name = "zerovec-derive" version = "0.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6eafa6dfb17584ea3e2bd6e76e0cc15ad7af12b09abdd1ca55961bed9b1063c6" dependencies = [ "proc-macro2", "quote", "syn", ] hickory-dns-0.24.4/Cargo.toml0000644000000116140000000000100113560ustar # THIS FILE IS AUTOMATICALLY GENERATED BY CARGO # # When uploading crates to the registry Cargo will automatically # "normalize" Cargo.toml files for maximal compatibility # with all versions of Cargo and also rewrite `path` dependencies # to registry (e.g., crates.io) dependencies. # # If you are reading this file be aware that the original Cargo.toml # will likely look very different (and much more reasonable). # See Cargo.toml.orig for the original contents. [package] edition = "2021" rust-version = "1.71.1" name = "hickory-dns" version = "0.24.4" authors = ["The contributors to Hickory DNS"] build = false autolib = false autobins = false autoexamples = false autotests = false autobenches = false description = """ Hickory DNS is a safe and secure DNS server with DNSSEC support. Eventually this could be a replacement for BIND9. The DNSSEC support allows for live signing of all records, in it does not currently support records signed offline. The server supports dynamic DNS with SIG0 authenticated requests. Hickory DNS is based on the Tokio and Futures libraries, which means it should be easily integrated into other software that also use those libraries. """ homepage = "https://hickory-dns.org/" documentation = "https://docs.rs/hickory-dns" readme = "README.md" keywords = [ "DNS", "BIND", "dig", "named", "dnssec", ] categories = ["network-programming"] license = "MIT OR Apache-2.0" repository = "https://github.com/hickory-dns/hickory-dns" [[bin]] name = "hickory-dns" path = "src/hickory-dns.rs" [[test]] name = "named_https_tests" path = "tests/named_https_tests.rs" [[test]] name = "named_openssl_tests" path = "tests/named_openssl_tests.rs" [[test]] name = "named_quic_tests" path = "tests/named_quic_tests.rs" [[test]] name = "named_rustls_tests" path = "tests/named_rustls_tests.rs" [[test]] name = "named_test_rsa_dnssec" path = "tests/named_test_rsa_dnssec.rs" [[test]] name = "named_tests" path = "tests/named_tests.rs" [[bench]] name = "comparison_benches" path = "benches/comparison_benches.rs" [dependencies.clap] version = "4.0" features = [ "std", "cargo", "help", "derive", "suggestions", ] default-features = false [dependencies.futures-util] version = "0.3.5" features = ["std"] default-features = false [dependencies.hickory-client] version = "0.24.0" default-features = false [dependencies.hickory-proto] version = "0.24.0" default-features = false [dependencies.hickory-server] version = "0.24.0" features = ["toml"] default-features = false [dependencies.rustls] version = "0.21.6" optional = true [dependencies.time] version = "0.3" [dependencies.tokio] version = "1.21" features = [ "time", "rt", ] [dependencies.tracing] version = "0.1.30" [dependencies.tracing-subscriber] version = "0.3" features = [ "std", "fmt", "env-filter", ] [dev-dependencies.hickory-proto] version = "0.24.0" features = [ "testing", "dns-over-native-tls", ] default-features = false [dev-dependencies.hickory-resolver] version = "0.24.0" default-features = false [dev-dependencies.native-tls] version = "0.2" [dev-dependencies.regex] version = "1.3.4" [dev-dependencies.webpki-roots] version = "0.25.0" [features] ascii-art = [] default = [ "sqlite", "resolver", "native-certs", "ascii-art", ] dns-over-h3 = [ "dns-over-rustls", "hickory-server/dns-over-h3", ] dns-over-https = ["hickory-server/dns-over-https"] dns-over-https-rustls = [ "dns-over-https", "dns-over-rustls", "hickory-proto/dns-over-https-rustls", "hickory-client/dns-over-https-rustls", "hickory-server/dns-over-https-rustls", ] dns-over-openssl = [ "dns-over-tls", "dnssec-openssl", "hickory-proto/dns-over-openssl", "hickory-client/dns-over-openssl", "hickory-server/dns-over-openssl", ] dns-over-quic = [ "dns-over-rustls", "hickory-server/dns-over-quic", ] dns-over-rustls = [ "dns-over-tls", "dnssec-ring", "rustls", "hickory-proto/dns-over-rustls", "hickory-client/dns-over-rustls", "hickory-server/dns-over-rustls", ] dns-over-tls = [] dnssec = [] dnssec-openssl = [ "dnssec", "hickory-client/dnssec-openssl", "hickory-proto/dnssec-openssl", "hickory-server/dnssec-openssl", ] dnssec-ring = [ "dnssec", "hickory-client/dnssec-ring", "hickory-proto/dnssec-ring", "hickory-server/dnssec-ring", ] native-certs = [ "hickory-client/native-certs", "hickory-server/native-certs", ] recursor = ["hickory-server/recursor"] resolver = ["hickory-server/resolver"] sqlite = ["hickory-server/sqlite"] tls = ["dns-over-openssl"] tls-openssl = ["dns-over-openssl"] webpki-roots = [ "hickory-client/webpki-roots", "hickory-server/webpki-roots", ] [badges.codecov] branch = "main" repository = "hickory-dns/hickory-dns" service = "github" [badges.maintenance] status = "actively-developed" [lints.rust.unexpected_cfgs] level = "warn" priority = 0 check-cfg = ["cfg(nightly)"] hickory-dns-0.24.4/Cargo.toml.orig000064400000000000000000000100741046102023000150360ustar 00000000000000[package] name = "hickory-dns" # A short blurb about the package. This is not rendered in any format when # uploaded to crates.io (aka this is not markdown) description = """ Hickory DNS is a safe and secure DNS server with DNSSEC support. Eventually this could be a replacement for BIND9. The DNSSEC support allows for live signing of all records, in it does not currently support records signed offline. The server supports dynamic DNS with SIG0 authenticated requests. Hickory DNS is based on the Tokio and Futures libraries, which means it should be easily integrated into other software that also use those libraries. """ documentation = "https://docs.rs/hickory-dns" readme = "README.md" version.workspace = true authors.workspace = true edition.workspace = true rust-version.workspace = true homepage.workspace = true repository.workspace = true keywords.workspace = true categories.workspace = true license.workspace = true [badges] #github-actions = { repository = "bluejekyll/hickory", branch = "main", workflow = "test" } codecov = { repository = "hickory-dns/hickory-dns", branch = "main", service = "github" } maintenance = { status = "actively-developed" } [features] default = ["sqlite", "resolver", "native-certs", "ascii-art"] # if enabled, the hickory-dns binary will print ascii-art on start, disable to reduce the binary size ascii-art = [] dnssec-openssl = [ "dnssec", "hickory-client/dnssec-openssl", "hickory-proto/dnssec-openssl", "hickory-server/dnssec-openssl", ] dnssec-ring = [ "dnssec", "hickory-client/dnssec-ring", "hickory-proto/dnssec-ring", "hickory-server/dnssec-ring", ] dnssec = [] recursor = ["hickory-server/recursor"] # Recursive Resolution is Experimental! resolver = ["hickory-server/resolver"] sqlite = ["hickory-server/sqlite"] # TODO: Need to figure out how to be consistent with ring/openssl usage... # dns-over-https-openssl = ["dns-over-openssl", "hickory-client/dns-over-https-openssl", "dns-over-https"] dns-over-https-rustls = [ "dns-over-https", "dns-over-rustls", "hickory-proto/dns-over-https-rustls", "hickory-client/dns-over-https-rustls", "hickory-server/dns-over-https-rustls", ] dns-over-https = ["hickory-server/dns-over-https"] dns-over-quic = ["dns-over-rustls", "hickory-server/dns-over-quic"] dns-over-h3 = ["dns-over-rustls", "hickory-server/dns-over-h3"] # TODO: migrate all tls and tls-openssl features to dns-over-tls, et al dns-over-openssl = [ "dns-over-tls", "dnssec-openssl", "hickory-proto/dns-over-openssl", "hickory-client/dns-over-openssl", "hickory-server/dns-over-openssl", ] dns-over-rustls = [ "dns-over-tls", "dnssec-ring", "rustls", "hickory-proto/dns-over-rustls", "hickory-client/dns-over-rustls", "hickory-server/dns-over-rustls", ] dns-over-tls = [] # This is a deprecated feature... tls-openssl = ["dns-over-openssl"] tls = ["dns-over-openssl"] webpki-roots = ["hickory-client/webpki-roots", "hickory-server/webpki-roots"] native-certs = ["hickory-client/native-certs", "hickory-server/native-certs"] [[bin]] name = "hickory-dns" path = "src/hickory-dns.rs" [dependencies] # clap features: # - suggestion for advanced help with error in cli # - derive for clap derive api # - help to generate --help clap = { workspace = true, default-features = false, features = [ "std", "cargo", "help", "derive", "suggestions", ] } futures-util = { workspace = true, default-features = false, features = [ "std", ] } rustls = { workspace = true, optional = true } time.workspace = true tracing.workspace = true tracing-subscriber = { workspace = true, features = [ "std", "fmt", "env-filter", ] } tokio = { workspace = true, features = ["time", "rt"] } hickory-client.workspace = true hickory-proto.workspace = true hickory-server = { workspace = true, features = ["toml"] } [dev-dependencies] native-tls.workspace = true regex.workspace = true hickory-proto = { workspace = true, features = [ "testing", "dns-over-native-tls", ] } hickory-resolver.workspace = true webpki-roots.workspace = true [lints] workspace = true hickory-dns-0.24.4/LICENSE-APACHE000064400000000000000000000261401046102023000140740ustar 00000000000000 Apache License Version 2.0, January 2004 https://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "{}" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright {yyyy} {name of copyright owner} Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at https://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. hickory-dns-0.24.4/LICENSE-MIT000064400000000000000000000021151046102023000136000ustar 00000000000000Copyright (c) 2015 The Hickory DNS Developers Copyright (c) 2017 Google LLC. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. hickory-dns-0.24.4/README.md000064400000000000000000000076661046102023000134430ustar 00000000000000# Overview Hickory DNS provides a binary for hosting or forwarding DNS zones. This a named implementation for DNS zone hosting. It is capable of performing signing all records in the zone for server DNSSEC RRSIG records associated with all records in a zone. There is also a `hickory-dns` binary that can be generated from the library with `cargo install hickory-dns`. Dynamic updates are supported via `SIG0` (an mTLS authentication method is under development). **NOTICE** This project was rebranded fromt Trust-DNS to Hickory DNS and has been moved to the https://github.com/hickory-dns/hickory-dns organization and repo, this crate/binary has been moved to [hickory-dns](https://crates.io/crates/hickory-dns), from `0.24` and onward, for prior versions see [trust-dns](https://crates.io/crates/trust-dns). ## Features - Dynamic Update with sqlite journaling backend (SIG0) - DNSSEC online signing (NSEC not NSEC3) - DNS over TLS (DoT) - DNS over HTTPS/2 (DoH) - DNS over HTTPS/3 (DoH3) - DNS over Quic (DoQ) - Forwarding stub resolver - ANAME resolution, for zone mapping aliass to A and AAAA records - Additionals section generation for aliasing record types ## DNS-over-TLS and DNS-over-HTTPS Support of TLS on the Server is managed through a pkcs12 der file. The documentation is captured in the example test config file, [example.toml](https://github.com/hickory-dns/hickory-dns/blob/main/tests/test-data/test_configs/example.toml). A registered certificate to the server can be pinned to the Client with the `add_ca()` method. Alternatively, as the client uses the rust-native-tls library, it should work with certificate signed by any standard CA. DoT and DoH are supported. This is accomplished through the use of one of `native-tls`, `openssl`, or `rustls` (only `rustls` is currently supported for DoH). The Resolver requires only requires valid DoT or DoH resolvers being registered in order to be used. To use with the `Client`, the `TlsClientConnection` or `HttpsClientConnection` should be used. Similarly, to use with the tokio `AsyncClient` the `TlsClientStream` or `HttpsClientStream` should be used. ClientAuth, mTLS, is currently not supported, there are some issues still being worked on. TLS is useful for Server authentication and connection privacy. To enable DoT one of the features `dns-over-native-tls`, `dns-over-openssl`, or `dns-over-rustls` must be enabled, `dns-over-https-rustls` is used for DoH. ## DNSSEC status Currently the root key is hardcoded into the system. This gives validation of DNSKEY and DS records back to the root. NSEC is implemented, but not NSEC3. Because caching is not yet enabled, it has been noticed that some DNS servers appear to rate limit the connections, validating RRSIG records back to the root can require a significant number of additional queries for those records. Zones will be automatically resigned on any record updates via dynamic DNS. To enable DNSSEC, one of the features `dnssec-openssl` or `dnssec-ring` must be enabled. ## Future goals - Distributed dynamic DNS updates, with consensus - mTLS based authorization for Dynamic Updates - Online NSEC creation for queries - Full hint based resolving - Maybe NSEC3 and/or NSEC5 support ## Minimum Rust Version The current minimum rustc version for this project is `1.67` ## Versioning Hickory DNS does it's best job to follow semver. Hickory DNS will be promoted to 1.0 upon stabilization of the publicly exposed APIs. This does not mean that Hickory DNS will necessarily break on upgrades between 0.x updates. Whenever possible, old APIs will be deprecated with notes on what replaced those deprecations. Hickory DNS will make a best effort to never break software which depends on it due to API changes, though this can not be guaranteed. Deprecated interfaces will be maintained for at minimum one major release after that in which they were deprecated (where possible), with the exception of the upgrade to 1.0 where all deprecated interfaces will be planned to be removed. hickory-dns-0.24.4/benches/bind_conf/example.conf000064400000000000000000000017611046102023000200040ustar 00000000000000/* Hickory DNS bench setup: this is meant to mimic the hickory-server config which is in tests/test-data/test_configs/example.toml */ controls { /* empty */ }; options { pid-file "/tmp/named.pid"; listen-on { 127.0.0.1; }; listen-on-v6 { none; }; recursion no; }; zone "localhost" { type primary; file "../../../tests/test-data/test_configs/default/localhost.zone"; }; zone "0.0.127.in-addr.arpa" { type primary; file "../../../tests/test-data/test_configs/default/127.0.0.1.zone"; }; zone "0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa" { type primary; file "../../../tests/test-data/test_configs/default/ipv6_1.zone"; }; zone "255.in-addr.arpa" { type primary; file "../../../tests/test-data/test_configs/default/255.zone"; }; zone "0.in-addr.arpa" { type primary; file "../../../tests/test-data/test_configs/default/0.zone"; }; zone "example.com" { type primary; file "../../../tests/test-data/test_configs/example.com.zone"; }; hickory-dns-0.24.4/benches/comparison_benches.rs000064400000000000000000000170111046102023000177630ustar 00000000000000#![cfg(nightly)] #![feature(test)] extern crate test; use std::env; use std::fs::{DirBuilder, File}; use std::mem; use std::net::{Ipv4Addr, SocketAddr, ToSocketAddrs}; use std::path::Path; use std::process::{Child, Command, Stdio}; use std::str::FromStr; use std::sync::Arc; use std::thread; use std::time::Duration; use futures::Future; use test::Bencher; use tokio::net::TcpStream; use tokio::net::UdpSocket; use tokio::runtime::Runtime; use hickory_client::client::*; use hickory_client::op::*; use hickory_client::rr::*; use hickory_client::tcp::*; use hickory_client::udp::*; use hickory_proto::error::*; use hickory_proto::iocompat::AsyncIoTokioAsStd; use hickory_proto::op::NoopMessageFinalizer; use hickory_proto::xfer::*; fn find_test_port() -> u16 { let server = std::net::UdpSocket::bind(("0.0.0.0", 0)).unwrap(); let server_addr = server.local_addr().unwrap(); server_addr.port() } struct NamedProcess { named: Child, } impl Drop for NamedProcess { fn drop(&mut self) { self.named.kill().expect("could not kill process"); self.named.wait().expect("waiting failed"); } } fn wrap_process(named: Child, server_port: u16) -> NamedProcess { let mut started = false; for _ in 0..20 { let io_loop = Runtime::new().unwrap(); let addr: SocketAddr = ("127.0.0.1", server_port) .to_socket_addrs() .unwrap() .next() .unwrap(); let stream = UdpClientStream::::new(addr); let client = AsyncClient::connect(stream); let (mut client, bg) = io_loop.block_on(client).expect("failed to create client"); io_loop.spawn(bg); let name = domain::Name::from_str("www.example.com.").unwrap(); let response = io_loop.block_on(client.query(name.clone(), DNSClass::IN, RecordType::A)); if response.is_ok() { started = true; break; } else { // wait for the server to start thread::sleep(Duration::from_millis(500)); } } assert!(started, "server did not startup..."); // return handle to child process NamedProcess { named } } /// Returns a NamedProcess (cleans the process up on drop), and a socket addr for connecting /// to the server. fn hickory_process() -> (NamedProcess, u16) { // find a random port to listen on let test_port = find_test_port(); let ws_root = env::var("WORKSPACE_ROOT").unwrap_or_else(|_| "..".to_owned()); let named_path = env!("CARGO_BIN_EXE_hickory-dns"); let config_path = format!("{}/tests/test-data/test_configs/example.toml", ws_root); let zone_dir = format!("{}/tests/test-data/test_configs", ws_root); File::open(&named_path).expect(&named_path); File::open(&config_path).expect(&config_path); File::open(&zone_dir).expect(&zone_dir); let named = Command::new(&named_path) .stdout(Stdio::null()) .arg("-q") // TODO: need to rethink this one... .arg(&format!("--config={}", config_path)) .arg(&format!("--zonedir={}", zone_dir)) .arg(&format!("--port={}", test_port)) .spawn() .expect("failed to start hickory-dns"); // let process = wrap_process(named, test_port); // return handle to child process (process, test_port) } /// Runs the bench tesk using the specified client fn bench(b: &mut Bencher, stream: F) where F: Future> + 'static + Send + Unpin, S: DnsRequestSender, { let io_loop = Runtime::new().unwrap(); let client = AsyncClient::connect(stream); let (mut client, bg) = io_loop.block_on(client).expect("failed to create client"); io_loop.spawn(bg); let name = domain::Name::from_str("www.example.com.").unwrap(); // validate the request let query = client.query(name.clone(), DNSClass::IN, RecordType::A); let response = io_loop.block_on(query).expect("Request failed"); assert_eq!(response.response_code(), ResponseCode::NoError); let record = &response.answers()[0]; if let Some(RData::A(ref address)) = record.data() { assert_eq!(address, &Ipv4Addr::new(127, 0, 0, 1)); } else { unreachable!(); } b.iter(|| { let response = io_loop.block_on(client.query(name.clone(), DNSClass::IN, RecordType::A)); response.unwrap(); }); } #[bench] fn hickory_udp_bench(b: &mut Bencher) { let (named, server_port) = hickory_process(); let addr: SocketAddr = ("127.0.0.1", server_port) .to_socket_addrs() .unwrap() .next() .unwrap(); let stream = UdpClientStream::::new(addr); bench(b, stream); // cleaning up the named process drop(named); } #[bench] #[ignore] fn hickory_udp_bench_prof(b: &mut Bencher) { let server_port = 6363; let addr: SocketAddr = ("127.0.0.1", server_port) .to_socket_addrs() .unwrap() .next() .unwrap(); let stream = UdpClientStream::::new(addr); bench(b, stream); } #[bench] fn hickory_tcp_bench(b: &mut Bencher) { let (named, server_port) = hickory_process(); let addr: SocketAddr = ("127.0.0.1", server_port) .to_socket_addrs() .unwrap() .next() .unwrap(); let (stream, sender) = TcpClientStream::>::new(addr); let mp = DnsMultiplexer::new(stream, sender, None::>); bench(b, mp); // cleaning up the named process drop(named); } // downloaded from https://www.isc.org/downloads/file/bind-9-11-0-p1/ // cd bind-9-11-0-p1 // .configure // make // export TDNS_BIND_PATH=${PWD}/bin/named/named fn bind_process() -> (NamedProcess, u16) { let test_port = find_test_port(); let bind_path = env::var("TDNS_BIND_PATH").unwrap_or_else(|_| "".to_owned()); let server_path = env::var("TDNS_WORKSPACE_ROOT").unwrap_or_else(|_| "..".to_owned()); let bind_path = format!("{}/sbin/named", bind_path); // create the work directory let working_dir = format!("{}/../target/bind_pwd", server_path); if !Path::new(&working_dir).exists() { DirBuilder::new() .create(&working_dir) .expect("failed to create dir"); } let mut named = Command::new(bind_path) .current_dir(&working_dir) .stderr(Stdio::piped()) .arg("-c") .arg("../../server/benches/bind_conf/example.conf") //.arg("-d").arg("0") .arg("-D") .arg("Hickory DNS cmp bench") .arg("-g") .arg("-p") .arg(&format!("{}", test_port)) .spawn() .expect("failed to start named"); mem::replace(&mut named.stderr, None).unwrap(); let process = wrap_process(named, test_port); (process, test_port) } #[bench] #[ignore] fn bind_udp_bench(b: &mut Bencher) { let (named, server_port) = bind_process(); let addr: SocketAddr = ("127.0.0.1", server_port) .to_socket_addrs() .unwrap() .next() .unwrap(); let stream = UdpClientStream::::new(addr); bench(b, stream); // cleaning up the named process drop(named); } #[bench] #[ignore] fn bind_tcp_bench(b: &mut Bencher) { let (named, server_port) = bind_process(); let addr: SocketAddr = ("127.0.0.1", server_port) .to_socket_addrs() .unwrap() .next() .unwrap(); let (stream, sender) = TcpClientStream::>::new(addr); let mp = DnsMultiplexer::new(stream, sender, None::>); bench(b, mp); // cleaning up the named process drop(named); } hickory-dns-0.24.4/src/hickory-dns.ascii000064400000000000000000000065111046102023000162030ustar 00000000000000 ------ --------- +---------- ++++++------- ++++++++++++++ +++++++++++++++ +++++++++++++++ ++++++++++++++++ ++++++++++++++++ #### ++++++++++++++++ ######## ####++++++++++++ ########### ################ ############ ################ ############## ################ ############## ################ ############### ################ ###########++++ ################ ######++++++++++ ################ ++++++++++++++++ ############### ++++++++++++++++ ############### +++++++++++++++ ############## +++++++++----- ############# +++++-------- ++++++##### +---------- +++++++++ --------- +++++ ----- ## ### ### ### #### ### ### ### ### ### ### ### ### ### #### ########## ### #### ########## ####### #### #### ############### #### #### #### ### #### #### #### ### ### ### ### ### #### ### ####### #### #### ### ### ### ### ### #### ### ######## ### #### ### #### ### ### ### #### ### ### ### ### ### ### ### ####### ### ### #### ########## ### #### ########## ### ##### ### ### #### ###### ### #### ###### ### ### ### +++++ + + ++++ ####### ++ + +++ + ++ ##### ++ + + +++ ++ +++++ + + +++++ hickory-dns-0.24.4/src/hickory-dns.rs000064400000000000000000000637661046102023000155560ustar 00000000000000// Copyright 2015-2018 Benjamin Fry // // Licensed under the Apache License, Version 2.0, or the MIT license , at your option. This file may not be // copied, modified, or distributed except according to those terms. //! The `hickory-dns` binary for running a DNS server //! //! ```text //! Usage: hickory-dns [options] //! hickory-dns (-h | --help | --version) //! //! Options: //! -q, --quiet Disable INFO messages, WARN and ERROR will remain //! -d, --debug Turn on DEBUG messages (default is only INFO) //! -h, --help Show this message //! -v, --version Show the version of hickory-dns //! -c FILE, --config=FILE Path to configuration file, default is /etc/named.toml //! -z DIR, --zonedir=DIR Path to the root directory for all zone files, see also config toml //! -p PORT, --port=PORT Override the listening port //! --tls-port=PORT Override the listening port for TLS connections //! ``` // BINARY WARNINGS #![warn( clippy::dbg_macro, clippy::unimplemented, missing_copy_implementations, missing_docs, non_snake_case, non_upper_case_globals, rust_2018_idioms, unreachable_pub )] #![recursion_limit = "128"] #![allow(clippy::redundant_clone)] use std::{ env, fmt, net::{IpAddr, Ipv4Addr, SocketAddr, ToSocketAddrs}, path::{Path, PathBuf}, sync::Arc, }; use clap::Parser; use time::OffsetDateTime; use tokio::{ net::{TcpListener, UdpSocket}, runtime, }; use tracing::{debug, error, info, warn, Event, Subscriber}; use tracing_subscriber::{ fmt::{format, FmtContext, FormatEvent, FormatFields, FormattedFields}, layer::SubscriberExt, registry::LookupSpan, util::SubscriberInitExt, }; use hickory_client::rr::Name; #[cfg(feature = "dns-over-tls")] use hickory_server::config::dnssec::{self, TlsCertConfig}; #[cfg(feature = "resolver")] use hickory_server::store::forwarder::ForwardAuthority; #[cfg(feature = "recursor")] use hickory_server::store::recursor::RecursiveAuthority; #[cfg(feature = "sqlite")] use hickory_server::store::sqlite::{SqliteAuthority, SqliteConfig}; use hickory_server::{ authority::{AuthorityObject, Catalog, ZoneType}, config::{Config, ZoneConfig}, server::ServerFuture, store::{ file::{FileAuthority, FileConfig}, StoreConfig, }, }; #[cfg(feature = "dnssec")] use {hickory_client::rr::rdata::key::KeyUsage, hickory_server::authority::DnssecAuthority}; #[cfg(feature = "dnssec")] async fn load_keys( authority: &mut A, zone_name: Name, zone_config: &ZoneConfig, ) -> Result<(), String> where A: DnssecAuthority, L: Send + Sync + Sized + 'static, { if zone_config.is_dnssec_enabled() { for key_config in zone_config.get_keys() { info!( "adding key to zone: {:?}, is_zsk: {}, is_auth: {}", key_config.key_path(), key_config.is_zone_signing_key(), key_config.is_zone_update_auth() ); if key_config.is_zone_signing_key() { let zone_signer = key_config.try_into_signer(zone_name.clone()).map_err(|e| { format!("failed to load key: {:?} msg: {}", key_config.key_path(), e) })?; authority .add_zone_signing_key(zone_signer) .await .expect("failed to add zone signing key to authority"); } if key_config.is_zone_update_auth() { let update_auth_signer = key_config.try_into_signer(zone_name.clone()).map_err(|e| { format!("failed to load key: {:?} msg: {}", key_config.key_path(), e) })?; let public_key = update_auth_signer .key() .to_sig0key_with_usage(update_auth_signer.algorithm(), KeyUsage::Host) .expect("failed to get sig0 key"); authority .add_update_auth_key(zone_name.clone(), public_key) .await .expect("failed to add update auth key to authority"); } } info!("signing zone: {}", zone_config.get_zone()?); authority.secure_zone().await.expect("failed to sign zone"); } Ok(()) } #[cfg(not(feature = "dnssec"))] #[allow(clippy::unnecessary_wraps)] async fn load_keys( _authority: &mut T, _zone_name: Name, _zone_config: &ZoneConfig, ) -> Result<(), String> { Ok(()) } #[cfg_attr(not(feature = "dnssec"), allow(unused_mut, unused))] #[warn(clippy::wildcard_enum_match_arm)] // make sure all cases are handled despite of non_exhaustive async fn load_zone( zone_dir: &Path, zone_config: &ZoneConfig, ) -> Result, String> { debug!("loading zone with config: {:#?}", zone_config); let zone_name: Name = zone_config.get_zone().expect("bad zone name"); let zone_name_for_signer = zone_name.clone(); let zone_path: Option = zone_config.file.clone(); let zone_type: ZoneType = zone_config.get_zone_type(); let is_axfr_allowed = zone_config.is_axfr_allowed(); #[allow(unused_variables)] let is_dnssec_enabled = zone_config.is_dnssec_enabled(); if zone_config.is_update_allowed() { warn!("allow_update is deprecated in [[zones]] section, it belongs in [[zones.stores]]"); } // load the zone let authority: Box = match zone_config.stores { #[cfg(feature = "sqlite")] Some(StoreConfig::Sqlite(ref config)) => { if zone_path.is_some() { warn!("ignoring [[zones.file]] instead using [[zones.stores.zone_file_path]]"); } let mut authority = SqliteAuthority::try_from_config( zone_name, zone_type, is_axfr_allowed, is_dnssec_enabled, Some(zone_dir), config, ) .await?; // load any keys for the Zone, if it is a dynamic update zone, then keys are required load_keys(&mut authority, zone_name_for_signer, zone_config).await?; Box::new(Arc::new(authority)) as Box } Some(StoreConfig::File(ref config)) => { if zone_path.is_some() { warn!("ignoring [[zones.file]] instead using [[zones.stores.zone_file_path]]"); } let mut authority = FileAuthority::try_from_config( zone_name, zone_type, is_axfr_allowed, Some(zone_dir), config, )?; // load any keys for the Zone, if it is a dynamic update zone, then keys are required load_keys(&mut authority, zone_name_for_signer, zone_config).await?; Box::new(Arc::new(authority)) as Box } #[cfg(feature = "resolver")] Some(StoreConfig::Forward(ref config)) => { let forwarder = ForwardAuthority::try_from_config(zone_name, zone_type, config)?; Box::new(Arc::new(forwarder)) as Box } #[cfg(feature = "recursor")] Some(StoreConfig::Recursor(ref config)) => { let recursor = RecursiveAuthority::try_from_config(zone_name, zone_type, config, Some(zone_dir)); let authority = recursor.await?; Box::new(Arc::new(authority)) as Box } #[cfg(feature = "sqlite")] None if zone_config.is_update_allowed() => { warn!( "using deprecated SQLite load configuration, please move to [[zones.stores]] form" ); let zone_file_path = zone_path.ok_or("file is a necessary parameter of zone_config")?; let journal_file_path = PathBuf::from(zone_file_path.clone()) .with_extension("jrnl") .to_str() .map(String::from) .ok_or("non-unicode characters in file name")?; let config = SqliteConfig { zone_file_path, journal_file_path, allow_update: zone_config.is_update_allowed(), }; let mut authority = SqliteAuthority::try_from_config( zone_name, zone_type, is_axfr_allowed, is_dnssec_enabled, Some(zone_dir), &config, ) .await?; // load any keys for the Zone, if it is a dynamic update zone, then keys are required load_keys(&mut authority, zone_name_for_signer, zone_config).await?; Box::new(Arc::new(authority)) as Box } None => { let config = FileConfig { zone_file_path: zone_path.ok_or("file is a necessary parameter of zone_config")?, }; let mut authority = FileAuthority::try_from_config( zone_name, zone_type, is_axfr_allowed, Some(zone_dir), &config, )?; // load any keys for the Zone, if it is a dynamic update zone, then keys are required load_keys(&mut authority, zone_name_for_signer, zone_config).await?; Box::new(Arc::new(authority)) as Box } Some(_) => { panic!("unrecognized authority type, check enabled features"); } }; info!("zone successfully loaded: {}", zone_config.get_zone()?); Ok(authority) } /// Cli struct for all options managed with clap derive api. #[derive(Debug, Parser)] #[clap(name = "Hickory DNS named server", version, about)] struct Cli { /// Disable INFO messages, WARN and ERROR will remain #[clap(short = 'q', long = "quiet", conflicts_with = "debug")] pub(crate) quiet: bool, /// Turn on `DEBUG` messages (default is only `INFO`) #[clap(short = 'd', long = "debug", conflicts_with = "quiet")] pub(crate) debug: bool, /// Path to configuration file of named server, /// by default `/etc/named.toml` #[clap( short = 'c', long = "config", default_value = "/etc/named.toml", value_name = "NAME", value_hint=clap::ValueHint::FilePath, )] pub(crate) config: PathBuf, /// Path to the root directory for all zone files, /// see also config toml #[clap(short = 'z', long = "zonedir", value_name = "DIR", value_hint=clap::ValueHint::DirPath)] pub(crate) zonedir: Option, /// Listening port for DNS queries, /// overrides any value in config file #[clap(short = 'p', long = "port", value_name = "PORT")] pub(crate) port: Option, /// Listening port for DNS over TLS queries, /// overrides any value in config file #[clap(long = "tls-port", value_name = "TLS-PORT")] pub(crate) tls_port: Option, /// Listening port for DNS over HTTPS queries, /// overrides any value in config file #[clap(long = "https-port", value_name = "HTTPS-PORT")] pub(crate) https_port: Option, /// Listening port for DNS over QUIC queries, /// overrides any value in config file #[clap(long = "quic-port", value_name = "QUIC-PORT")] pub(crate) quic_port: Option, } /// Main method for running the named server. /// /// `Note`: Tries to avoid panics, in favor of always starting. #[allow(unused_mut)] fn main() { let args = Cli::parse(); // TODO: this should be set after loading config, but it's necessary for initial log lines, no? if args.quiet { quiet(); } else if args.debug { debug(); } else { default(); } info!("Hickory DNS {} starting", hickory_client::version()); // start up the server for listening let config = args.config.clone(); let config_path = Path::new(&config); info!("loading configuration from: {:?}", config_path); let config = Config::read_config(config_path) .unwrap_or_else(|e| panic!("could not read config {}: {:?}", config_path.display(), e)); let directory_config = config.get_directory().to_path_buf(); let zonedir = args.zonedir.clone(); let zone_dir: PathBuf = zonedir .as_ref() .map(PathBuf::from) .unwrap_or_else(|| directory_config.clone()); // TODO: allow for num threads configured... let mut runtime = runtime::Builder::new_multi_thread() .enable_all() .worker_threads(4) .thread_name("hickory-server-runtime") .build() .expect("failed to initialize Tokio Runtime"); let mut catalog: Catalog = Catalog::new(); // configure our server based on the config_path for zone in config.get_zones() { let zone_name = zone .get_zone() .unwrap_or_else(|_| panic!("bad zone name in {:?}", config_path)); match runtime.block_on(load_zone(&zone_dir, zone)) { Ok(authority) => catalog.upsert(zone_name.into(), authority), Err(error) => panic!("could not load zone {}: {}", zone_name, error), } } // TODO: support all the IPs asked to listen on... // TODO:, there should be the option to listen on any port, IP and protocol option... let v4addr = config .get_listen_addrs_ipv4() .expect("Error with parsing provided by configuration Ipv4"); let v6addr = config .get_listen_addrs_ipv6() .expect("Error with parsing provided by configuration Ipv6"); let mut listen_addrs: Vec = v4addr .into_iter() .map(IpAddr::V4) .chain(v6addr.into_iter().map(IpAddr::V6)) .collect(); let listen_port: u16 = args.port.unwrap_or_else(|| config.get_listen_port()); let tcp_request_timeout = config.get_tcp_request_timeout(); if listen_addrs.is_empty() { listen_addrs.push(IpAddr::V4(Ipv4Addr::new(0, 0, 0, 0))); } let sockaddrs: Vec = listen_addrs .iter() .flat_map(|x| (*x, listen_port).to_socket_addrs().unwrap()) .collect(); // now, run the server, based on the config #[cfg_attr(not(feature = "dns-over-tls"), allow(unused_mut))] let mut server = ServerFuture::new(catalog); // load all the listeners for udp_socket in &sockaddrs { info!("binding UDP to {:?}", udp_socket); let udp_socket = runtime .block_on(UdpSocket::bind(udp_socket)) .unwrap_or_else(|err| panic!("could not bind to UDP socket {udp_socket}: {err}")); info!( "listening for UDP on {:?}", udp_socket .local_addr() .expect("could not lookup local address") ); let _guard = runtime.enter(); server.register_socket(udp_socket); } // and TCP as necessary for tcp_listener in &sockaddrs { info!("binding TCP to {:?}", tcp_listener); let tcp_listener = runtime .block_on(TcpListener::bind(tcp_listener)) .unwrap_or_else(|_| panic!("could not bind to tcp: {}", tcp_listener)); info!( "listening for TCP on {:?}", tcp_listener .local_addr() .expect("could not lookup local address") ); let _guard = runtime.enter(); server.register_listener(tcp_listener, tcp_request_timeout); } let tls_cert_config = config.get_tls_cert(); // and TLS as necessary // TODO: we should add some more control from configs to enable/disable TLS/HTTPS/QUIC if let Some(_tls_cert_config) = tls_cert_config { // setup TLS listeners #[cfg(feature = "dns-over-tls")] config_tls( &args, &mut server, &config, _tls_cert_config, &zone_dir, &listen_addrs, &mut runtime, ); // setup HTTPS listeners #[cfg(feature = "dns-over-https")] config_https( &args, &mut server, &config, _tls_cert_config, &zone_dir, &listen_addrs, &mut runtime, ); // setup QUIC listeners #[cfg(feature = "dns-over-quic")] config_quic( &args, &mut server, &config, _tls_cert_config, &zone_dir, &listen_addrs, &mut runtime, ); } // config complete, starting! banner(); info!("awaiting connections..."); // TODO: how to do threads? should we do a bunch of listener threads and then query threads? // Ideally the processing would be n-threads for receiving, which hand off to m-threads for // request handling. It would generally be the case that n <= m. info!("Server starting up"); match runtime.block_on(server.block_until_done()) { Ok(()) => { // we're exiting for some reason... info!("Hickory DNS {} stopping", hickory_client::version()); } Err(e) => { let error_msg = format!( "Hickory DNS {} has encountered an error: {}", hickory_client::version(), e ); error!("{}", error_msg); panic!("{}", error_msg); } }; } #[cfg(feature = "dns-over-tls")] fn config_tls( args: &Cli, server: &mut ServerFuture, config: &Config, tls_cert_config: &TlsCertConfig, zone_dir: &Path, listen_addrs: &[IpAddr], runtime: &mut runtime::Runtime, ) { use futures_util::TryFutureExt; let tls_listen_port: u16 = args .tls_port .unwrap_or_else(|| config.get_tls_listen_port()); let tls_sockaddrs: Vec = listen_addrs .iter() .flat_map(|x| (*x, tls_listen_port).to_socket_addrs().unwrap()) .collect(); if tls_sockaddrs.is_empty() { warn!("a tls certificate was specified, but no TLS addresses configured to listen on"); } for tls_listener in &tls_sockaddrs { info!( "loading cert for DNS over TLS: {:?}", tls_cert_config.get_path() ); let tls_cert = dnssec::load_cert(zone_dir, tls_cert_config) .expect("error loading tls certificate file"); info!("binding TLS to {:?}", tls_listener); let tls_listener = runtime.block_on( TcpListener::bind(tls_listener) .unwrap_or_else(|_| panic!("could not bind to tls: {}", tls_listener)), ); info!( "listening for TLS on {:?}", tls_listener .local_addr() .expect("could not lookup local address") ); let _guard = runtime.enter(); server .register_tls_listener(tls_listener, config.get_tcp_request_timeout(), tls_cert) .expect("could not register TLS listener"); } } #[cfg(feature = "dns-over-https")] fn config_https( args: &Cli, server: &mut ServerFuture, config: &Config, tls_cert_config: &TlsCertConfig, zone_dir: &Path, listen_addrs: &[IpAddr], runtime: &mut runtime::Runtime, ) { use futures_util::TryFutureExt; let https_listen_port: u16 = args .https_port .unwrap_or_else(|| config.get_https_listen_port()); let https_sockaddrs: Vec = listen_addrs .iter() .flat_map(|x| (*x, https_listen_port).to_socket_addrs().unwrap()) .collect(); if https_sockaddrs.is_empty() { warn!("a tls certificate was specified, but no HTTPS addresses configured to listen on"); } for https_listener in &https_sockaddrs { if let Some(endpoint_name) = tls_cert_config.get_endpoint_name() { info!( "loading cert for DNS over TLS named {} from {:?}", endpoint_name, tls_cert_config.get_path() ); } else { info!( "loading cert for DNS over TLS from {:?}", tls_cert_config.get_path() ); } // TODO: see about modifying native_tls to impl Clone for Pkcs12 let tls_cert = dnssec::load_cert(zone_dir, tls_cert_config) .expect("error loading tls certificate file"); info!("binding HTTPS to {:?}", https_listener); let https_listener = runtime.block_on( TcpListener::bind(https_listener) .unwrap_or_else(|_| panic!("could not bind to tls: {}", https_listener)), ); info!( "listening for HTTPS on {:?}", https_listener .local_addr() .expect("could not lookup local address") ); let _guard = runtime.enter(); server .register_https_listener( https_listener, config.get_tcp_request_timeout(), tls_cert, tls_cert_config.get_endpoint_name().map(|s| s.to_string()), ) .expect("could not register HTTPS listener"); } } #[cfg(feature = "dns-over-quic")] fn config_quic( args: &Cli, server: &mut ServerFuture, config: &Config, tls_cert_config: &TlsCertConfig, zone_dir: &Path, listen_addrs: &[IpAddr], runtime: &mut runtime::Runtime, ) { use futures_util::TryFutureExt; let quic_listen_port: u16 = args .quic_port .unwrap_or_else(|| config.get_quic_listen_port()); let quic_sockaddrs: Vec = listen_addrs .iter() .flat_map(|x| (*x, quic_listen_port).to_socket_addrs().unwrap()) .collect(); if quic_sockaddrs.is_empty() { warn!("a tls certificate was specified, but no QUIC addresses configured to listen on"); } for quic_listener in &quic_sockaddrs { if let Some(endpoint_name) = tls_cert_config.get_endpoint_name() { info!( "loading cert for DNS over QUIC named {} from {:?}", endpoint_name, tls_cert_config.get_path() ); } else { info!( "loading cert for DNS over QUIC from {:?}", tls_cert_config.get_path() ); } // TODO: see about modifying native_tls to impl Clone for Pkcs12 let tls_cert = dnssec::load_cert(zone_dir, tls_cert_config) .expect("error loading tls certificate file"); info!("binding QUIC to {:?}", quic_listener); let quic_listener = runtime.block_on( UdpSocket::bind(quic_listener) .unwrap_or_else(|_| panic!("could not bind to tls: {}", quic_listener)), ); info!( "listening for QUIC on {:?}", quic_listener .local_addr() .expect("could not lookup local address") ); let _guard = runtime.enter(); server .register_quic_listener( quic_listener, config.get_tcp_request_timeout(), tls_cert, tls_cert_config.get_endpoint_name().map(|s| s.to_string()), ) .expect("could not register QUIC listener"); } } fn banner() { #[cfg(feature = "ascii-art")] const HICKORY_DNS_LOGO: &str = include_str!("hickory-dns.ascii"); #[cfg(not(feature = "ascii-art"))] const HICKORY_DNS_LOGO: &str = "Hickory DNS"; info!(""); for line in HICKORY_DNS_LOGO.lines() { info!(" {line}"); } info!(""); } struct TdnsFormatter; impl FormatEvent for TdnsFormatter where S: Subscriber + for<'a> LookupSpan<'a>, N: for<'a> FormatFields<'a> + 'static, { fn format_event( &self, ctx: &FmtContext<'_, S, N>, mut writer: format::Writer<'_>, event: &Event<'_>, ) -> fmt::Result { let now = OffsetDateTime::now_utc(); let now_secs = now.unix_timestamp(); // Format values from the event's's metadata: let metadata = event.metadata(); write!( &mut writer, "{}:{}:{}", now_secs, metadata.level(), metadata.target() )?; if let Some(line) = metadata.line() { write!(&mut writer, ":{line}")?; } // Format all the spans in the event's span context. if let Some(scope) = ctx.event_scope() { for span in scope.from_root() { write!(writer, ":{}", span.name())?; let ext = span.extensions(); let fields = &ext .get::>() .expect("will never be `None`"); // Skip formatting the fields if the span had no fields. if !fields.is_empty() { write!(writer, "{{{fields}}}")?; } } } // Write fields on the event write!(writer, ":")?; ctx.field_format().format_fields(writer.by_ref(), event)?; writeln!(writer) } } fn get_env() -> String { env::var("RUST_LOG").unwrap_or_default() } fn all_hickory_dns(level: impl ToString) -> String { format!( "hickory_dns={level},{env}", level = level.to_string().to_lowercase(), env = get_env() ) } /// appends hickory-server debug to RUST_LOG pub fn debug() { logger(tracing::Level::DEBUG); } /// appends hickory-server info to RUST_LOG pub fn default() { logger(tracing::Level::INFO); } /// appends hickory-server error to RUST_LOG pub fn quiet() { logger(tracing::Level::ERROR); } // TODO: add dep on util crate, share logging config... fn logger(level: tracing::Level) { // Setup tracing for logging based on input let filter = tracing_subscriber::EnvFilter::builder() .with_default_directive(tracing::Level::WARN.into()) .parse(all_hickory_dns(level)) .expect("failed to configure tracing/logging"); let formatter = tracing_subscriber::fmt::layer().event_format(TdnsFormatter); tracing_subscriber::registry() .with(formatter) .with(filter) .init(); } hickory-dns-0.24.4/tests/named_https_tests.rs000064400000000000000000000063501046102023000174110ustar 00000000000000// Copyright 2015-2017 Benjamin Fry // // Licensed under the Apache License, Version 2.0, or the MIT license , at your option. This file may not be // copied, modified, or distributed except according to those terms. #![cfg(not(windows))] #![cfg(feature = "dns-over-https")] mod server_harness; use std::env; use std::fs::File; use std::io::*; use std::net::*; use std::sync::Arc; use hickory_client::client::*; use hickory_proto::h2::HttpsClientStreamBuilder; use hickory_proto::iocompat::AsyncIoTokioAsStd; use rustls::{Certificate, ClientConfig, OwnedTrustAnchor, RootCertStore}; use tokio::net::TcpStream as TokioTcpStream; use tokio::runtime::Runtime; use server_harness::{named_test_harness, query_a}; #[test] fn test_example_https_toml_startup() { // env_logger::try_init().ok(); const ALPN_H2: &[u8] = b"h2"; named_test_harness("dns_over_https.toml", move |_, _, _, https_port, _| { let mut cert_der = vec![]; let server_path = env::var("TDNS_WORKSPACE_ROOT").unwrap_or_else(|_| "..".to_owned()); println!("using server src path: {server_path}"); File::open(format!( "{server_path}/tests/test-data/test_configs/sec/example.cert" )) .expect("failed to open cert") .read_to_end(&mut cert_der) .expect("failed to read cert"); let mut io_loop = Runtime::new().unwrap(); let addr: SocketAddr = ("127.0.0.1", https_port.expect("no https_port")) .to_socket_addrs() .unwrap() .next() .unwrap(); std::thread::sleep(std::time::Duration::from_secs(1)); // using the mozilla default root store let mut root_store = RootCertStore::empty(); root_store.add_trust_anchors(webpki_roots::TLS_SERVER_ROOTS.iter().map(|ta| { OwnedTrustAnchor::from_subject_spki_name_constraints( ta.subject, ta.spki, ta.name_constraints, ) })); let cert = to_trust_anchor(&cert_der); root_store.add(&cert).unwrap(); let mut client_config = ClientConfig::builder() .with_safe_default_cipher_suites() .with_safe_default_kx_groups() .with_safe_default_protocol_versions() .unwrap() .with_root_certificates(root_store) .with_no_client_auth(); client_config.alpn_protocols.push(ALPN_H2.to_vec()); let client_config = Arc::new(client_config); let https_builder = HttpsClientStreamBuilder::with_client_config(client_config); let mp = https_builder .build::>(addr, "ns.example.com".to_string()); let client = AsyncClient::connect(mp); // ipv4 should succeed let (mut client, bg) = io_loop.block_on(client).expect("client failed to connect"); hickory_proto::spawn_bg(&io_loop, bg); query_a(&mut io_loop, &mut client); // a second request should work... query_a(&mut io_loop, &mut client); }) } fn to_trust_anchor(cert_der: &[u8]) -> Certificate { Certificate(cert_der.to_vec()) } hickory-dns-0.24.4/tests/named_openssl_tests.rs000064400000000000000000000063671046102023000177420ustar 00000000000000// Copyright 2015-2017 Benjamin Fry // // Licensed under the Apache License, Version 2.0, or the MIT license , at your option. This file may not be // copied, modified, or distributed except according to those terms. #![cfg(not(windows))] #![cfg(feature = "dns-over-openssl")] #![cfg(not(feature = "dns-over-rustls"))] // TODO: enable this test for rustls as well using below config // #![cfg(feature = "dns-over-tls")] mod server_harness; use std::env; use std::fs::File; use std::io::*; use std::net::*; use native_tls::Certificate; use tokio::net::TcpStream as TokioTcpStream; use tokio::runtime::Runtime; use hickory_client::client::*; use hickory_proto::native_tls::TlsClientStreamBuilder; use hickory_proto::iocompat::AsyncIoTokioAsStd; use server_harness::{named_test_harness, query_a}; #[test] fn test_example_tls_toml_startup() { test_startup("dns_over_tls.toml") } #[test] fn test_example_tls_rustls_and_openssl_toml_startup() { test_startup("dns_over_tls_rustls_and_openssl.toml") } fn test_startup(toml: &'static str) { named_test_harness(toml, move |_, _, tls_port, _, _| { let mut cert_der = vec![]; let server_path = env::var("TDNS_WORKSPACE_ROOT").unwrap_or_else(|_| "..".to_owned()); println!("using server src path: {}", server_path); File::open(&format!( "{}/tests/test-data/test_configs/sec/example.cert", server_path )) .expect("failed to open cert") .read_to_end(&mut cert_der) .expect("failed to read cert"); let mut io_loop = Runtime::new().unwrap(); let addr: SocketAddr = ("127.0.0.1", tls_port.expect("no tls_port")) .to_socket_addrs() .unwrap() .next() .unwrap(); let mut tls_conn_builder = TlsClientStreamBuilder::>::new(); let cert = to_trust_anchor(&cert_der); tls_conn_builder.add_ca(cert); let (stream, sender) = tls_conn_builder.build(addr, "ns.example.com".to_string()); let client = AsyncClient::new(stream, sender, None); let (mut client, bg) = io_loop.block_on(client).expect("client failed to connect"); hickory_proto::spawn_bg(&io_loop, bg); query_a(&mut io_loop, &mut client); let addr: SocketAddr = ("127.0.0.1", tls_port.expect("no tls_port")) .to_socket_addrs() .unwrap() .next() .unwrap(); let mut tls_conn_builder = TlsClientStreamBuilder::>::new(); let cert = to_trust_anchor(&cert_der); tls_conn_builder.add_ca(cert); let (stream, sender) = tls_conn_builder.build(addr, "ns.example.com".to_string()); let client = AsyncClient::new(stream, sender, None); let (mut client, bg) = io_loop.block_on(client).expect("client failed to connect"); hickory_proto::spawn_bg(&io_loop, bg); // ipv6 should succeed query_a(&mut io_loop, &mut client); assert!(true); }) } fn to_trust_anchor(cert_der: &[u8]) -> Certificate { Certificate::from_der(cert_der).unwrap() } hickory-dns-0.24.4/tests/named_quic_tests.rs000064400000000000000000000054671046102023000172200ustar 00000000000000// Copyright 2015-2022 Benjamin Fry // // Licensed under the Apache License, Version 2.0, or the MIT license , at your option. This file may not be // copied, modified, or distributed except according to those terms. #![cfg(not(windows))] #![cfg(feature = "dns-over-quic")] mod server_harness; use std::{env, fs::File, io::*, net::*}; use hickory_client::client::*; use hickory_proto::quic::QuicClientStream; use rustls::{Certificate, ClientConfig, OwnedTrustAnchor, RootCertStore}; use tokio::runtime::Runtime; use server_harness::{named_test_harness, query_a}; #[test] fn test_example_quic_toml_startup() { // env_logger::try_init().ok(); named_test_harness("dns_over_quic.toml", move |_, _, _, _, quic_port| { let mut cert_der = vec![]; let server_path = env::var("TDNS_WORKSPACE_ROOT").unwrap_or_else(|_| "..".to_owned()); println!("using server src path: {server_path} and quic_port: {quic_port:?}"); File::open(format!( "{server_path}/tests/test-data/test_configs/sec/example.cert" )) .expect("failed to open cert") .read_to_end(&mut cert_der) .expect("failed to read cert"); let mut io_loop = Runtime::new().unwrap(); let addr: SocketAddr = ("127.0.0.1", quic_port.expect("no quic_port")) .to_socket_addrs() .unwrap() .next() .unwrap(); std::thread::sleep(std::time::Duration::from_secs(1)); // using the mozilla default root store let mut root_store = RootCertStore::empty(); root_store.add_trust_anchors(webpki_roots::TLS_SERVER_ROOTS.iter().map(|ta| { OwnedTrustAnchor::from_subject_spki_name_constraints( ta.subject, ta.spki, ta.name_constraints, ) })); let cert = to_trust_anchor(&cert_der); root_store.add(&cert).unwrap(); let client_config = ClientConfig::builder() .with_safe_defaults() .with_root_certificates(root_store) .with_no_client_auth(); let mut quic_builder = QuicClientStream::builder(); quic_builder.crypto_config(client_config); let mp = quic_builder.build(addr, "ns.example.com".to_string()); let client = AsyncClient::connect(mp); // ipv4 should succeed let (mut client, bg) = io_loop.block_on(client).expect("client failed to connect"); hickory_proto::spawn_bg(&io_loop, bg); query_a(&mut io_loop, &mut client); // a second request should work... query_a(&mut io_loop, &mut client); }) } fn to_trust_anchor(cert_der: &[u8]) -> Certificate { Certificate(cert_der.to_vec()) } hickory-dns-0.24.4/tests/named_rustls_tests.rs000064400000000000000000000065251046102023000176070ustar 00000000000000// Copyright 2015-2017 Benjamin Fry // // Licensed under the Apache License, Version 2.0, or the MIT license , at your option. This file may not be // copied, modified, or distributed except according to those terms. #![cfg(not(windows))] #![cfg(feature = "dns-over-rustls")] mod server_harness; use std::env; use std::fs::File; use std::io::*; use std::net::*; use std::sync::Arc; use rustls::Certificate; use rustls::ClientConfig; use rustls::RootCertStore; use tokio::net::TcpStream as TokioTcpStream; use tokio::runtime::Runtime; use hickory_client::client::*; use hickory_proto::iocompat::AsyncIoTokioAsStd; use hickory_proto::rustls::tls_client_connect; use server_harness::{named_test_harness, query_a}; #[test] fn test_example_tls_toml_startup() { named_test_harness( "dns_over_tls_rustls_and_openssl.toml", move |_, _, tls_port, _, _| { let mut cert_der = vec![]; let server_path = env::var("TDNS_WORKSPACE_ROOT").unwrap_or_else(|_| "..".to_owned()); println!("using server src path: {server_path}"); File::open(format!( "{server_path}/tests/test-data/test_configs/sec/example.cert" )) .expect("failed to open cert") .read_to_end(&mut cert_der) .expect("failed to read cert"); let mut io_loop = Runtime::new().unwrap(); let addr: SocketAddr = ("127.0.0.1", tls_port.expect("no tls_port")) .to_socket_addrs() .unwrap() .next() .unwrap(); let cert = to_trust_anchor(&cert_der); let mut root_store = RootCertStore::empty(); root_store.add(&cert).expect("bad certificate"); let config = ClientConfig::builder() .with_safe_defaults() .with_root_certificates(root_store) .with_no_client_auth(); let config = Arc::new(config); let (stream, sender) = tls_client_connect::>( addr, "ns.example.com".to_string(), config.clone(), ); let client = AsyncClient::new(stream, sender, None); let (mut client, bg) = io_loop.block_on(client).expect("client failed to connect"); hickory_proto::spawn_bg(&io_loop, bg); // ipv4 should succeed query_a(&mut io_loop, &mut client); let addr: SocketAddr = ("127.0.0.1", tls_port.expect("no tls_port")) .to_socket_addrs() .unwrap() .next() .unwrap(); let (stream, sender) = tls_client_connect::>( addr, "ns.example.com".to_string(), config, ); let client = AsyncClient::new(stream, sender, None); let (mut client, bg) = io_loop.block_on(client).expect("client failed to connect"); hickory_proto::spawn_bg(&io_loop, bg); // ipv6 should succeed query_a(&mut io_loop, &mut client); }, ) } fn to_trust_anchor(cert_der: &[u8]) -> Certificate { Certificate(cert_der.to_vec()) } hickory-dns-0.24.4/tests/named_test_rsa_dnssec.rs000064400000000000000000000202771046102023000202140ustar 00000000000000#![cfg(feature = "dnssec")] #![cfg(not(windows))] mod server_harness; use std::env; use std::fs::File; use std::io::Read; use std::net::*; use std::path::Path; use tokio::net::TcpStream as TokioTcpStream; use tokio::runtime::Runtime; use hickory_client::client::{Signer, *}; use hickory_client::proto::tcp::TcpClientStream; use hickory_client::proto::DnssecDnsHandle; use hickory_proto::rr::dnssec::*; use hickory_proto::xfer::{DnsExchangeBackground, DnsMultiplexer}; use hickory_proto::{iocompat::AsyncIoTokioAsStd, TokioTime}; use server_harness::*; #[cfg(all(not(feature = "dnssec-ring"), feature = "dnssec-openssl"))] fn confg_toml() -> &'static str { "openssl_dnssec.toml" } #[cfg(all(feature = "dnssec-ring", not(feature = "dnssec-openssl")))] fn confg_toml() -> &'static str { "ring_dnssec.toml" } #[cfg(all(feature = "dnssec-ring", feature = "dnssec-openssl"))] fn confg_toml() -> &'static str { "all_supported_dnssec.toml" } fn trust_anchor(public_key_path: &Path, format: KeyFormat, algorithm: Algorithm) -> TrustAnchor { let mut file = File::open(public_key_path).expect("key not found"); let mut buf = Vec::::new(); file.read_to_end(&mut buf).expect("could not read key"); let key_pair = format .decode_key(&buf, Some("123456"), algorithm) .expect("could not decode key"); let public_key = key_pair.to_public_key().unwrap(); let mut trust_anchor = TrustAnchor::new(); trust_anchor.insert_trust_anchor(&public_key); trust_anchor } #[allow(clippy::type_complexity)] async fn standard_tcp_conn( port: u16, ) -> ( AsyncClient, DnsExchangeBackground< DnsMultiplexer>, Signer>, TokioTime, >, ) { let addr: SocketAddr = ("127.0.0.1", port) .to_socket_addrs() .unwrap() .next() .unwrap(); let (stream, sender) = TcpClientStream::>::new(addr); AsyncClient::new(stream, sender, None) .await .expect("new AsyncClient failed") } fn generic_test(config_toml: &str, key_path: &str, key_format: KeyFormat, algorithm: Algorithm) { // TODO: look into the `test-log` crate for enabling logging during tests // use hickory_client::logger; // use tracing::LogLevel; let server_path = env::var("TDNS_WORKSPACE_ROOT").unwrap_or_else(|_| "..".to_owned()); let server_path = Path::new(&server_path); named_test_harness(config_toml, |_, tcp_port, _, _, _| { let mut io_loop = Runtime::new().unwrap(); // verify all records are present let client = standard_tcp_conn(tcp_port.expect("no tcp port")); let (client, bg) = io_loop.block_on(client); hickory_proto::spawn_bg(&io_loop, bg); query_all_dnssec_wo_rfc6975(&mut io_loop, client, algorithm); // test that request with Dnssec client is successful, i.e. validates chain let trust_anchor = trust_anchor(&server_path.join(key_path), key_format, algorithm); let client = standard_tcp_conn(tcp_port.expect("no tcp port")); let (client, bg) = io_loop.block_on(client); hickory_proto::spawn_bg(&io_loop, bg); let mut client = DnssecDnsHandle::with_trust_anchor(client, trust_anchor); query_a(&mut io_loop, &mut client); }); } #[test] #[cfg(feature = "dnssec-openssl")] fn test_rsa_sha256() { generic_test( confg_toml(), "tests/test-data/test_configs/dnssec/rsa_2048.pem", KeyFormat::Pem, Algorithm::RSASHA256, ); } #[test] #[cfg(feature = "dnssec-openssl")] fn test_rsa_sha512() { generic_test( confg_toml(), "tests/test-data/test_configs/dnssec/rsa_2048.pem", KeyFormat::Pem, Algorithm::RSASHA512, ); } #[test] #[cfg(feature = "dnssec-openssl")] fn test_ecdsa_p256() { generic_test( confg_toml(), "tests/test-data/test_configs/dnssec/ecdsa_p256.pem", KeyFormat::Pem, Algorithm::ECDSAP256SHA256, ); } #[test] #[cfg(feature = "dnssec-ring")] fn test_ecdsa_p256_pkcs8() { generic_test( confg_toml(), "tests/test-data/test_configs/dnssec/ecdsa_p256.pk8", KeyFormat::Pkcs8, Algorithm::ECDSAP256SHA256, ); } #[test] #[cfg(feature = "dnssec-openssl")] fn test_ecdsa_p384() { generic_test( confg_toml(), "tests/test-data/test_configs/dnssec/ecdsa_p384.pem", KeyFormat::Pem, Algorithm::ECDSAP384SHA384, ); } #[test] #[cfg(feature = "dnssec-ring")] fn test_ecdsa_p384_pkcs8() { generic_test( confg_toml(), "tests/test-data/test_configs/dnssec/ecdsa_p384.pk8", KeyFormat::Pkcs8, Algorithm::ECDSAP384SHA384, ); } #[test] #[cfg(feature = "dnssec-ring")] fn test_ed25519() { generic_test( confg_toml(), "tests/test-data/test_configs/dnssec/ed25519.pk8", KeyFormat::Pkcs8, Algorithm::ED25519, ); } #[test] #[should_panic] #[allow(deprecated)] fn test_rsa_sha1_fails() { generic_test( confg_toml(), "tests/test-data/test_configs/dnssec/rsa_2048.pem", KeyFormat::Pem, Algorithm::RSASHA1, ); } #[cfg(feature = "dnssec-openssl")] #[cfg(feature = "sqlite")] #[test] fn test_dnssec_restart_with_update_journal() { // TODO: make journal path configurable, it should be in target/tests/... let server_path = env::var("TDNS_WORKSPACE_ROOT").unwrap_or_else(|_| "..".to_owned()); let server_path = Path::new(&server_path); let journal = server_path.join("tests/test-data/test_configs/example.com_dnssec_update.jrnl"); std::fs::remove_file(&journal).ok(); generic_test( "dnssec_with_update.toml", "tests/test-data/test_configs/dnssec/rsa_2048.pem", KeyFormat::Pem, Algorithm::RSASHA256, ); // after running the above test, the journal file should exist assert!(journal.exists()); // and all dnssec tests should still pass generic_test( "dnssec_with_update.toml", "tests/test-data/test_configs/dnssec/rsa_2048.pem", KeyFormat::Pem, Algorithm::RSASHA256, ); // and journal should still exist assert!(journal.exists()); // cleanup... // TODO: fix journal path so that it doesn't leave the dir dirty... this might make windows an option after that std::fs::remove_file(&journal).expect("failed to cleanup after test"); } #[cfg(feature = "dnssec-openssl")] #[cfg(feature = "sqlite")] #[test] fn test_dnssec_restart_with_update_journal_dep() { // TODO: make journal path configurable, it should be in target/tests/... let server_path = env::var("TDNS_WORKSPACE_ROOT").unwrap_or_else(|_| "..".to_owned()); let server_path = Path::new(&server_path); let journal = server_path.join("tests/test-data/test_configs/example.com.jrnl"); std::fs::remove_file(&journal).ok(); generic_test( "dnssec_with_update_deprecated.toml", "tests/test-data/test_configs/dnssec/rsa_2048.pem", KeyFormat::Pem, Algorithm::RSASHA256, ); // after running the above test, the journal file should exist assert!(journal.exists()); // and all dnssec tests should still pass generic_test( "dnssec_with_update_deprecated.toml", "tests/test-data/test_configs/dnssec/rsa_2048.pem", KeyFormat::Pem, Algorithm::RSASHA256, ); // and journal should still exist assert!(journal.exists()); // cleanup... // TODO: fix journal path so that it doesn't leave the dir dirty... this might make windows an option after that std::fs::remove_file(&journal).expect("failed to cleanup after test"); } #[cfg(feature = "dnssec-openssl")] #[test] fn crypto_self_test() { let buf = std::fs::read("../tests/test-data/test_configs/dnssec/ecdsa_p256.pem").unwrap(); let key_pair = KeyFormat::Pem .decode_key(&buf, None, Algorithm::ECDSAP256SHA256) .unwrap(); let public_key = key_pair.to_public_key().unwrap(); println!("{:02x?}", public_key.public_bytes()); let tbs = TBS::from(b"hello".as_slice()); let signature = key_pair.sign(Algorithm::ECDSAP256SHA256, &tbs).unwrap(); public_key .verify(Algorithm::ECDSAP256SHA256, tbs.as_ref(), &signature) .expect("signature should verify"); } hickory-dns-0.24.4/tests/named_tests.rs000064400000000000000000000306321046102023000161670ustar 00000000000000// Copyright 2015-2017 Benjamin Fry // // Licensed under the Apache License, Version 2.0, or the MIT license , at your option. This file may not be // copied, modified, or distributed except according to those terms. mod server_harness; use std::io::Write; use std::net::*; use std::str::FromStr; use tokio::net::TcpStream as TokioTcpStream; use tokio::net::UdpSocket as TokioUdpSocket; use tokio::runtime::Runtime; use hickory_client::client::*; use hickory_client::op::ResponseCode; use hickory_client::rr::*; use hickory_client::tcp::TcpClientStream; use hickory_client::udp::UdpClientStream; // TODO: Needed for when TLS tests are added back // #[cfg(feature = "dns-over-openssl")] // use hickory_proto::openssl::TlsClientStreamBuilder; use hickory_proto::iocompat::AsyncIoTokioAsStd; use server_harness::{named_test_harness, query_a}; #[test] fn test_example_toml_startup() { named_test_harness("example.toml", |_, tcp_port, _, _, _| { let mut io_loop = Runtime::new().unwrap(); let addr: SocketAddr = SocketAddr::new( Ipv4Addr::new(127, 0, 0, 1).into(), tcp_port.expect("no tcp_port"), ); let (stream, sender) = TcpClientStream::>::new(addr); let client = AsyncClient::new(Box::new(stream), sender, None); let (mut client, bg) = io_loop.block_on(client).expect("client failed to connect"); hickory_proto::spawn_bg(&io_loop, bg); query_a(&mut io_loop, &mut client); // just tests that multiple queries work let addr: SocketAddr = SocketAddr::new( Ipv4Addr::new(127, 0, 0, 1).into(), tcp_port.expect("no tcp_port"), ); let (stream, sender) = TcpClientStream::>::new(addr); let client = AsyncClient::new(Box::new(stream), sender, None); let (mut client, bg) = io_loop.block_on(client).expect("client failed to connect"); hickory_proto::spawn_bg(&io_loop, bg); query_a(&mut io_loop, &mut client); }) } #[test] fn test_ipv4_only_toml_startup() { named_test_harness("ipv4_only.toml", |_, tcp_port, _, _, _| { let mut io_loop = Runtime::new().unwrap(); let addr: SocketAddr = SocketAddr::new( Ipv4Addr::new(127, 0, 0, 1).into(), tcp_port.expect("no tcp_port"), ); let (stream, sender) = TcpClientStream::>::new(addr); let client = AsyncClient::new(Box::new(stream), sender, None); let (mut client, bg) = io_loop.block_on(client).expect("client failed to connect"); hickory_proto::spawn_bg(&io_loop, bg); // ipv4 should succeed query_a(&mut io_loop, &mut client); let addr: SocketAddr = SocketAddr::new( Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1).into(), tcp_port.expect("no tcp_port"), ); let (stream, sender) = TcpClientStream::>::new(addr); let client = AsyncClient::new(Box::new(stream), sender, None); assert!(io_loop.block_on(client).is_err()); //let (client, bg) = io_loop.block_on(client).expect("client failed to connect"); //hickory_proto::spawn_bg(&io_loop, bg); // ipv6 should fail // FIXME: probably need to send something for proper test... maybe use JoinHandle in tokio 0.2 // assert!(io_loop.block_on(client).is_err()); }) } // TODO: this is commented out b/c at least on macOS, ipv4 will route properly to ipv6 only // listeners over the [::ffff:127.0.0.1] interface // // #[ignore] // #[test] // fn test_ipv6_only_toml_startup() { // named_test_harness("ipv6_only.toml", |port, _| { // let mut io_loop = Runtime::new().unwrap(); // let addr: SocketAddr = ("127.0.0.1", port).to_socket_addrs().unwrap().next().unwrap(); // let (stream, sender) = TcpClientStream::new(addr); // let client = AsyncClient::new(stream, sender, None); // let mut client = io_loop.block_on(client).unwrap(); // // // ipv4 should fail // assert!(!query(&mut io_loop, client)); // // let addr: SocketAddr = ("::1", port).to_socket_addrs().unwrap().next().unwrap(); // let (stream, sender) = TcpClientStream::new(addr); // let client = AsyncClient::new(stream, sender, None); // let mut client = io_loop.block_on(client).unwrap(); // // // ipv6 should succeed // assert!(query(&mut io_loop, client)); // // assert!(true); // }) // } #[ignore] #[test] fn test_ipv4_and_ipv6_toml_startup() { named_test_harness("ipv4_and_ipv6.toml", |_, tcp_port, _, _, _| { let mut io_loop = Runtime::new().unwrap(); let addr: SocketAddr = SocketAddr::new( Ipv4Addr::new(127, 0, 0, 1).into(), tcp_port.expect("no tcp_port"), ); let (stream, sender) = TcpClientStream::>::new(addr); let client = AsyncClient::new(Box::new(stream), sender, None); let (mut client, bg) = io_loop.block_on(client).expect("client failed to connect"); hickory_proto::spawn_bg(&io_loop, bg); // ipv4 should succeed query_a(&mut io_loop, &mut client); let addr: SocketAddr = SocketAddr::new( Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1).into(), tcp_port.expect("no tcp_port"), ); let (stream, sender) = TcpClientStream::>::new(addr); let client = AsyncClient::new(Box::new(stream), sender, None); let (mut client, bg) = io_loop.block_on(client).expect("client failed to connect"); hickory_proto::spawn_bg(&io_loop, bg); // ipv6 should succeed query_a(&mut io_loop, &mut client); }) } #[test] fn test_nodata_where_name_exists() { named_test_harness("example.toml", |_, tcp_port, _, _, _| { let io_loop = Runtime::new().unwrap(); let addr: SocketAddr = SocketAddr::new( Ipv4Addr::new(127, 0, 0, 1).into(), tcp_port.expect("no tcp_port"), ); let (stream, sender) = TcpClientStream::>::new(addr); let client = AsyncClient::new(Box::new(stream), sender, None); let (mut client, bg) = io_loop.block_on(client).expect("client failed to connect"); hickory_proto::spawn_bg(&io_loop, bg); let msg = io_loop .block_on(client.query( Name::from_str("www.example.com.").unwrap(), DNSClass::IN, RecordType::SRV, )) .unwrap(); assert_eq!(msg.response_code(), ResponseCode::NoError); assert!(msg.answers().is_empty()); }) } #[test] fn test_nxdomain_where_no_name_exists() { named_test_harness("example.toml", |_, tcp_port, _, _, _| { let io_loop = Runtime::new().unwrap(); let addr: SocketAddr = SocketAddr::new( Ipv4Addr::new(127, 0, 0, 1).into(), tcp_port.expect("no tcp_port"), ); let (stream, sender) = TcpClientStream::>::new(addr); let client = AsyncClient::new(Box::new(stream), sender, None); let (mut client, bg) = io_loop.block_on(client).expect("client failed to connect"); hickory_proto::spawn_bg(&io_loop, bg); let msg = io_loop .block_on(client.query( Name::from_str("nxdomain.example.com.").unwrap(), DNSClass::IN, RecordType::SRV, )) .unwrap(); assert_eq!(msg.response_code(), ResponseCode::NXDomain); assert!(msg.answers().is_empty()); }) } #[test] fn test_server_continues_on_bad_data_udp() { named_test_harness("example.toml", |udp_port, _, _, _, _| { let mut io_loop = Runtime::new().unwrap(); let addr: SocketAddr = SocketAddr::new( Ipv4Addr::new(127, 0, 0, 1).into(), udp_port.expect("no udp_port"), ); let stream = UdpClientStream::::new(addr); let client = AsyncClient::connect(stream); let (mut client, bg) = io_loop.block_on(client).expect("client failed to connect"); hickory_proto::spawn_bg(&io_loop, bg); query_a(&mut io_loop, &mut client); // Send a bad packet, this should get rejected by the server let raw_socket = UdpSocket::bind(SocketAddr::new(Ipv4Addr::new(0, 0, 0, 0).into(), 0)) .expect("couldn't bind raw"); raw_socket .send_to(b"0xDEADBEEF", addr) .expect("raw send failed"); // just tests that multiple queries work let addr: SocketAddr = SocketAddr::new( Ipv4Addr::new(127, 0, 0, 1).into(), udp_port.expect("no udp_port"), ); let stream = UdpClientStream::::new(addr); let client = AsyncClient::connect(stream); let (mut client, bg) = io_loop.block_on(client).expect("client failed to connect"); hickory_proto::spawn_bg(&io_loop, bg); query_a(&mut io_loop, &mut client); }) } #[test] fn test_server_continues_on_bad_data_tcp() { named_test_harness("example.toml", |_, tcp_port, _, _, _| { let mut io_loop = Runtime::new().unwrap(); let addr: SocketAddr = SocketAddr::new( Ipv4Addr::new(127, 0, 0, 1).into(), tcp_port.expect("no tcp_port"), ); let (stream, sender) = TcpClientStream::>::new(addr); let client = AsyncClient::new(Box::new(stream), sender, None); let (mut client, bg) = io_loop.block_on(client).expect("client failed to connect"); hickory_proto::spawn_bg(&io_loop, bg); query_a(&mut io_loop, &mut client); // Send a bad packet, this should get rejected by the server let mut raw_socket = TcpStream::connect(addr).expect("couldn't bind raw"); raw_socket .write_all(b"0xDEADBEEF") .expect("raw send failed"); // just tests that multiple queries work let addr: SocketAddr = SocketAddr::new( Ipv4Addr::new(127, 0, 0, 1).into(), tcp_port.expect("no tcp_port"), ); let (stream, sender) = TcpClientStream::>::new(addr); let client = AsyncClient::new(Box::new(stream), sender, None); let (mut client, bg) = io_loop.block_on(client).expect("client failed to connect"); hickory_proto::spawn_bg(&io_loop, bg); query_a(&mut io_loop, &mut client); }) } #[test] #[cfg(feature = "resolver")] fn test_forward() { use server_harness::query_message; //env_logger::init(); named_test_harness("example_forwarder.toml", |_, tcp_port, _, _, _| { let mut io_loop = Runtime::new().unwrap(); let addr: SocketAddr = SocketAddr::new( Ipv4Addr::new(127, 0, 0, 1).into(), tcp_port.expect("no tcp_port"), ); let (stream, sender) = TcpClientStream::>::new(addr); let client = AsyncClient::new(Box::new(stream), sender, None); let (mut client, bg) = io_loop.block_on(client).expect("client failed to connect"); hickory_proto::spawn_bg(&io_loop, bg); let response = query_message( &mut io_loop, &mut client, Name::from_str("www.example.com").unwrap(), RecordType::A, ); assert!(response .answers() .iter() .any(|record| record.data().unwrap().as_a().is_some())); // just tests that multiple queries work let addr: SocketAddr = SocketAddr::new( Ipv4Addr::new(127, 0, 0, 1).into(), tcp_port.expect("no tcp_port"), ); let (stream, sender) = TcpClientStream::>::new(addr); let client = AsyncClient::new(Box::new(stream), sender, None); let (mut client, bg) = io_loop.block_on(client).expect("client failed to connect"); hickory_proto::spawn_bg(&io_loop, bg); let response = query_message( &mut io_loop, &mut client, Name::from_str("www.example.com").unwrap(), RecordType::A, ); assert!(response .answers() .iter() .any(|record| record.data().unwrap().as_a().is_some())); assert!(!response.header().authoritative()); }) } hickory-dns-0.24.4/tests/server_harness/mod.rs000064400000000000000000000247771046102023000175060ustar 00000000000000pub mod mut_message_client; use std::{ env, io::{stdout, BufRead, BufReader, Write}, panic::{catch_unwind, UnwindSafe}, process::{Command, Stdio}, str::FromStr, sync::*, thread, time::*, }; use hickory_client::{client::*, proto::xfer::DnsResponse}; #[cfg(feature = "dnssec")] use hickory_proto::rr::dnssec::*; use hickory_proto::rr::{rdata::A, *}; use regex::Regex; use tokio::runtime::Runtime; use tracing::{info, warn}; #[cfg(feature = "dnssec")] use self::mut_message_client::MutMessageHandle; fn collect_and_print(read: &mut R, output: &mut String) { output.clear(); read.read_line(output).expect("could not read stdio"); if !output.is_empty() { // uncomment for debugging // println!("SRV: {}", output.trim_end()); } } /// Spins up a Server and handles shutting it down after running the test #[allow(dead_code)] pub fn named_test_harness(toml: &str, test: F) where F: FnOnce(Option, Option, Option, Option, Option) -> R + UnwindSafe, { let server_path = env::var("TDNS_WORKSPACE_ROOT").unwrap_or_else(|_| "..".to_owned()); println!("using server src path: {server_path}"); let mut command = Command::new(env!("CARGO_BIN_EXE_hickory-dns")); command .stdout(Stdio::piped()) .env( "RUST_LOG", "hickory_dns=debug,hickory_client=debug,hickory_proto=debug,hickory_resolver=debug,hickory_server=debug", ) .arg("-d") .arg(format!( "--config={server_path}/tests/test-data/test_configs/{toml}" )) .arg(format!( "--zonedir={server_path}/tests/test-data/test_configs" )) .arg(format!("--port={}", 0)) .arg(format!("--tls-port={}", 0)) .arg(format!("--https-port={}", 0)) .arg(format!("--quic-port={}", 0)); println!("named cli options: {command:#?}"); let mut named = command.spawn().expect("failed to start named"); println!("server starting"); let mut named_out = BufReader::new(named.stdout.take().expect("no stdout")); // forced thread killer let named = Arc::new(Mutex::new(named)); let named_killer = Arc::clone(&named); let succeeded = Arc::new(atomic::AtomicBool::new(false)); let succeeded_clone = succeeded.clone(); let killer_join = thread::Builder::new() .name("thread_killer".to_string()) .spawn(move || { let succeeded = succeeded_clone; let kill_named = || { info!("killing named"); let mut named = named_killer.lock().unwrap(); if let Err(e) = named.kill() { warn!("warning: failed to kill named: {:?}", e); } }; for _ in 0..30 { thread::sleep(Duration::from_secs(1)); if succeeded.load(atomic::Ordering::Relaxed) { kill_named(); return; } } kill_named(); println!("Thread Killer has been awoken, killing process"); std::process::exit(-1); }) .expect("could not start thread killer"); // These will be collected from the server startup' // FIXME: create a wrapper type for all of these params let mut test_udp_port = Option::::None; let mut test_tcp_port = Option::::None; let mut test_tls_port = Option::::None; let mut test_https_port = Option::::None; let mut test_quic_port = Option::::None; // we should get the correct output before 1000 lines... let mut output = String::new(); let mut found = false; let wait_for_start_until = Instant::now() + Duration::from_secs(60); // Search strings for the ports used during testing let udp_regex = Regex::new(r"listening for UDP on (?:V4\()?0\.0\.0\.0:(\d+)\)?").unwrap(); let tcp_regex = Regex::new(r"listening for TCP on (?:V4\()?0\.0\.0\.0:(\d+)\)?").unwrap(); let tls_regex = Regex::new(r"listening for TLS on (?:V4\()?0\.0\.0\.0:(\d+)\)?").unwrap(); let https_regex = Regex::new(r"listening for HTTPS on (?:V4\()?0\.0\.0\.0:(\d+)\)?").unwrap(); let quic_regex = Regex::new(r"listening for QUIC on (?:V4\()?0\.0\.0\.0:(\d+)\)?").unwrap(); while Instant::now() < wait_for_start_until { { if let Some(ret_code) = named .lock() .unwrap() .try_wait() .expect("failed to check status of named") { panic!("named has already exited with code: {}", ret_code); } } collect_and_print(&mut named_out, &mut output); if let Some(udp) = udp_regex.captures(&output) { test_udp_port = Some( udp.get(1) .expect("udp missing port") .as_str() .parse() .expect("could not parse udp port"), ); } else if let Some(tcp) = tcp_regex.captures(&output) { test_tcp_port = Some( tcp.get(1) .expect("tcp missing port") .as_str() .parse() .expect("could not parse tcp port"), ); } else if let Some(tls) = tls_regex.captures(&output) { test_tls_port = Some( tls.get(1) .expect("tls missing port") .as_str() .parse() .expect("could not parse tls port"), ); } else if let Some(https) = https_regex.captures(&output) { test_https_port = Some( https .get(1) .expect("https missing port") .as_str() .parse() .expect("could not parse https port"), ); } else if let Some(quic) = quic_regex.captures(&output) { test_quic_port = Some( quic.get(1) .expect("quic missing port") .as_str() .parse() .expect("could not parse quic port"), ); } else if output.contains("awaiting connections...") { found = true; break; } } stdout().flush().unwrap(); assert!(found); println!( "Test server started. ports: udp {test_udp_port:?}, tcp {test_tcp_port:?}, tls {test_tls_port:?}, https {test_https_port:?}, quic {test_quic_port:?}", ); // spawn a thread to capture stdout let succeeded_clone = succeeded.clone(); thread::Builder::new() .name("named stdout".into()) .spawn(move || { let succeeded = succeeded_clone; while !succeeded.load(atomic::Ordering::Relaxed) { collect_and_print(&mut named_out, &mut output); if let Some(_ret_code) = named .lock() .unwrap() .try_wait() .expect("failed to check status of named") { // uncomment for debugging: // println!("named exited with code: {}", _ret_code); } } }) .expect("no thread available"); println!("running test..."); let result = catch_unwind(move || { test( test_udp_port, test_tcp_port, test_tls_port, test_https_port, test_quic_port, ) }); println!("test completed"); succeeded.store(true, atomic::Ordering::Relaxed); killer_join.join().expect("join failed"); assert!(result.is_ok(), "test failed"); } pub fn query_message( io_loop: &mut Runtime, client: &mut C, name: Name, record_type: RecordType, ) -> DnsResponse { println!("sending request: {name} for: {record_type}"); let response = io_loop.block_on(client.query(name, DNSClass::IN, record_type)); //println!("got response: {}"); response.expect("request failed") } // This only validates that a query to the server works, it shouldn't be used for more than this. // i.e. more complex checks live with the clients and authorities to validate deeper functionality #[allow(dead_code)] pub fn query_a(io_loop: &mut Runtime, client: &mut C) { let name = Name::from_str("www.example.com").unwrap(); let response = query_message(io_loop, client, name, RecordType::A); let record = &response.answers()[0]; if let Some(RData::A(ref address)) = record.data() { assert_eq!(address, &A::new(127, 0, 0, 1)) } else { panic!("wrong RDATA") } } // This only validates that a query to the server works, it shouldn't be used for more than this. // i.e. more complex checks live with the clients and authorities to validate deeper functionality #[allow(dead_code)] #[cfg(feature = "dnssec")] pub fn query_all_dnssec( io_loop: &mut Runtime, client: AsyncClient, algorithm: Algorithm, with_rfc6975: bool, ) { use hickory_client::rr::rdata::{DNSKEY, RRSIG}; let name = Name::from_str("example.com.").unwrap(); let mut client = MutMessageHandle::new(client); client.lookup_options.set_is_dnssec(true); if with_rfc6975 { client .lookup_options .set_supported_algorithms(SupportedAlgorithms::from_vec(&[algorithm])); } let response = query_message(io_loop, &mut client, name.clone(), RecordType::DNSKEY); let dnskey = response .answers() .iter() .filter_map(Record::data) .filter_map(DNSKEY::try_borrow) .find(|d| d.algorithm() == algorithm); assert!(dnskey.is_some(), "DNSKEY not found"); let response = query_message(io_loop, &mut client, name, RecordType::DNSKEY); let rrsig = response .answers() .iter() .filter_map(Record::data) .filter_map(RRSIG::try_borrow) .filter(|rrsig| rrsig.algorithm() == algorithm) .find(|rrsig| rrsig.type_covered() == RecordType::DNSKEY); assert!(rrsig.is_some(), "Associated RRSIG not found"); } #[allow(dead_code)] #[cfg(feature = "dnssec")] pub fn query_all_dnssec_with_rfc6975( io_loop: &mut Runtime, client: AsyncClient, algorithm: Algorithm, ) { query_all_dnssec(io_loop, client, algorithm, true) } #[allow(dead_code)] #[cfg(feature = "dnssec")] pub fn query_all_dnssec_wo_rfc6975( io_loop: &mut Runtime, client: AsyncClient, algorithm: Algorithm, ) { query_all_dnssec(io_loop, client, algorithm, false) } hickory-dns-0.24.4/tests/server_harness/mut_message_client.rs000064400000000000000000000026421046102023000225610ustar 00000000000000use hickory_client::client::*; use hickory_client::proto::xfer::{DnsHandle, DnsRequest}; #[cfg(feature = "dnssec")] use hickory_client::{op::Edns, rr::rdata::opt::EdnsOption}; #[cfg(feature = "dnssec")] use hickory_server::authority::LookupOptions; #[derive(Clone)] pub struct MutMessageHandle { client: C, #[cfg(feature = "dnssec")] pub lookup_options: LookupOptions, } impl MutMessageHandle { #[allow(dead_code)] pub fn new(client: C) -> Self { MutMessageHandle { client, #[cfg(feature = "dnssec")] lookup_options: Default::default(), } } } impl DnsHandle for MutMessageHandle { type Response = ::Response; type Error = ::Error; fn is_verifying_dnssec(&self) -> bool { true } #[allow(unused_mut)] fn send + Unpin>(&self, request: R) -> Self::Response { let mut request = request.into(); #[cfg(feature = "dnssec")] { // mutable block let edns = request.extensions_mut().get_or_insert_with(Edns::new); edns.set_dnssec_ok(true); edns.options_mut() .insert(EdnsOption::DAU(self.lookup_options.supported_algorithms())); } println!("sending message"); self.client.send(request) } }