12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697 |
- use log::*;
- use crate::strings::{Labels, ReadLabels};
- use crate::wire::*;
- /// An **MX** _(mail exchange)_ record, which contains the hostnames for mail
- /// servers that handle mail sent to the domain.
- ///
- /// # References
- ///
- /// - [RFC 1035 §3.3.9](https://tools.ietf.org/html/rfc1035) — Domain Names,
- /// Implementation and Specification (November 1987)
- #[derive(PartialEq, Debug)]
- pub struct MX {
- /// The preference that clients should give to this MX record amongst all
- /// that get returned.
- pub preference: u16,
- /// The domain name of the mail exchange server.
- pub exchange: Labels,
- }
- impl Wire for MX {
- const NAME: &'static str = "MX";
- const RR_TYPE: u16 = 15;
- #[cfg_attr(all(test, feature = "with_mutagen"), ::mutagen::mutate)]
- fn read(stated_length: u16, c: &mut Cursor<&[u8]>) -> Result<Self, WireError> {
- let preference = c.read_u16::<BigEndian>()?;
- trace!("Parsed preference -> {:?}", preference);
- let (exchange, exchange_length) = c.read_labels()?;
- trace!("Parsed exchange -> {:?}", exchange);
- let length_after_labels = 2 + exchange_length;
- if stated_length == length_after_labels {
- trace!("Length is correct");
- Ok(Self { preference, exchange })
- }
- else {
- warn!("Length is incorrect (stated length {:?}, preference plus exchange length {:?}", stated_length, length_after_labels);
- Err(WireError::WrongLabelLength { stated_length, length_after_labels })
- }
- }
- }
- #[cfg(test)]
- mod test {
- use super::*;
- use pretty_assertions::assert_eq;
- #[test]
- fn parses() {
- let buf = &[
- 0x00, 0x0A, // preference
- 0x05, 0x62, 0x73, 0x61, 0x67, 0x6f, 0x02, 0x6d, 0x65, // exchange
- 0x00, // exchange terminator
- ];
- assert_eq!(MX::read(buf.len() as _, &mut Cursor::new(buf)).unwrap(),
- MX {
- preference: 10,
- exchange: Labels::encode("bsago.me").unwrap(),
- });
- }
- #[test]
- fn incorrect_record_length() {
- let buf = &[
- 0x00, 0x0A, // preference
- 0x03, 0x65, 0x66, 0x67, // domain
- 0x00, // domain terminator
- ];
- assert_eq!(MX::read(6, &mut Cursor::new(buf)),
- Err(WireError::WrongLabelLength { stated_length: 6, length_after_labels: 7 }));
- }
- #[test]
- fn record_empty() {
- assert_eq!(MX::read(0, &mut Cursor::new(&[])),
- Err(WireError::IO));
- }
- #[test]
- fn buffer_ends_abruptly() {
- let buf = &[
- 0x00, 0x0A, // half a preference
- ];
- assert_eq!(MX::read(23, &mut Cursor::new(buf)),
- Err(WireError::IO));
- }
- }
|