mirror of
https://github.com/NLnetLabs/domain.git
synced 2026-09-28 20:54:55 +02:00
Convert domain-tsig to new core.
This commit is contained in:
@@ -1,5 +1,3 @@
|
||||
[workspace]
|
||||
members = ["domain", "domain-core", "domain-resolv", "domain-sign", "domain-tsig", "domain-validate", "interop"]
|
||||
|
||||
[patch.crates-io]
|
||||
ring = { git = "https://github.com/andrewtj/ring.git", rev = "eedb0514fb73e1034eefbec10140af8a51effff3"}
|
||||
+19
-13
@@ -83,9 +83,9 @@ impl<Octets> Message<Octets> {
|
||||
/// # Header Section
|
||||
///
|
||||
impl<Octets: AsRef<[u8]>> Message<Octets> {
|
||||
/// Returns a reference to the message header.
|
||||
pub fn header(&self) -> &Header {
|
||||
Header::for_message_slice(self.as_slice())
|
||||
/// Returns a the message header.
|
||||
pub fn header(&self) -> Header {
|
||||
*Header::for_message_slice(self.as_slice())
|
||||
}
|
||||
|
||||
/// Returns a mutable reference to the message header.
|
||||
@@ -94,18 +94,14 @@ impl<Octets: AsRef<[u8]>> Message<Octets> {
|
||||
Header::for_message_slice_mut(self.as_slice_mut())
|
||||
}
|
||||
|
||||
/// Returns a reference the header counts of the message.
|
||||
pub fn header_counts(&self) -> &HeaderCounts {
|
||||
HeaderCounts::for_message_slice(self.as_slice())
|
||||
/// Returns the header counts of the message.
|
||||
pub fn header_counts(&self) -> HeaderCounts {
|
||||
*HeaderCounts::for_message_slice(self.as_slice())
|
||||
}
|
||||
|
||||
/// Returns a mutable reference to the header counts.
|
||||
///
|
||||
/// Since you can quite effectively break the message with this, it is
|
||||
/// private.
|
||||
pub fn header_counts_mut(&mut self) -> &mut HeaderCounts
|
||||
where Octets: AsMut<[u8]> {
|
||||
HeaderCounts::for_message_slice_mut(self.as_slice_mut())
|
||||
/// Returns the entire header section.
|
||||
pub fn header_section(&self) -> HeaderSection {
|
||||
*HeaderSection::for_message_slice(&self.as_slice())
|
||||
}
|
||||
|
||||
/// Returns whether the rcode is NoError.
|
||||
@@ -424,6 +420,11 @@ impl<Ref: OctetsRef> QuestionSection<Ref> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the current position relative to the beginning of the message.
|
||||
pub fn pos(&self) -> usize {
|
||||
self.parser.pos()
|
||||
}
|
||||
|
||||
/// Proceeds to the answer section.
|
||||
///
|
||||
/// Skips over any remaining questions and then converts itself into the
|
||||
@@ -556,6 +557,11 @@ impl<Ref: OctetsRef> RecordSection<Ref> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the current position relative to the beginning of the message.
|
||||
pub fn pos(&self) -> usize {
|
||||
self.parser.pos()
|
||||
}
|
||||
|
||||
/// Trades `self` in for an iterator limited to a concrete record type.
|
||||
///
|
||||
/// The record type is given through its record data type. Since the data
|
||||
|
||||
@@ -8,10 +8,12 @@ use core::ops::{Deref, DerefMut};
|
||||
#[cfg(feature = "bytes")] use bytes::BytesMut;
|
||||
use unwrap::unwrap;
|
||||
use crate::header::{Header, HeaderCounts, HeaderSection};
|
||||
use crate::iana::{OptionCode, OptRcode};
|
||||
use crate::iana::{OptionCode, OptRcode, Rcode, Rtype};
|
||||
use crate::message::Message;
|
||||
use crate::name::{ToDname, Label};
|
||||
use crate::octets::{Compose, IntoOctets, Octets64, OctetsBuilder, ShortBuf};
|
||||
use crate::octets::{
|
||||
Compose, IntoOctets, Octets64, OctetsBuilder, OctetsRef, ShortBuf
|
||||
};
|
||||
use crate::opt::{OptHeader, OptData};
|
||||
use crate::question::Question;
|
||||
use crate::rdata::RecordData;
|
||||
@@ -68,6 +70,45 @@ impl MessageBuilder<StreamTarget<BytesMut>> {
|
||||
}
|
||||
|
||||
impl<Target: OctetsBuilder> MessageBuilder<Target> {
|
||||
/// Starts creating an answer for the given message.
|
||||
///
|
||||
/// Specifically, this sets the ID, QR, OPCODE, RD, and RCODE fields
|
||||
/// in the header and attempts to push the message’s questions to the
|
||||
/// builder. If iterating of the questions fails, it adds what it can.
|
||||
pub fn start_answer<Octets>(
|
||||
mut self,
|
||||
msg: &Message<Octets>,
|
||||
rcode: Rcode,
|
||||
) -> Result<AnswerBuilder<Target>, ShortBuf>
|
||||
where Octets: AsRef<[u8]>, for<'a> &'a Octets: OctetsRef {
|
||||
{
|
||||
let header = self.header_mut();
|
||||
header.set_id(msg.header().id());
|
||||
header.set_qr(true);
|
||||
header.set_opcode(msg.header().opcode());
|
||||
header.set_rd(msg.header().rd());
|
||||
header.set_rcode(rcode);
|
||||
}
|
||||
let mut builder = self.question();
|
||||
for item in msg.question() {
|
||||
if let Ok(item) = item {
|
||||
builder.push(item)?;
|
||||
}
|
||||
}
|
||||
Ok(builder.answer())
|
||||
}
|
||||
|
||||
/// Creates an AXFR request for the given domain.
|
||||
pub fn request_axfr<N: ToDname>(
|
||||
mut self,
|
||||
apex: N
|
||||
) -> Result<AnswerBuilder<Target>, ShortBuf> {
|
||||
self.header_mut().set_random_id();
|
||||
let mut builder = self.question();
|
||||
builder.push((apex, Rtype::Axfr))?;
|
||||
Ok(builder.answer())
|
||||
}
|
||||
|
||||
pub fn question(self) -> QuestionBuilder<Target> {
|
||||
QuestionBuilder::new(self)
|
||||
}
|
||||
@@ -96,6 +137,10 @@ impl<Target: OctetsBuilder> MessageBuilder<Target> {
|
||||
&mut self.target
|
||||
}
|
||||
|
||||
pub fn as_slice(&self) -> &[u8] {
|
||||
self.as_target().as_ref()
|
||||
}
|
||||
|
||||
pub fn as_message(&self) -> Message<&[u8]>
|
||||
where Target: AsRef<[u8]> {
|
||||
unsafe { Message::from_octets_unchecked(self.target.as_ref()) }
|
||||
@@ -106,16 +151,16 @@ impl<Target: OctetsBuilder> MessageBuilder<Target> {
|
||||
unsafe { Message::from_octets_unchecked(self.target.into_octets()) }
|
||||
}
|
||||
|
||||
pub fn header(&self) -> &Header {
|
||||
Header::for_message_slice(self.target.as_ref())
|
||||
pub fn header(&self) -> Header {
|
||||
*Header::for_message_slice(self.target.as_ref())
|
||||
}
|
||||
|
||||
pub fn header_mut(&mut self) -> &mut Header {
|
||||
Header::for_message_slice_mut(self.target.as_mut())
|
||||
}
|
||||
|
||||
pub fn counts(&self) -> &HeaderCounts {
|
||||
HeaderCounts::for_message_slice(self.target.as_ref())
|
||||
pub fn counts(&self) -> HeaderCounts {
|
||||
*HeaderCounts::for_message_slice(self.target.as_ref())
|
||||
}
|
||||
|
||||
fn counts_mut(&mut self) -> &mut HeaderCounts {
|
||||
@@ -508,7 +553,7 @@ where Target: OctetsBuilder {
|
||||
fn push<N, D, R>(&mut self, record: R) -> Result<(), ShortBuf>
|
||||
where N: ToDname, D: RecordData, R: Into<Record<N, D>> {
|
||||
record.into().compose(self.as_target_mut())?;
|
||||
self.counts_mut().inc_ancount();
|
||||
self.counts_mut().inc_arcount();
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
@@ -592,7 +637,7 @@ impl<Target: OctetsBuilder> OptBuilder<Target> {
|
||||
}
|
||||
|
||||
pub fn rcode(&self) -> OptRcode {
|
||||
self.opt_header().rcode(*self.header())
|
||||
self.opt_header().rcode(self.header())
|
||||
}
|
||||
|
||||
pub fn set_rcode(&mut self, rcode: OptRcode) {
|
||||
|
||||
@@ -676,6 +676,9 @@ octets_array!(pub Octets2048 => 2048);
|
||||
octets_array!(pub Octets4096 => 4096);
|
||||
|
||||
|
||||
#[cfg(feature = "smallvec")]
|
||||
pub type OctetsVec = SmallVec<[u8; 24]>;
|
||||
|
||||
//------------ ShortBuf ------------------------------------------------------
|
||||
|
||||
/// An attempt was made to go beyond the end of a buffer.
|
||||
|
||||
@@ -157,7 +157,6 @@ impl<O, N> Tsig<O, N> {
|
||||
///
|
||||
/// [`fudge`]: #method.fudge
|
||||
/// [`time_signed`]: #method.time_signed
|
||||
#[cfg(feature = "chrono")]
|
||||
pub fn is_valid_now(&self) -> bool {
|
||||
Time48::now().eq_fudged(self.time_signed, self.fudge.into())
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
//! [`Serial`]: struct.Serial.html
|
||||
|
||||
use core::{cmp, fmt, str};
|
||||
#[cfg(feature = "bytes")] use chrono::{Utc, TimeZone};
|
||||
use chrono::{DateTime, Utc, TimeZone};
|
||||
use crate::cmp::CanonicalOrd;
|
||||
#[cfg(feature = "bytes")] use crate::master::scan::{
|
||||
CharSource, Scan, ScanError, Scanner, SyntaxError
|
||||
@@ -42,7 +42,6 @@ pub struct Serial(pub u32);
|
||||
|
||||
impl Serial {
|
||||
/// Returns a serial number for the current Unix time.
|
||||
#[cfg(feature = "chrono")]
|
||||
pub fn now() -> Self {
|
||||
Utc::now().into()
|
||||
}
|
||||
@@ -88,7 +87,7 @@ impl Serial {
|
||||
/// In RRSIG records, the expiration and inception time is given as
|
||||
/// serial values. Their master file format can either be the signature
|
||||
/// value or a specific date in `YYYYMMDDHHmmSS` format.
|
||||
#[cfg(all(feature="bytes"))]
|
||||
#[cfg(feature="bytes")]
|
||||
pub fn scan_rrsig<C: CharSource>(
|
||||
scanner: &mut Scanner<C>
|
||||
) -> Result<Self, ScanError> {
|
||||
@@ -182,7 +181,6 @@ impl From<Serial> for u32 {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "chrono")]
|
||||
impl<T: TimeZone> From<DateTime<T>> for Serial {
|
||||
fn from(value: DateTime<T>) -> Self {
|
||||
let mut value = value.timestamp();
|
||||
|
||||
@@ -19,13 +19,13 @@ path = "src/lib.rs"
|
||||
bytes = "0.4"
|
||||
derive_more = "^0.15"
|
||||
openssl = { version = "^0.10", optional = true }
|
||||
ring = { version = "0.15.0-alpha", optional = true }
|
||||
ring = { version = "0.16", optional = true }
|
||||
unwrap = "^1.2"
|
||||
|
||||
[dependencies.domain-core]
|
||||
path = "../domain-core"
|
||||
version = "0.4.1"
|
||||
version = "0.5.0-pre"
|
||||
|
||||
[features]
|
||||
ringsigner = ["ring"]
|
||||
default = ["ringsigner"]
|
||||
default = ["ringsigner"]
|
||||
|
||||
@@ -17,10 +17,13 @@ path = "src/lib.rs"
|
||||
|
||||
[dependencies]
|
||||
bytes = "^0.4"
|
||||
derive_more = "^0.14"
|
||||
ring = "0.15.0-alpha"
|
||||
derive_more = "^0.99"
|
||||
ring = "0.16"
|
||||
smallvec = "1.0"
|
||||
unwrap = "1.2"
|
||||
|
||||
[dependencies.domain-core]
|
||||
path = "../domain-core"
|
||||
version = "0.4.1"
|
||||
version = "0.5.0-pre"
|
||||
features = ["std", "smallvec"]
|
||||
|
||||
|
||||
+390
-256
File diff suppressed because it is too large
Load Diff
@@ -18,8 +18,8 @@ path = "src/lib.rs"
|
||||
[dependencies]
|
||||
bytes = "0.4"
|
||||
derive_more = "^0.15"
|
||||
ring = "=0.15.0-alpha3"
|
||||
ring = "0.16"
|
||||
|
||||
[dependencies.domain-core]
|
||||
path = "../domain-core"
|
||||
version = "0.4.1"
|
||||
version = "0.5.0-pre"
|
||||
|
||||
+3
-3
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "domain"
|
||||
version = "0.4.1"
|
||||
version = "0.5.0-pre"
|
||||
edition = "2018"
|
||||
authors = ["Martin Hoffmann <martin@nlnetlabs.nl>"]
|
||||
description = "A DNS library for Rust – Meta Crate."
|
||||
@@ -19,11 +19,11 @@ validate = ["domain-validate"]
|
||||
|
||||
[dependencies.domain-core]
|
||||
path = "../domain-core"
|
||||
version = "0.4.1"
|
||||
version = "0.5.0-pre"
|
||||
|
||||
[dependencies.domain-resolv]
|
||||
path = "../domain-resolv"
|
||||
version = "0.4.1"
|
||||
version = "0.5.0-pre"
|
||||
optional = true
|
||||
|
||||
[dependencies.domain-sign]
|
||||
|
||||
+2
-1
@@ -11,5 +11,6 @@ domain-core = { path = "../domain-core" }
|
||||
domain-resolv = { path = "../domain-resolv" }
|
||||
domain-tsig = { path = "../domain-tsig" }
|
||||
bytes = "0.4"
|
||||
ring = "0.15.0-alpha"
|
||||
ring = "0.16"
|
||||
unwrap = "1.2"
|
||||
|
||||
|
||||
+102
-70
@@ -1,6 +1,4 @@
|
||||
//! Tests the TSIG implementation.
|
||||
extern crate interop;
|
||||
extern crate ring;
|
||||
|
||||
use std::{env, fs, io, thread};
|
||||
use std::io::{Read, Write};
|
||||
@@ -9,16 +7,24 @@ use std::process::Command;
|
||||
use std::str::FromStr;
|
||||
use std::time::Duration;
|
||||
use ring::rand::SystemRandom;
|
||||
use unwrap::unwrap;
|
||||
use interop::nsd;
|
||||
use interop::domain::core::{Dname, Message, MessageBuilder, Record};
|
||||
use interop::domain::core::message::Message;
|
||||
use interop::domain::core::message_builder::{
|
||||
AdditionalBuilder, RecordSectionBuilder, SectionBuilder
|
||||
AdditionalBuilder, AnswerBuilder, MessageBuilder, RecordSectionBuilder,
|
||||
StreamTarget,
|
||||
};
|
||||
use interop::domain::core::name::Dname;
|
||||
use interop::domain::core::iana::{Rcode, Rtype};
|
||||
use interop::domain::core::rdata::{A, Soa};
|
||||
use interop::domain::core::utils::base64;
|
||||
use interop::domain::tsig;
|
||||
|
||||
type TestMessage = Message<Vec<u8>>;
|
||||
type TestBuilder = MessageBuilder<StreamTarget<Vec<u8>>>;
|
||||
type TestAnswer = AnswerBuilder<StreamTarget<Vec<u8>>>;
|
||||
type TestAdditional = AdditionalBuilder<StreamTarget<Vec<u8>>>;
|
||||
|
||||
|
||||
//------------ Tests --------------------------------------------------------
|
||||
|
||||
@@ -66,21 +72,27 @@ fn tsig_client_nsd() {
|
||||
|
||||
let res = thread::spawn(move || {
|
||||
// Create an AXFR request and send it to NSD.
|
||||
let request = MessageBuilder::request_axfr(
|
||||
Dname::from_str("example.com.").unwrap()
|
||||
).additional();
|
||||
let (msg, tran) = tsig::ClientTransaction::request(&key, request)
|
||||
.unwrap();
|
||||
let request = TestBuilder::new_stream_vec();
|
||||
let mut request = unwrap!(request.request_axfr(
|
||||
unwrap!(Dname::<Vec<u8>>::from_str("example.com."))
|
||||
)).additional();
|
||||
let tran = unwrap!(
|
||||
tsig::ClientTransaction::request(&key, &mut request)
|
||||
);
|
||||
let sock = UdpSocket::bind("127.0.0.1:54320").unwrap();
|
||||
sock.send_to(msg.as_ref(), "127.0.0.1:54321").unwrap();
|
||||
unwrap!(sock.send_to(
|
||||
request.as_target().as_dgram_slice(),
|
||||
"127.0.0.1:54321"
|
||||
));
|
||||
let mut answer = loop {
|
||||
let mut buf = vec![0; 512];
|
||||
let (len, addr) = sock.recv_from(buf.as_mut()).unwrap();
|
||||
if addr != SocketAddr::from_str("127.0.0.1:54321").unwrap() {
|
||||
continue;
|
||||
}
|
||||
let answer = Message::from_bytes(buf[..len].into()).unwrap();
|
||||
if answer.header().id() == msg.header().id() {
|
||||
buf.truncate(len);
|
||||
let answer = Message::from_octets(buf).unwrap();
|
||||
if answer.header().id() == request.header().id() {
|
||||
break answer;
|
||||
}
|
||||
};
|
||||
@@ -91,7 +103,7 @@ fn tsig_client_nsd() {
|
||||
|
||||
// Shut down NSD just to be sure.
|
||||
let _ = nsd.kill();
|
||||
res.unwrap(); // Panic if the thread paniced.
|
||||
unwrap!(res); // Panic if the thread paniced.
|
||||
}
|
||||
|
||||
/// Tests the TSIG server implementation against drill as a client.
|
||||
@@ -113,25 +125,34 @@ fn tsig_server_drill() {
|
||||
loop {
|
||||
let mut buf = vec![0; 512];
|
||||
let (len, addr) = sock.recv_from(buf.as_mut()).unwrap();
|
||||
let mut request = match Message::from_bytes(buf[..len].into()) {
|
||||
buf.truncate(len);
|
||||
let mut request = match Message::from_octets(buf) {
|
||||
Ok(request) => request,
|
||||
Err(_) => continue,
|
||||
};
|
||||
let mut answer = MessageBuilder::new_udp();
|
||||
answer.start_answer(&request, Rcode::NoError);
|
||||
let tran = match tsig::ServerTransaction::request(&&key,
|
||||
&mut request) {
|
||||
let answer = TestBuilder::new_stream_vec();
|
||||
let answer = unwrap!(
|
||||
answer.start_answer(&request, Rcode::NoError)
|
||||
);
|
||||
let tran = match tsig::ServerTransaction::request(
|
||||
&&key, &mut request
|
||||
) {
|
||||
Ok(Some(tran)) => tran,
|
||||
Ok(None) => {
|
||||
sock.send_to(answer.freeze().as_slice(), addr).unwrap();
|
||||
sock.send_to(answer.as_slice(), addr).unwrap();
|
||||
continue;
|
||||
}
|
||||
Err(error) => {
|
||||
sock.send_to(error.as_slice(), addr).unwrap();
|
||||
let answer = unwrap!(error.build_message(
|
||||
&request,
|
||||
TestBuilder::new_stream_vec()
|
||||
));
|
||||
sock.send_to(answer.as_slice(), addr).unwrap();
|
||||
continue;
|
||||
}
|
||||
};
|
||||
let answer = tran.answer(answer.additional()).unwrap();
|
||||
let mut answer = answer.additional();
|
||||
unwrap!(tran.answer(&mut answer));
|
||||
sock.send_to(answer.as_slice(), addr).unwrap();
|
||||
}
|
||||
});
|
||||
@@ -187,14 +208,15 @@ fn tsig_client_sequence_nsd() {
|
||||
}
|
||||
|
||||
let res = thread::spawn(move || {
|
||||
let mut sock = TcpStream::connect("127.0.0.1:54323").unwrap();
|
||||
let request = MessageBuilder::request_axfr(
|
||||
Dname::from_str("example.com.").unwrap()
|
||||
).additional();
|
||||
let (msg, mut tran) = tsig::ClientSequence::request(&key, request)
|
||||
.unwrap();
|
||||
sock.write_all(&(msg.len() as u16).to_be_bytes()).unwrap();
|
||||
sock.write_all(msg.as_slice()).unwrap();
|
||||
let mut sock = unwrap!(TcpStream::connect("127.0.0.1:54323"));
|
||||
let request = TestBuilder::new_stream_vec();
|
||||
let mut request = unwrap!(request.request_axfr(
|
||||
unwrap!(Dname::<Vec<u8>>::from_str("example.com."))
|
||||
)).additional();
|
||||
let mut tran = unwrap!(
|
||||
tsig::ClientSequence::request(&key, &mut request)
|
||||
);
|
||||
unwrap!(sock.write_all(request.as_target().as_stream_slice()));
|
||||
loop {
|
||||
let mut len = [0u8; 2];
|
||||
sock.read_exact(&mut len).unwrap();
|
||||
@@ -202,8 +224,8 @@ fn tsig_client_sequence_nsd() {
|
||||
assert!(len != 0);
|
||||
let mut buf = vec![0; len];
|
||||
sock.read_exact(&mut buf).unwrap();
|
||||
let mut answer = Message::from_bytes(buf.into()).unwrap();
|
||||
tran.answer(&mut answer).unwrap();
|
||||
let mut answer = unwrap!(Message::from_octets(buf));
|
||||
unwrap!(tran.answer(&mut answer));
|
||||
// Last message has SOA as last record in answer section.
|
||||
// We don’t care about details.
|
||||
if answer.answer().unwrap().last().unwrap().unwrap().rtype()
|
||||
@@ -211,7 +233,7 @@ fn tsig_client_sequence_nsd() {
|
||||
break
|
||||
}
|
||||
}
|
||||
tran.done().unwrap()
|
||||
unwrap!(tran.done())
|
||||
}).join();
|
||||
|
||||
// Shut down NSD just to be sure.
|
||||
@@ -243,25 +265,30 @@ fn tsig_server_sequence_drill() {
|
||||
let len = u16::from_be_bytes(buf) as usize;
|
||||
let mut buf = vec![0; len];
|
||||
sock.read_exact(&mut buf).unwrap();
|
||||
let mut request = Message::from_bytes(buf.into()).unwrap();
|
||||
let mut request = Message::from_octets(buf).unwrap();
|
||||
let mut tran = tsig::ServerSequence::request(&&key, &mut request)
|
||||
.unwrap().unwrap();
|
||||
let mut answer = make_first_axfr(&request);
|
||||
unwrap!(tran.answer(&mut answer));
|
||||
send_tcp(
|
||||
&mut sock,
|
||||
tran.answer(make_first_axfr(&request)).unwrap().as_ref()
|
||||
answer.as_target().as_stream_slice()
|
||||
).unwrap();
|
||||
for two in 0..10u8 {
|
||||
for one in 0..10u8 {
|
||||
let mut answer = make_middle_axfr(&request, one, two);
|
||||
unwrap!(tran.answer(&mut answer));
|
||||
send_tcp(
|
||||
&mut sock,
|
||||
tran.answer(make_middle_axfr(&request, one, two))
|
||||
.unwrap().as_ref()
|
||||
answer.as_target().as_stream_slice()
|
||||
).unwrap();
|
||||
}
|
||||
}
|
||||
let mut answer = make_last_axfr(&request);
|
||||
unwrap!(tran.answer(&mut answer));
|
||||
send_tcp(
|
||||
&mut sock,
|
||||
tran.answer(make_last_axfr(&request)).unwrap().as_ref()
|
||||
answer.as_target().as_stream_slice()
|
||||
).unwrap();
|
||||
}
|
||||
});
|
||||
@@ -286,50 +313,55 @@ fn send_tcp(sock: &mut TcpStream, msg: &[u8]) -> Result<(), io::Error> {
|
||||
sock.write_all(msg)
|
||||
}
|
||||
|
||||
fn make_first_axfr(request: &Message) -> AdditionalBuilder {
|
||||
let mut msg = MessageBuilder::new_tcp(1024);
|
||||
msg.start_answer(request, Rcode::NoError);
|
||||
let mut msg = msg.answer();
|
||||
msg.push(make_soa()).unwrap();
|
||||
msg.push(make_a(0, 0, 0)).unwrap();
|
||||
fn make_first_axfr(request: &TestMessage) -> TestAdditional {
|
||||
let msg = TestBuilder::new_stream_vec();
|
||||
let mut msg = unwrap!(msg.start_answer(request, Rcode::NoError));
|
||||
push_soa(&mut msg);
|
||||
push_a(&mut msg, 0, 0, 0);
|
||||
msg.additional()
|
||||
}
|
||||
|
||||
fn make_middle_axfr(request: &Message, one: u8, two: u8) -> AdditionalBuilder {
|
||||
let mut msg = MessageBuilder::new_tcp(1024);
|
||||
msg.start_answer(request, Rcode::NoError);
|
||||
let mut msg = msg.answer();
|
||||
msg.push(make_a(1, one, two)).unwrap();
|
||||
fn make_middle_axfr(
|
||||
request: &TestMessage,
|
||||
one: u8,
|
||||
two: u8
|
||||
) -> TestAdditional {
|
||||
let msg = TestBuilder::new_stream_vec();
|
||||
let mut msg = unwrap!(msg.start_answer(request, Rcode::NoError));
|
||||
push_a(&mut msg, 1, one, two);
|
||||
msg.additional()
|
||||
}
|
||||
|
||||
fn make_last_axfr(request: &Message) -> AdditionalBuilder {
|
||||
let mut msg = MessageBuilder::new_tcp(1024);
|
||||
msg.start_answer(request, Rcode::NoError);
|
||||
let mut msg = msg.answer();
|
||||
msg.push(make_a(2, 0, 0)).unwrap();
|
||||
msg.push(make_soa()).unwrap();
|
||||
fn make_last_axfr(request: &TestMessage) -> TestAdditional {
|
||||
let msg = TestBuilder::new_stream_vec();
|
||||
let mut msg = unwrap!(msg.start_answer(request, Rcode::NoError));
|
||||
push_a(&mut msg, 2, 0, 0);
|
||||
push_soa(&mut msg);
|
||||
msg.additional()
|
||||
}
|
||||
|
||||
fn make_soa() -> Record<Dname, Soa<Dname>> {
|
||||
(
|
||||
Dname::from_str("example.com.").unwrap(),
|
||||
3600,
|
||||
Soa::new(
|
||||
Dname::from_str("mname.example.com.").unwrap(),
|
||||
Dname::from_str("rname.example.com.").unwrap(),
|
||||
12.into(),
|
||||
3600, 3600, 3600, 3600
|
||||
fn push_soa(builder: &mut TestAnswer) {
|
||||
unwrap!(builder.push(
|
||||
(
|
||||
Dname::<Vec<u8>>::from_str("example.com.").unwrap(),
|
||||
3600,
|
||||
Soa::new(
|
||||
Dname::<Vec<u8>>::from_str("mname.example.com.").unwrap(),
|
||||
Dname::<Vec<u8>>::from_str("rname.example.com.").unwrap(),
|
||||
12.into(),
|
||||
3600, 3600, 3600, 3600
|
||||
)
|
||||
)
|
||||
).into()
|
||||
))
|
||||
}
|
||||
|
||||
fn make_a(zero: u8, one: u8, two: u8) -> Record<Dname, A> {
|
||||
(
|
||||
Dname::from_str("example.com.").unwrap(),
|
||||
3600,
|
||||
A::from_octets(10, zero, one, two)
|
||||
).into()
|
||||
fn push_a(builder: &mut TestAnswer, zero: u8, one: u8, two: u8) {
|
||||
unwrap!(builder.push(
|
||||
(
|
||||
Dname::<Vec<u8>>::from_str("example.com.").unwrap(),
|
||||
3600,
|
||||
A::from_octets(10, zero, one, two)
|
||||
)
|
||||
))
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user