Skip to main content

rtc_dtls/handshake/
handshake_message_hello_verify_request.rs

1#[cfg(test)]
2mod handshake_message_hello_verify_request_test;
3
4use super::*;
5use crate::record_layer::record_layer_header::*;
6
7use byteorder::{ReadBytesExt, WriteBytesExt};
8use std::io::{Read, Write};
9
10/*
11   The definition of HelloVerifyRequest is as follows:
12
13   struct {
14     ProtocolVersion server_version;
15     opaque cookie<0..2^8-1>;
16   } HelloVerifyRequest;
17
18   The HelloVerifyRequest message type is hello_verify_request(3).
19
20   When the client sends its ClientHello message to the server, the server
21   MAY respond with a HelloVerifyRequest message.  This message contains
22   a stateless cookie generated using the technique of [PHOTURIS].  The
23   client MUST retransmit the ClientHello with the cookie added.
24*/
25/// ## Specifications
26///
27/// * [RFC 6347 §4.2.1]
28///
29/// [RFC 6347 §4.2.1]: https://tools.ietf.org/html/rfc6347#section-4.2.1
30#[derive(Clone, Debug, PartialEq, Eq)]
31pub struct HandshakeMessageHelloVerifyRequest {
32    pub(crate) version: ProtocolVersion,
33    pub(crate) cookie: Vec<u8>,
34}
35
36impl HandshakeMessageHelloVerifyRequest {
37    /// The handshake type that identifies this message on the wire.
38    pub fn handshake_type(&self) -> HandshakeType {
39        HandshakeType::HelloVerifyRequest
40    }
41
42    /// The encoded size of this message in bytes.
43    pub fn size(&self) -> usize {
44        1 + 1 + 1 + self.cookie.len()
45    }
46
47    /// Encodes this message to `writer`.
48    ///
49    /// # Errors
50    ///
51    /// Fails on a write error, or if a field exceeds the length its wire format allows.
52    pub fn marshal<W: Write>(&self, writer: &mut W) -> Result<()> {
53        if self.cookie.len() > 255 {
54            return Err(Error::ErrCookieTooLong);
55        }
56
57        writer.write_u8(self.version.major)?;
58        writer.write_u8(self.version.minor)?;
59        writer.write_u8(self.cookie.len() as u8)?;
60        writer.write_all(&self.cookie)?;
61
62        Ok(writer.flush()?)
63    }
64
65    /// Decodes one of these messages from `reader`.
66    ///
67    /// # Errors
68    ///
69    /// Fails if `reader` is truncated or its contents are not a valid encoding.
70    pub fn unmarshal<R: Read>(reader: &mut R) -> Result<Self> {
71        let major = reader.read_u8()?;
72        let minor = reader.read_u8()?;
73        let cookie_length = reader.read_u8()?;
74        let mut cookie = vec![];
75        reader.read_to_end(&mut cookie)?;
76
77        if cookie.len() < cookie_length as usize {
78            return Err(Error::ErrBufferTooSmall);
79        }
80
81        Ok(HandshakeMessageHelloVerifyRequest {
82            version: ProtocolVersion { major, minor },
83            cookie,
84        })
85    }
86}