### Initialize SOA record Source: https://github.com/balliegojr/simple-dns/blob/main/_autodocs/api-reference/rdata-basic.md Example of creating a new SOA record instance. ```rust use simple_dns::rdata::SOA; let soa = SOA { mname: Name::new("ns1.example.com")?, rname: Name::new("admin.example.com")?, serial: 2024010101, refresh: 10800, retry: 3600, expire: 604800, minimum: 86400, }; ``` -------------------------------- ### Create A Record Instance Source: https://github.com/balliegojr/simple-dns/blob/main/_autodocs/api-reference/rdata-basic.md Example of initializing a ResourceRecord with an A record type. ```rust use simple_dns::rdata::A; let record = ResourceRecord::new( Name::new("example.com")?, CLASS::IN, 300, RData::A(A { address: 0x7f000001 }), ); ``` -------------------------------- ### Create a new Question instance Source: https://github.com/balliegojr/simple-dns/blob/main/_autodocs/api-reference/question-resource-record.md Example usage of the Question constructor to initialize a query for an A record. ```rust use simple_dns::{Question, Name, QTYPE, QCLASS, CLASS, TYPE}; let question = Question::new( Name::new("example.com")?, QTYPE::TYPE(TYPE::A), QCLASS::CLASS(CLASS::IN), false, ); ``` -------------------------------- ### Configure simple-dns dependencies Source: https://github.com/balliegojr/simple-dns/blob/main/_autodocs/README.md Examples of Cargo.toml configurations for different environments including std, no_std with allocation, and bare metal. ```toml # Default with std simple-dns = "0.12" # no_std with allocation simple-dns = { version = "0.12", default-features = false, features = ["alloc"] } # Bare metal, stack only simple-dns = { version = "0.12", default-features = false } ``` -------------------------------- ### Embedded Configuration Example Source: https://github.com/balliegojr/simple-dns/blob/main/_autodocs/configuration.md Demonstrates dependency configuration and a basic packet processing function for embedded systems. ```toml [dependencies] simple-dns = { version = "0.12", default-features = false, features = ["alloc"] } ``` ```rust #![no_std] #![no_main] extern crate alloc; use alloc::vec::Vec; use simple_dns::{Packet, Name, Question, QTYPE, QCLASS, CLASS, TYPE}; #[no_mangle] pub extern "C" fn process_dns(data: &[u8]) -> *mut u8 { let packet = match Packet::parse(data) { Ok(p) => p, Err(_) => return core::ptr::null_mut(), }; if let Ok(bytes) = packet.build_bytes_vec() { let ptr = bytes.leak() as *mut [u8] as *mut u8; ptr } else { core::ptr::null_mut() } } ``` -------------------------------- ### Discovering Services with IPV6 Source: https://github.com/balliegojr/simple-dns/blob/main/simple-mdns/README.md Demonstrates how to initialize ServiceDiscovery for IPV6 using NetworkScope::V6. This example requires the 'sync' feature to be enabled. ```rust # // This is test is marked as no_run because IPV6 is not available in github actions. # #[cfg(feature = "sync")] { use simple_mdns::sync_discovery::ServiceDiscovery; use simple_mdns::{NetworkScope, InstanceInformation}; use std::str::FromStr; let mut discovery = ServiceDiscovery::new_with_scope( InstanceInformation::new("a".into()), "_mysrv._tcp.local", 60, None, NetworkScope::V6, ).expect(" Service Name"); # } ``` -------------------------------- ### Initialize SRV record Source: https://github.com/balliegojr/simple-dns/blob/main/_autodocs/api-reference/rdata-basic.md Example of creating an SRV record and wrapping it in a ResourceRecord. ```rust use simple_dns::rdata::SRV; let srv = SRV { priority: 10, weight: 50, port: 5060, target: Name::new("sip.example.com")?, }; let record = ResourceRecord::new( Name::new("_sip._tcp.example.com")?, CLASS::IN, 3600, RData::SRV(srv), ); ``` -------------------------------- ### Set OPCODE in packet Source: https://github.com/balliegojr/simple-dns/blob/main/_autodocs/api-reference/header-flags.md Example of setting the opcode on a DNS packet. ```rust let mut packet = Packet::new_reply(1); *packet.opcode_mut() = OPCODE::StandardQuery; ``` -------------------------------- ### Configure OPT record in a packet Source: https://github.com/balliegojr/simple-dns/blob/main/_autodocs/api-reference/rdata-advanced.md Example of setting the OPT record on a DNS packet using opt_mut(). ```rust use simple_dns::rdata::OPT; let mut packet = Packet::new_reply(1); *packet.opt_mut() = Some(OPT { opt_codes: vec![], udp_packet_size: 1472, version: 0, }); ``` -------------------------------- ### Process packets in no_std with alloc Source: https://github.com/balliegojr/simple-dns/blob/main/_autodocs/configuration.md Example usage of simple-dns in a no_std environment requiring a global allocator. ```rust #![no_std] extern crate alloc; use alloc::vec::Vec; use simple_dns::Packet; fn process_packet(data: &[u8]) -> simple_dns::Result> { let packet = Packet::parse(data)?; packet.build_bytes_vec() } ``` -------------------------------- ### Define SOA record Source: https://github.com/balliegojr/simple-dns/blob/main/_autodocs/types.md Represents a Start of Authority record. ```rust pub struct SOA<'a> { pub mname: Name<'a>, pub rname: Name<'a>, pub serial: u32, pub refresh: i32, pub retry: i32, pub expire: i32, pub minimum: u32, } ``` -------------------------------- ### Set and check RCODE in packet Source: https://github.com/balliegojr/simple-dns/blob/main/_autodocs/api-reference/header-flags.md Example of setting an RCODE and matching against it to handle response results. ```rust let mut reply = Packet::new_reply(1); *reply.rcode_mut() = RCODE::NameError; // Domain not found // Check response code match reply.rcode() { RCODE::NoError => println!("Success"), RCODE::NameError => println!("Domain not found"), RCODE::Refused => println!("Server refused"), _ => println!("Other error"), } ``` -------------------------------- ### Get Label length Source: https://github.com/balliegojr/simple-dns/blob/main/_autodocs/api-reference/name.md Returns the byte length of the label. ```rust pub fn len(&self) -> usize ``` -------------------------------- ### Convert string to Name Source: https://github.com/balliegojr/simple-dns/blob/main/_autodocs/api-reference/name.md Usage example for converting a string literal into a Name using try_into. ```rust let name: Name = "example.com".try_into()?; ``` -------------------------------- ### Build the project Source: https://github.com/balliegojr/simple-dns/blob/main/_autodocs/README.md Commands to build the project with different feature sets, including standard, no_std with alloc, and minimal configurations. ```bash # Standard library cargo build # no_std with alloc cargo build --no-default-features --features alloc # Minimal (stack only) cargo build --no-default-features ``` -------------------------------- ### Perform DNS type and code conversions Source: https://github.com/balliegojr/simple-dns/blob/main/_autodocs/api-reference/header-flags.md Demonstrates converting between TYPE, QTYPE, and RCODE, including handling unknown types. ```rust use simple_dns::{TYPE, QTYPE, RCODE}; // TYPE to QTYPE let qtype = QTYPE::TYPE(TYPE::A); // u16 to TYPE let type_code: u16 = 1; let type_enum = TYPE::from(type_code); // TYPE::A // Check if TYPE is Unknown if let TYPE::Unknown(code) = type_enum { println!("Unknown type: {}", code); } // RCODE from u16 let response_code = RCODE::from(3u16); // RCODE::NameError ``` -------------------------------- ### Build a DNS query in Rust Source: https://github.com/balliegojr/simple-dns/blob/main/_autodocs/getting-started.md Shows how to construct a new query packet, set flags, add a question, and serialize the packet to bytes. ```rust use simple_dns::{Packet, Question, Name, QTYPE, QCLASS, CLASS, TYPE, PacketFlag}; fn create_a_query() -> simple_dns::Result> { // Create query packet let mut packet = Packet::new_query(12345); // packet ID // Set flags packet.set_flags(PacketFlag::RECURSION_DESIRED); // Add a question let question = Question::new( Name::new("example.com")?, QTYPE::TYPE(TYPE::A), QCLASS::CLASS(CLASS::IN), false, ); packet.questions.push(question); // Serialize to bytes packet.build_bytes_vec() } fn main() -> simple_dns::Result<()> { let query = create_a_query()?; println!("Query bytes: {:?}", query); // Send query to DNS server... Ok(()) } ``` -------------------------------- ### Question::new Source: https://github.com/balliegojr/simple-dns/blob/main/_autodocs/api-reference/question-resource-record.md Creates a new Question instance for querying DNS records. ```APIDOC ## Question::new ### Description Creates a new Question instance to be used in a DNS packet query. ### Parameters - **qname** (Name<'a>) - Required - Domain name to query for - **qtype** (QTYPE) - Required - Type of records to query (A, AAAA, MX, etc., or ANY) - **qclass** (QCLASS) - Required - Class of records (typically IN for Internet) - **unicast_response** (bool) - Required - Whether to request unicast instead of multicast response (mDNS) ### Returns - **Question<'a>** - New question object ### Example ```rust use simple_dns::{Question, Name, QTYPE, QCLASS, CLASS, TYPE}; let question = Question::new( Name::new("example.com")?, QTYPE::TYPE(TYPE::A), QCLASS::CLASS(CLASS::IN), false, ); ``` ``` -------------------------------- ### Run benchmarks Source: https://github.com/balliegojr/simple-dns/blob/main/_autodocs/README.md Commands to navigate to the benchmark directory and execute performance tests. ```bash cd simple-dns/bench cargo bench ``` -------------------------------- ### Get CharacterString length Source: https://github.com/balliegojr/simple-dns/blob/main/_autodocs/api-reference/character-string.md Returns the total length of the CharacterString, including the wire format length byte. ```rust let cs = CharacterString::new(b"hello")?; assert_eq!(cs.len(), 6); // 1 byte length + 5 bytes data ``` -------------------------------- ### Integrate simple-mdns with simple-dns Source: https://github.com/balliegojr/simple-dns/blob/main/_autodocs/api-reference/simple-mdns.md Demonstrates parsing DNS packets and accessing structures using the simple-dns and simple-mdns crates. ```rust use simple_dns::{Packet, ResourceRecord, Name, CLASS, TYPE}; use simple_mdns::InstanceInformation; // Parse DNS packet let packet = Packet::parse(&bytes)?; // Access DNS structures normally for question in &packet.questions { println!("Query: {}", question.qname); } // Build mDNS-specific responses // ... use simple_mdns utilities ``` -------------------------------- ### Create new TXT record Source: https://github.com/balliegojr/simple-dns/blob/main/_autodocs/api-reference/rdata-basic.md Initializes an empty TXT record instance. ```rust pub fn new() -> Self ``` -------------------------------- ### Convert QTYPE to and from wire format Source: https://github.com/balliegojr/simple-dns/blob/main/_autodocs/api-reference/header-flags.md Demonstrates converting between QTYPE variants and their corresponding u16 wire format codes. ```rust // From TYPE to QTYPE let qtype = QTYPE::TYPE(TYPE::A); let qtype_any = QTYPE::ANY; // Convert to u16 for wire format let code: u16 = qtype.into(); // Convert from u16 let parsed = QTYPE::try_from(1u16)?; // QTYPE::TYPE(TYPE::A) let zone_transfer = QTYPE::try_from(252u16)?; // QTYPE::AXFR ``` -------------------------------- ### CAA Record Structure and Usage Source: https://github.com/balliegojr/simple-dns/blob/main/_autodocs/api-reference/rdata-advanced.md Defines the Certification Authority Authorization record (Type 257) and provides an example of its instantiation. ```rust pub struct CAA<'a> { pub flags: u8, pub tag: CharacterString<'a>, pub value: CharacterString<'a>, } ``` ```rust let caa = CAA { flags: 0, tag: CharacterString::new(b"issue")?, value: CharacterString::new(b"letsencrypt.org")?, }; ``` -------------------------------- ### Add simple-mdns dependency Source: https://github.com/balliegojr/simple-dns/blob/main/_autodocs/README.md Include simple-dns and simple-mdns with sync and async-tokio features enabled. ```toml [dependencies] simple-dns = "0.12" simple-mdns = { version = "0.7", features = ["sync", "async-tokio"] } ``` -------------------------------- ### Build for Minimal Targets Source: https://github.com/balliegojr/simple-dns/blob/main/_autodocs/configuration.md Build commands for bare-metal environments without dynamic allocation. ```bash # Bare metal without alloc cargo build --target thumbv7em-none-eabihf --no-default-features # WebAssembly without std cargo build --target wasm32-unknown-unknown --no-default-features ``` -------------------------------- ### Question constructor signature Source: https://github.com/balliegojr/simple-dns/blob/main/_autodocs/api-reference/question-resource-record.md The signature for creating a new DNS question instance. ```rust pub fn new(qname: Name<'a>, qtype: QTYPE, qclass: QCLASS, unicast_response: bool) -> Self ``` -------------------------------- ### Build for Standard Targets Source: https://github.com/balliegojr/simple-dns/blob/main/_autodocs/configuration.md Standard build commands for environments with std enabled. ```bash # Linux, macOS, Windows, etc. cargo build cargo build --target x86_64-unknown-linux-gnu cargo build --target x86_64-apple-darwin ``` -------------------------------- ### Run tests Source: https://github.com/balliegojr/simple-dns/blob/main/_autodocs/README.md Commands to execute the test suite under various feature configurations. ```bash # All tests cargo test # With all features cargo test --all-features # no_std tests cargo test --no-default-features --features alloc ``` -------------------------------- ### Use QCLASS for queries Source: https://github.com/balliegojr/simple-dns/blob/main/_autodocs/api-reference/header-flags.md Shows instantiation and conversion of QCLASS variants to wire format. ```rust let qclass = QCLASS::CLASS(CLASS::IN); let qclass_any = QCLASS::ANY; let code: u16 = qclass.into(); let parsed = QCLASS::try_from(1u16)?; // QCLASS::CLASS(CLASS::IN) ``` -------------------------------- ### Add simple-dns dependency Source: https://github.com/balliegojr/simple-dns/blob/main/_autodocs/README.md Include the basic simple-dns crate in your Cargo.toml file. ```toml [dependencies] simple-dns = "0.12" ``` -------------------------------- ### Create New Query Packet Source: https://github.com/balliegojr/simple-dns/blob/main/_autodocs/api-reference/packet.md Initializes a new empty packet configured as a DNS query. ```rust pub fn new_query(id: u16) -> Self ``` ```rust use simple_dns::Packet; let mut packet = Packet::new_query(1234); packet.questions.push(question); ``` -------------------------------- ### Build a DNS Query Source: https://github.com/balliegojr/simple-dns/blob/main/_autodocs/README.md Construct a new DNS query packet with a specific question. ```rust use simple_dns::{Packet, Question, Name, QTYPE, QCLASS, CLASS, TYPE}; let mut packet = Packet::new_query(12345); packet.questions.push(Question::new( Name::new("example.com")?, QTYPE::TYPE(TYPE::A), QCLASS::CLASS(CLASS::IN), false, )); let bytes = packet.build_bytes_vec()?; ``` -------------------------------- ### Importing simple-dns structures Source: https://github.com/balliegojr/simple-dns/blob/main/_autodocs/module-summary.md Basic imports required to utilize DNS packet and resource record structures. ```rust use simple_dns::{Packet, ResourceRecord, Name, TYPE, CLASS}; use simple_dns::rdata::RData; ``` -------------------------------- ### Configure Cargo dependencies for alloc Source: https://github.com/balliegojr/simple-dns/blob/main/_autodocs/configuration.md Configuration for no_std environments with heap support enabled. ```toml [dependencies] simple-dns = { version = "0.12", default-features = false, features = ["alloc"] } ``` ```toml simple-dns = { version = "0.12", default-features = false, features = ["alloc"] } ``` -------------------------------- ### Create and Write DNS Packet Source: https://github.com/balliegojr/simple-dns/blob/main/simple-dns/README.md Construct a DNS query packet, add questions and additional records, and write it to a buffer or a Vec. Ensure correct imports for Packet, Name, TYPE, CLASS, and RData. ```rust use simple_dns::*; use simple_dns::rdata::*; let mut packet = Packet::new_query(1); let question = Question::new(Name::new_unchecked("_srv._udp.local"), TYPE::TXT.into(), CLASS::IN.into(), false); packet.questions.push(question); let resource = ResourceRecord::new(Name::new_unchecked("_srv._udp.local"), CLASS::IN, 10, RData::A(A { address: 10 })); packet.additional_records.push(resource); // Write the packet in the provided buffer; let mut bytes = [0u8; 200]; assert!(packet.write_to(&mut &mut bytes[..]).is_ok()); // Same as above, but allocates and returns a Vec let bytes = packet.build_bytes_vec(); assert!(bytes.is_ok()); // Same as above, but Names are compressed let bytes = packet.build_bytes_vec_compressed(); assert!(bytes.is_ok()); ``` -------------------------------- ### Service Discovery with Sync Discovery Source: https://github.com/balliegojr/simple-dns/blob/main/simple-mdns/README.md Use ServiceDiscovery to register and manage service instances. It requires instance information and service name. Services can be removed from discovery. ```rust # #[cfg(feature = "sync")] { use simple_mdns::sync_discovery::ServiceDiscovery; use simple_mdns::InstanceInformation; use std::str::FromStr; let mut discovery = ServiceDiscovery::new( InstanceInformation::new("a".into()).with_socket_address("192.168.1.22:8090".parse().expect("Invalid socket address")), "_mysrv._tcp.local", 60 ).expect("Failed to start service discovery"); // Removing service from discovery discovery.remove_service_from_discovery(); # } ``` -------------------------------- ### Enable DNS Name Compression Source: https://github.com/balliegojr/simple-dns/blob/main/_autodocs/configuration.md Demonstrates the difference between compressed and uncompressed packet serialization to reduce payload size. ```rust use simple_dns::Packet; use std::io::Cursor; let mut packet = Packet::new_reply(1); // ... add answers ... // Compressed (smaller) let compressed = packet.build_bytes_vec_compressed()?; // Uncompressed let uncompressed = packet.build_bytes_vec()?; ``` -------------------------------- ### TXT::new() Source: https://github.com/balliegojr/simple-dns/blob/main/_autodocs/api-reference/rdata-basic.md Creates an empty TXT record instance. ```APIDOC ## TXT::new() ### Description Creates an empty TXT record. ### Signature `pub fn new() -> Self` ``` -------------------------------- ### Run Tests with Feature Flags Source: https://github.com/balliegojr/simple-dns/blob/main/_autodocs/configuration.md Commands to execute tests using different feature configurations. ```bash # Default (std) cargo test # With alloc only cargo test --no-default-features --features alloc # No features at all cargo test --no-default-features # All features explicitly cargo test --all-features ``` -------------------------------- ### Export Public API in lib.rs Source: https://github.com/balliegojr/simple-dns/blob/main/_autodocs/module-summary.md The entry point for the crate, exposing the primary DNS types and the custom Result alias. ```rust pub use simple_dns_error::SimpleDnsError; pub use dns::*; // All DNS types pub type Result = core::result::Result; ``` -------------------------------- ### Create New Reply Packet Source: https://github.com/balliegojr/simple-dns/blob/main/_autodocs/api-reference/packet.md Initializes a new empty packet configured as a DNS response. ```rust pub fn new_reply(id: u16) -> Self ``` ```rust let reply_packet = Packet::new_reply(1234); ``` -------------------------------- ### Build DNS Response in Rust Source: https://github.com/balliegojr/simple-dns/blob/main/_autodocs/README.md Creates a reply packet based on a query and serializes the response into a compressed byte vector. ```rust let mut response = Packet::new_reply(query.id()); for question in &query.questions { // Build answer for each question let answer = ResourceRecord::new(/* ... */); response.answers.push(answer); } let bytes = response.build_bytes_vec_compressed()?; ``` -------------------------------- ### Build TXT record with string Source: https://github.com/balliegojr/simple-dns/blob/main/_autodocs/api-reference/rdata-basic.md Uses the builder pattern to add a string and return the modified instance. ```rust pub fn with_string(mut self, char_string: &'a str) -> crate::Result ``` ```rust use simple_dns::rdata::TXT; let txt = TXT::new() .with_string("v=spf1 include:_spf.example.com ~all")?; ``` -------------------------------- ### Create new ResourceRecord Source: https://github.com/balliegojr/simple-dns/blob/main/_autodocs/api-reference/question-resource-record.md Constructor for initializing a new ResourceRecord instance. ```rust pub fn new(name: Name<'a>, class: CLASS, ttl: u32, rdata: RData<'a>) -> Self ``` ```rust use simple_dns::{ResourceRecord, Name, CLASS, rdata::RData}; let record = ResourceRecord::new( Name::new("example.com")?, CLASS::IN, 300, RData::A(simple_dns::rdata::A { address: 0x7f000001 }), ); ``` -------------------------------- ### Define async_discovery Module Source: https://github.com/balliegojr/simple-dns/blob/main/_autodocs/api-reference/simple-mdns.md Provides asynchronous mDNS discovery using Tokio's async/await syntax. ```rust pub mod async_discovery { pub struct ServiceDiscovery { // Fields hidden } } ``` -------------------------------- ### Initialize a Mailbox RData record Source: https://github.com/balliegojr/simple-dns/blob/main/_autodocs/api-reference/rdata-basic.md Creates a new MB record using a Name instance. Requires the Name to be valid. ```rust let name_rdata = MB(Name::new("mailbox.example.com")?); ``` -------------------------------- ### Configure Cargo dependencies for bare minimum Source: https://github.com/balliegojr/simple-dns/blob/main/_autodocs/configuration.md Configuration for stack-only operations without heap allocation. ```toml simple-dns = { version = "0.12", default-features = false } ``` -------------------------------- ### Configure Cargo dependencies for std Source: https://github.com/balliegojr/simple-dns/blob/main/_autodocs/configuration.md Default configuration enabling standard library support. ```toml [dependencies] simple-dns = "0.12" # std is enabled by default ``` ```toml simple-dns = "0.12" ``` -------------------------------- ### Build for Embedded Targets with Alloc Source: https://github.com/balliegojr/simple-dns/blob/main/_autodocs/configuration.md Build commands for no_std environments that support dynamic allocation. ```bash # ARM Cortex-M with alloc cargo build --target thumbv7em-none-eabihf --no-default-features --features alloc # RISC-V with alloc cargo build --target riscv64gc-unknown-none-elf --no-default-features --features alloc ``` -------------------------------- ### Build a DNS Response Source: https://github.com/balliegojr/simple-dns/blob/main/_autodocs/README.md Construct a new DNS reply packet containing a resource record. ```rust use simple_dns::{Packet, ResourceRecord, Name, CLASS}; use simple_dns::rdata::A; let mut packet = Packet::new_reply(12345); let record = ResourceRecord::new( Name::new("example.com")?, CLASS::IN, 300, simple_dns::rdata::RData::A(A { address: 0x7f000001 }), ); packet.answers.push(record); ``` -------------------------------- ### Build a DNS Response Packet in Rust Source: https://github.com/balliegojr/simple-dns/blob/main/_autodocs/getting-started.md Creates a DNS reply packet with an authoritative A record and serializes it using compression. ```rust use simple_dns::{Packet, ResourceRecord, Name, CLASS, PacketFlag}; use simple_dns::rdata::A; use std::net::Ipv4Addr; fn create_response_packet() -> simple_dns::Result> { // Build reply from original query let mut response = Packet::new_reply(12345); // original query ID // Add authoritative answer let record = ResourceRecord::new( Name::new("example.com")?, CLASS::IN, 300, simple_dns::rdata::RData::A(A { address: 0x7f000001 }), // 127.0.0.1 ); response.answers.push(record); // Serialize with compression for optimal size response.build_bytes_vec_compressed() } ``` -------------------------------- ### Configure no_std Entry Point Source: https://github.com/balliegojr/simple-dns/blob/main/_autodocs/configuration.md Defines the crate entry point for no_std environments with conditional feature exports. ```rust #![no_std] extern crate alloc; // Public re-exports available in any feature combination: pub use simple_dns_error::SimpleDnsError; pub use dns::*; // All DNS types // Conditionally available: #[cfg(feature = "std")] pub use std::io::Cursor; #[cfg(feature = "alloc")] pub use alloc::vec::Vec; ``` -------------------------------- ### Create new Label Source: https://github.com/balliegojr/simple-dns/blob/main/_autodocs/api-reference/name.md Constructor for creating a validated Label instance. ```rust pub fn new>>(data: T) -> crate::Result ``` ```rust use simple_dns::Label; let label = Label::new("example")?; let invalid = Label::new("a-b--c"); // Invalid if ends with hyphen ``` -------------------------------- ### Initialize HINFO record Source: https://github.com/balliegojr/simple-dns/blob/main/_autodocs/api-reference/character-string.md Creates an HINFO record using CharacterString for CPU and OS fields. ```rust use simple_dns::rdata::HINFO; let hinfo = HINFO { cpu: CharacterString::new(b"Intel-PC")?, os: CharacterString::new(b"Linux")?, }; ``` -------------------------------- ### Discover Services Synchronously with mDNS Source: https://github.com/balliegojr/simple-dns/blob/main/_autodocs/getting-started.md Requires the 'sync' feature enabled. Searches for services matching a specific service type string. ```rust use simple_mdns::InstanceInformation; #[cfg(feature = "sync")] fn discover_http_services() -> Result<(), Box> { use simple_mdns::sync_discovery::ServiceDiscovery; let discovery = ServiceDiscovery::new( InstanceInformation::default(), )?; // Search for HTTP services let services = discovery.search("_http._tcp.local")?; for service in services { println!("Found service: {}", service.name); for ip in service.ip_addresses { println!(" Address: {}", ip); } } Ok(()) } ``` -------------------------------- ### Define Question struct Source: https://github.com/balliegojr/simple-dns/blob/main/_autodocs/api-reference/question-resource-record.md The structure definition for a DNS query question. ```rust pub struct Question<'a> { pub qname: Name<'a>, pub qtype: QTYPE, pub qclass: QCLASS, pub unicast_response: bool, } ``` -------------------------------- ### Query MX Records in Rust Source: https://github.com/balliegojr/simple-dns/blob/main/_autodocs/getting-started.md Constructs a DNS query packet for mail server records and demonstrates how to serialize the packet to bytes. ```rust use simple_dns::{Packet, Name, QTYPE, QCLASS, CLASS, TYPE}; use simple_dns::rdata::RData; fn query_mx_records(domain: &str) -> simple_dns::Result<()> { let mut packet = Packet::new_query(2); let question = simple_dns::Question::new( Name::new(domain)?, QTYPE::TYPE(TYPE::MX), QCLASS::CLASS(CLASS::IN), false, ); packet.questions.push(question); let query_bytes = packet.build_bytes_vec()?; // Send query_bytes to resolver, parse response: // let response = Packet::parse(&response)?; // for answer in response.answers { // if let RData::MX(mx) = answer.rdata { // println!("Server: {} (preference: {})", mx.exchange, mx.preference); // } // } Ok(()) } ``` -------------------------------- ### Parse a DNS packet in Rust Source: https://github.com/balliegojr/simple-dns/blob/main/_autodocs/getting-started.md Demonstrates parsing raw bytes into a Packet structure and iterating over questions and answers. ```rust use simple_dns::Packet; fn parse_dns_response(data: &[u8]) -> simple_dns::Result<()> { // Parse the packet let packet = Packet::parse(data)?; println!("Packet ID: {}", packet.id()); println!("Is response: {}", packet.has_flags(simple_dns::PacketFlag::RESPONSE)); // Iterate questions for question in &packet.questions { println!("Question: {} (type: {:?})", question.qname, question.qtype); } // Iterate answers for answer in &packet.answers { println!("Answer: {} -> {:?}", answer.name, answer.rdata); } Ok(()) } ``` -------------------------------- ### Name::new Source: https://github.com/balliegojr/simple-dns/blob/main/_autodocs/api-reference/name.md Creates a new Name instance with validation for size limits and content. ```APIDOC ## Name::new ### Description Creates a new Name with validation of size limits and content. ### Parameters - **name** (&'a str) - Required - Domain name as a string (e.g., "example.com") ### Returns - Result> - Validated name or error ### Throws - InvalidServiceName - If name exceeds 255 characters - InvalidServiceLabel - If any label is invalid ``` -------------------------------- ### Export simple-dns modules Source: https://github.com/balliegojr/simple-dns/blob/main/_autodocs/README.md Primary exports for the simple-dns crate, including error handling and DNS functionality. ```rust pub use simple_dns_error::SimpleDnsError; pub use dns::*; pub type Result = core::result::Result; ``` -------------------------------- ### Create Name with validation Source: https://github.com/balliegojr/simple-dns/blob/main/_autodocs/api-reference/name.md Constructs a Name while enforcing DNS length and character constraints. ```rust pub fn new(name: &'a str) -> crate::Result ``` ```rust use simple_dns::Name; let name = Name::new("example.com")?; let invalid = Name::new("a".repeat(256)); // Error: too long ``` -------------------------------- ### Validate domain names Source: https://github.com/balliegojr/simple-dns/blob/main/_autodocs/getting-started.md Uses the Name::new() constructor to verify domain name formatting. ```rust use simple_dns::Name; fn validate_domain(input: &str) -> bool { match Name::new(input) { Ok(_) => true, Err(_) => false, } } ``` -------------------------------- ### Define sync_discovery Module Source: https://github.com/balliegojr/simple-dns/blob/main/_autodocs/api-reference/simple-mdns.md Provides synchronous mDNS discovery using blocking network operations. ```rust pub mod sync_discovery { pub struct ServiceDiscovery { // Fields hidden } } ``` -------------------------------- ### Discover Services via mDNS Source: https://github.com/balliegojr/simple-dns/blob/main/_autodocs/README.md Perform asynchronous service discovery for a specific service type. ```rust use simple_mdns::async_discovery::ServiceDiscovery; let discovery = ServiceDiscovery::new(Default::default()).await?; let services = discovery.search("_http._tcp.local").await?; for service in services { println!("Found: {}", service.name); } ``` -------------------------------- ### Discover Services Asynchronously Source: https://github.com/balliegojr/simple-dns/blob/main/_autodocs/api-reference/simple-mdns.md Uses the async ServiceDiscovery to search for services on the network. ```rust #[tokio::main] async fn main() -> Result<(), Box> { let discovery = simple_mdns::async_discovery::ServiceDiscovery::new( InstanceInformation::default(), ).await?; let services = discovery.search("_http._tcp.local").await?; for service in services { println!("Found: {}", service.name); } Ok(()) } ``` -------------------------------- ### Register Service Synchronously Source: https://github.com/balliegojr/simple-dns/blob/main/_autodocs/api-reference/simple-mdns.md Registers a service using the sync ServiceDiscovery; the service persists until the discovery object is dropped. ```rust use simple_mdns::sync_discovery::ServiceDiscovery; use std::net::Ipv4Addr; let discovery = ServiceDiscovery::new( InstanceInformation::default(), )?; discovery.register_service( "_http._tcp.local", "MyService", 8080, Ipv4Addr::new(192, 168, 1, 100), )?; // Service remains registered until dropped ``` -------------------------------- ### Define TXT record Source: https://github.com/balliegojr/simple-dns/blob/main/_autodocs/types.md Represents a Text record. ```rust pub struct TXT<'a> { strings: Vec>, size: usize, } ``` -------------------------------- ### Build Custom mDNS Responses Source: https://github.com/balliegojr/simple-dns/blob/main/_autodocs/api-reference/simple-mdns.md Constructs a custom mDNS reply by managing resource records and parsing incoming queries. ```rust use simple_mdns::{build_reply, conversion_utils::*}; use simple_dns::{Name, ResourceRecord, Packet}; let mut resources = ResourceRecordManager::new(); // Add service records let srv = port_to_srv_record( &Name::new("_service._tcp.local")?, 8080, 4500, ); resources.add_authoritative_resource(srv); // Build reply let query = Packet::parse(&raw_query)?; if let Some((reply, _)) = build_reply(query, &resources) { let bytes = reply.build_bytes_vec()?; send_response(&bytes); } ``` -------------------------------- ### build_reply Source: https://github.com/balliegojr/simple-dns/blob/main/_autodocs/api-reference/simple-mdns.md Constructs an mDNS reply packet based on an incoming query and a set of known resource records. ```APIDOC ## build_reply(packet, resources) ### Description Builds an mDNS reply packet for incoming queries. It automatically handles unicast response requests and includes additional records like A/AAAA for SRV targets. ### Parameters - **packet** (Packet) - Required - Incoming query packet - **resources** (&ResourceRecordManager) - Required - Known resource records to answer with ### Returns - **Option<(Packet<'b>, bool)>** - Reply packet and unicast flag, or None if no answers are found. ### Example ```rust use simple_mdns::{build_reply, resource_record_manager::ResourceRecordManager}; use simple_dns::Packet; let incoming = Packet::parse(&raw_bytes)?; let resources = ResourceRecordManager::new(); if let Some((reply, unicast)) = build_reply(incoming, &resources) { if unicast { // Send unicast response } else { // Send multicast response } } ``` ``` -------------------------------- ### Configure UDP Packet Size Source: https://github.com/balliegojr/simple-dns/blob/main/_autodocs/configuration.md Sets the initial capacity for the byte vector to accommodate standard or jumbo DNS packets. ```rust pub fn build_bytes_vec(&self) -> crate::Result> { let mut out = Vec::with_capacity(900); // 900 bytes = max jumbo UDP packet minus headers } ``` -------------------------------- ### Add simple-mdns to Cargo.toml Source: https://github.com/balliegojr/simple-dns/blob/main/_autodocs/getting-started.md Include the simple-mdns dependency with specific features enabled. ```toml simple-mdns = { version = "0.7", features = ["sync", "async-tokio"] } ``` -------------------------------- ### Add strings to TXT record Source: https://github.com/balliegojr/simple-dns/blob/main/_autodocs/api-reference/character-string.md Demonstrates adding multiple character strings to a TXT record. ```rust use simple_dns::rdata::TXT; use simple_dns::CharacterString; let mut txt = TXT::new(); txt.add_string("v=spf1 include:_spf.example.com ~all")?; txt.add_string("google-site-verification=abcdef123456")?; ``` -------------------------------- ### Use SimpleDnsError in no_std Environments Source: https://github.com/balliegojr/simple-dns/blob/main/_autodocs/errors.md Shows that SimpleDnsError is compatible with no_std environments by parsing packets without std dependencies. ```rust #![no_std] extern crate alloc; use simple_dns::{Packet, SimpleDnsError}; fn parse_packet(data: &[u8]) -> Result { Packet::parse(data) } ``` -------------------------------- ### Parse from wire format Source: https://github.com/balliegojr/simple-dns/blob/main/_autodocs/api-reference/question-resource-record.md Parses a resource record from a raw DNS wire format buffer. ```rust fn parse(data: &mut BytesBuffer<'a>) -> crate::Result ``` ```rust let mut buffer = BytesBuffer::new(raw_bytes); let record = ResourceRecord::parse(&mut buffer)?; ``` -------------------------------- ### Query TXT Records in Rust Source: https://github.com/balliegojr/simple-dns/blob/main/_autodocs/getting-started.md Constructs a DNS query packet specifically for TXT records. Requires handling the response by iterating over the packet's answers and matching against RData::TXT. ```rust use simple_dns::{Packet, Name, QTYPE, QCLASS, CLASS, TYPE}; use simple_dns::rdata::RData; fn query_txt_records(domain: &str) -> simple_dns::Result<()> { let mut packet = Packet::new_query(3); let question = simple_dns::Question::new( Name::new(domain)?, QTYPE::TYPE(TYPE::TXT), QCLASS::CLASS(CLASS::IN), false, ); packet.questions.push(question); // After receiving response: // for answer in response.answers { // if let RData::TXT(txt) = answer.rdata { // for (key, val) in txt.iter_raw() { // println!("TXT: {} = {:?}", // String::from_utf8_lossy(key), // val); // } // } // } Ok(()) } ``` -------------------------------- ### Enable logging via environment variable Source: https://github.com/balliegojr/simple-dns/blob/main/_autodocs/api-reference/simple-mdns.md Set the RUST_LOG environment variable to control the verbosity of the simple-mdns library during execution. ```bash RUST_LOG=simple_mdns=debug cargo run ``` -------------------------------- ### Serialize record to wire format in Rust Source: https://github.com/balliegojr/simple-dns/blob/main/_autodocs/api-reference/question-resource-record.md Writes the record to a writer in DNS wire format without compression. ```rust fn write_to(&self, out: &mut T) -> crate::Result<()> ``` -------------------------------- ### Implement query retry logic Source: https://github.com/balliegojr/simple-dns/blob/main/_autodocs/getting-started.md Handles potential packet loss in UDP-based DNS communication by retrying failed requests. ```rust fn query_with_retry(query: &[u8], max_retries: u32) -> Result, String> { for attempt in 0..max_retries { // Send query to server match send_and_receive(query) { Ok(response) => return Ok(response), Err(e) if attempt < max_retries - 1 => { eprintln!("Attempt {} failed, retrying...", attempt + 1); std::thread::sleep(std::time::Duration::from_millis(100)); } Err(e) => return Err(e.to_string()), } } unreachable!() } ``` -------------------------------- ### Define InstanceInformation struct Source: https://github.com/balliegojr/simple-dns/blob/main/_autodocs/api-reference/simple-mdns.md Represents information about an mDNS service instance. ```rust pub struct InstanceInformation { // Fields hidden } ``` -------------------------------- ### Parse DNS Names Source: https://github.com/balliegojr/simple-dns/blob/main/_autodocs/getting-started.md Use standard parsing for user input and new_unchecked for testing scenarios. ```rust // For trusted input: let name = Name::new(user_input)?; // For testing only: let name = Name::new_unchecked(test_data); ``` -------------------------------- ### Build mDNS reply packets Source: https://github.com/balliegojr/simple-dns/blob/main/_autodocs/module-summary.md Generates responses to incoming queries using the provided packet and resource manager. ```rust pub fn build_reply<'b>( packet: Packet, resources: &'b ResourceRecordManager<'b>, ) -> Option<(Packet<'b>, bool)> ``` -------------------------------- ### Match query class Source: https://github.com/balliegojr/simple-dns/blob/main/_autodocs/api-reference/question-resource-record.md Checks if the record matches a specific DNS query class. ```rust pub fn match_qclass(&self, qclass: QCLASS) -> bool ``` -------------------------------- ### Serialize record with compression in Rust Source: https://github.com/balliegojr/simple-dns/blob/main/_autodocs/api-reference/question-resource-record.md Writes the record with DNS name compression enabled, requiring a seekable writer and a map for name pointer tracking. ```rust fn write_compressed_to( &'a self, out: &mut T, name_refs: &mut BTreeMap<&[Label<'a>], u16>, ) -> crate::Result<()> ``` -------------------------------- ### Create Name from labels Source: https://github.com/balliegojr/simple-dns/blob/main/_autodocs/api-reference/name.md Constructs a Name from a slice of pre-existing Label objects. ```rust pub fn new_with_labels(labels: &[Label<'a>]) -> Self ``` ```rust let label1 = Label::new_unchecked("example"); let label2 = Label::new_unchecked("com"); let name = Name::new_with_labels(&[label1, label2]); ``` -------------------------------- ### Parse a DNS Packet Source: https://github.com/balliegojr/simple-dns/blob/main/_autodocs/README.md Parse raw bytes into a DNS packet and iterate over questions and answers. ```rust use simple_dns::Packet; let packet = Packet::parse(&raw_bytes)?; for question in &packet.questions { println!("Query: {}", question.qname); } for answer in &packet.answers { println!("Answer: {}", answer.name); } ``` -------------------------------- ### TXT::with_string() Source: https://github.com/balliegojr/simple-dns/blob/main/_autodocs/api-reference/rdata-basic.md Builder pattern method that adds a string and returns the modified TXT instance. ```APIDOC ## TXT::with_string() ### Description Builder pattern: adds a string and returns self. ### Signature `pub fn with_string(mut self, char_string: &'a str) -> crate::Result` ### Returns `Result` — Self with string added ``` -------------------------------- ### Validate Label Source: https://github.com/balliegojr/simple-dns/blob/main/_autodocs/api-reference/name.md Checks if the label conforms to standard DNS requirements. ```rust pub fn is_valid(&self) -> bool ``` -------------------------------- ### Name::new_with_labels Source: https://github.com/balliegojr/simple-dns/blob/main/_autodocs/api-reference/name.md Creates a Name instance from a slice of pre-constructed Label objects. ```APIDOC ## Name::new_with_labels ### Description Creates a Name from pre-constructed labels. Allows labels with dots in them. ### Parameters - **labels** (&[Label<'a>]) - Required - Array or slice of Label objects ### Returns - Name<'a> - Combined name from labels ``` -------------------------------- ### Label::new Source: https://github.com/balliegojr/simple-dns/blob/main/_autodocs/api-reference/name.md Creates a validated Label with size and content checks. Throws an error if the label is empty, exceeds 63 characters, or contains invalid characters. ```APIDOC ## Label::new ### Description Creates a validated Label with size and content checks. ### Parameters - **data** (T) - Required - Label bytes or string ### Returns - **Result>** - Validated label or error ### Throws - **InvalidServiceLabel** - If label is empty, exceeds 63 chars, or contains invalid characters ``` -------------------------------- ### Define OPT record Source: https://github.com/balliegojr/simple-dns/blob/main/_autodocs/types.md Represents an EDNS extension record. ```rust pub struct OPT<'a> { pub opt_codes: Vec>, pub udp_packet_size: u16, pub version: u8, } ``` -------------------------------- ### Define A record Source: https://github.com/balliegojr/simple-dns/blob/main/_autodocs/types.md Represents an IPv4 address record. ```rust pub struct A { pub address: u32, } ``` -------------------------------- ### Define PTR record Source: https://github.com/balliegojr/simple-dns/blob/main/_autodocs/api-reference/rdata-basic.md Defines a pointer record for reverse DNS lookups. ```rust pub struct PTR<'a>(pub Name<'a>); ``` ```rust use simple_dns::rdata::PTR; let ptr = PTR(Name::new("host.example.com")?); let record = ResourceRecord::new( Name::new("1.0.0.127.in-addr.arpa")?, // 127.0.0.1 reversed CLASS::IN, 3600, RData::PTR(ptr), ); ``` -------------------------------- ### write_to Source: https://github.com/balliegojr/simple-dns/blob/main/_autodocs/api-reference/question-resource-record.md Writes the record to a writer in DNS wire format without compression. ```APIDOC ## fn write_to(&self, out: &mut T) -> crate::Result<()> ### Description Writes the record to a writer in DNS wire format without compression. ### Parameters - **out** (&mut T) - Required - Writer implementing Write trait ### Returns - **Result<()>** - Success or error ``` -------------------------------- ### Name API Source: https://github.com/balliegojr/simple-dns/blob/main/_autodocs/module-summary.md Methods for managing domain names and labels. ```APIDOC ## Name API ### Description Handles domain name representation and validation. ### Key Methods - **Name::new(name: &str)** - Create a new Name with validation. - **Name::new_unchecked(name: &str)** - Create a new Name without validation. - **is_link_local()** - Check if the name has a .local suffix. - **is_subdomain_of(other: &Name)** - Check domain hierarchy. - **iter()** - Iterate over the labels of the name. ``` -------------------------------- ### Packet::new_query Source: https://github.com/balliegojr/simple-dns/blob/main/_autodocs/api-reference/packet.md Creates a new empty packet configured as a DNS query. ```APIDOC ## Packet::new_query(id: u16) ### Description Creates a new empty packet configured as a DNS query. ### Parameters - **id** (u16) - Required - Packet identifier used to match queries with responses ### Returns - **Packet<'a>** - A new query packet with empty sections ``` -------------------------------- ### Query A Records in Rust Source: https://github.com/balliegojr/simple-dns/blob/main/_autodocs/getting-started.md Constructs a DNS query packet for an IPv4 address using the A record type. ```rust use simple_dns::{Packet, Name, QTYPE, QCLASS, CLASS, TYPE, PacketFlag}; use simple_dns::rdata::RData; fn query_a_record(domain: &str) -> simple_dns::Result<()> { // Build query let mut packet = Packet::new_query(1); packet.set_flags(PacketFlag::RECURSION_DESIRED); let question = simple_dns::Question::new( Name::new(domain)?, QTYPE::TYPE(TYPE::A), QCLASS::CLASS(CLASS::IN), false, ); packet.questions.push(question); // Would send to resolver here, then: // let response = Packet::parse(&response_bytes)?; Ok(()) } ``` -------------------------------- ### Define ResourceRecord struct Source: https://github.com/balliegojr/simple-dns/blob/main/_autodocs/api-reference/question-resource-record.md The structure definition for a DNS resource record. ```rust pub struct ResourceRecord<'a> { pub name: Name<'a>, pub class: CLASS, pub ttl: u32, pub rdata: RData<'a>, pub cache_flush: bool, } ``` -------------------------------- ### Build mDNS Reply Packet Source: https://github.com/balliegojr/simple-dns/blob/main/_autodocs/api-reference/simple-mdns.md Constructs an mDNS reply packet for incoming queries, returning the packet and a unicast flag. ```rust pub fn build_reply<'b>( packet: Packet, resources: &'b ResourceRecordManager<'b>, ) -> Option<(Packet<'b>, bool)> ``` ```rust use simple_mdns::{build_reply, resource_record_manager::ResourceRecordManager}; use simple_dns::Packet; let incoming = Packet::parse(&raw_bytes)?; let resources = ResourceRecordManager::new(); if let Some((reply, unicast)) = build_reply(incoming, &resources) { if unicast { // Send unicast response } else { // Send multicast response } } ``` -------------------------------- ### Graceful Shutdown for Async SimpleMdnsResponder Source: https://github.com/balliegojr/simple-dns/blob/main/simple-mdns/README.md The async SimpleMdnsResponder can be initialized with a shutdown signal channel for graceful termination. Sending a signal on the channel stops the responder loop. ```rust # #[cfg(feature = "async-tokio")] { use simple_mdns::async_discovery::SimpleMdnsResponder; use simple_mdns::NetworkScope; use simple_dns::{Name, CLASS, ResourceRecord, rdata::{RData, A, SRV}}; use std::net::{IpAddr, Ipv4Addr, SocketAddr}; let (shutdown_tx, shutdown_rx) = tokio::sync::oneshot::channel::<()>(); let mut responder = SimpleMdnsResponder::new_with_scope(10, NetworkScope::V4, Some(shutdown_rx)); // This will stop the responder loop shutdown_tx.send(()).expect("Failed to send shutdown signal"); # } ``` -------------------------------- ### Convert Question to owned Source: https://github.com/balliegojr/simple-dns/blob/main/_autodocs/api-reference/question-resource-record.md Method signature for transforming a borrowed Question into an owned version. ```rust pub fn into_owned<'b>(self) -> Question<'b> ``` -------------------------------- ### write_compressed_to Source: https://github.com/balliegojr/simple-dns/blob/main/_autodocs/api-reference/question-resource-record.md Writes the record with DNS name compression enabled. ```APIDOC ## fn write_compressed_to(&'a self, out: &mut T, name_refs: &mut BTreeMap<&[Label<'a>], u16>) -> crate::Result<()> ### Description Writes the record with DNS name compression enabled. ### Parameters - **out** (&mut T) - Required - Seekable writer - **name_refs** (&mut BTreeMap) - Required - Map tracking name pointer positions ### Returns - **Result<()>** - Success or error ``` -------------------------------- ### Define QTYPE enumeration Source: https://github.com/balliegojr/simple-dns/blob/main/_autodocs/api-reference/header-flags.md Represents query types for DNS packet questions, extending standard TYPE values with special query types. ```rust pub enum QTYPE { TYPE(TYPE), IXFR, AXFR, MAILB, MAILA, ANY, } ``` -------------------------------- ### Define CNAME record Source: https://github.com/balliegojr/simple-dns/blob/main/_autodocs/api-reference/rdata-basic.md Defines a canonical name alias record. ```rust pub struct CNAME<'a>(pub Name<'a>); ``` ```rust use simple_dns::rdata::CNAME; let cname = CNAME(Name::new("actual.example.com")?); let record = ResourceRecord::new( Name::new("alias.example.com")?, CLASS::IN, 300, RData::CNAME(cname), ); ``` -------------------------------- ### Define EUI48 and EUI64 structures Source: https://github.com/balliegojr/simple-dns/blob/main/_autodocs/api-reference/rdata-advanced.md Structures for IEEE Extended Unique Identifiers used for hardware device identification. ```rust pub struct EUI48 { pub eui: [u8; 6], } pub struct EUI64 { pub eui: [u8; 8], } ``` -------------------------------- ### Match query type Source: https://github.com/balliegojr/simple-dns/blob/main/_autodocs/api-reference/question-resource-record.md Checks if the record matches a specific DNS query type. ```rust pub fn match_qtype(&self, qtype: QTYPE) -> bool ``` -------------------------------- ### Iterate over labels in a Name Source: https://github.com/balliegojr/simple-dns/blob/main/_autodocs/api-reference/name.md Iterates through the labels of a DNS name from left to right. ```rust for label in name.iter() { println!("Label: {}", label); } ``` -------------------------------- ### Manipulate and check PacketFlag Source: https://github.com/balliegojr/simple-dns/blob/main/_autodocs/api-reference/header-flags.md Demonstrates setting, checking, and removing flags on a DNS packet. ```rust use simple_dns::{Packet, PacketFlag}; let mut packet = Packet::new_query(1); packet.set_flags(PacketFlag::RECURSION_DESIRED); // Check for multiple flags if packet.has_flags(PacketFlag::RECURSION_DESIRED | PacketFlag::RECURSION_AVAILABLE) { println!("Recursion desired and available"); } // Remove a flag packet.remove_flags(PacketFlag::RECURSION_DESIRED); ``` -------------------------------- ### Configure cache flush Source: https://github.com/balliegojr/simple-dns/blob/main/_autodocs/api-reference/question-resource-record.md Builder method to set the cache flush flag for mDNS records. ```rust pub fn with_cache_flush(mut self, cache_flush: bool) -> Self ``` ```rust let record = ResourceRecord::new(...)? .with_cache_flush(true); ```