dns_message_parser/rr/edns/
rfc_7873.rs1use hex::encode;
2use std::fmt::{Display, Formatter, Result as FmtResult};
3use thiserror::Error;
4
5pub const CLIENT_COOKIE_LENGTH: usize = 8;
6pub const MINIMUM_SERVER_COOKIE_LENGTH: usize = 8;
7pub const MAXIMUM_SERVER_COOKIE_LENGTH: usize = 32;
8
9#[derive(Debug, PartialEq, Clone, Eq, Hash)]
10pub struct Cookie {
11 pub client_cookie: [u8; 8],
12 server_cookie: Option<Vec<u8>>,
13}
14
15#[derive(Debug, Clone, PartialEq, Eq, Hash, Error)]
16pub enum CookieError {
17 #[error("Server cookie length is not between {MINIMUM_SERVER_COOKIE_LENGTH} and {MAXIMUM_SERVER_COOKIE_LENGTH}: {0}]")]
18 ServerCookieLength(usize),
19}
20
21impl Cookie {
22 pub fn new(
23 client_cookie: [u8; 8],
24 server_cookie: Option<Vec<u8>>,
25 ) -> Result<Cookie, CookieError> {
26 let mut cookie = Cookie {
27 client_cookie,
28 server_cookie: None,
29 };
30 cookie.set_server_cookie(server_cookie)?;
31 Ok(cookie)
32 }
33
34 pub fn set_server_cookie(&mut self, server_cookie: Option<Vec<u8>>) -> Result<(), CookieError> {
35 match server_cookie {
36 Some(server_cookie) => {
37 let server_cookie_len = server_cookie.len();
38 if (MINIMUM_SERVER_COOKIE_LENGTH..MAXIMUM_SERVER_COOKIE_LENGTH)
39 .contains(&server_cookie_len)
40 {
41 self.server_cookie.replace(server_cookie);
42 Ok(())
43 } else {
44 Err(CookieError::ServerCookieLength(server_cookie_len))
45 }
46 }
47 None => {
48 self.server_cookie.take();
49 Ok(())
50 }
51 }
52 }
53
54 pub fn get_server_cookie(&self) -> Option<&[u8]> {
55 self.server_cookie.as_deref()
56 }
57}
58
59impl Display for Cookie {
60 fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
61 write!(f, "Cookie {}", encode(self.client_cookie))?;
62 match &self.server_cookie {
63 Some(server_cookie) => write!(f, " {}", encode(server_cookie)),
64 None => Ok(()),
65 }
66 }
67}