use trust_dns_proto::DnsHandle; use trust_dns_client::rr::{DNSClass, RecordType}; use trust_dns_client::op::{UpdateMessage, OpCode, MessageType, Message, Query}; use trust_dns_proto::error::ProtoError; use super::trust_dns_types::{Name, Record}; use super::client::{ClientResponse}; pub enum MessageError { RecordNotInZone { zone: Name, class: DNSClass, mismatched_class: Vec, mismatched_zone: Vec, } } pub trait DnsMessage: DnsHandle + Send { fn add_records(&mut self, zone: Name, class: DNSClass, new_records: Vec) -> Result, MessageError> { let mut mismatched_class = Vec::new(); let mut mismatched_zone = Vec::new(); for record in new_records.iter() { if !zone.zone_of(record.name()) { mismatched_zone.push(record.clone()); } if record.dns_class() != class { mismatched_class.push(record.clone()); } } if mismatched_class.len() > 0 || mismatched_zone.len() > 0 { return Err(MessageError::RecordNotInZone { zone, class, mismatched_zone, mismatched_class }) } let mut zone_query = Query::new(); zone_query.set_name(zone.clone()) .set_query_class(class) .set_query_type(RecordType::SOA); let mut message = Message::new(); // TODO: set random / time based id message .set_id(0) .set_message_type(MessageType::Query) .set_op_code(OpCode::Update) .set_recursion_desired(false); message.add_zone(zone_query); message.add_updates(new_records); { let edns = message.edns_mut(); edns.set_max_payload(1232); edns.set_version(0); } return Ok(ClientResponse(self.send(message))); } }