Skip to main content

rustbgpd_wire/
keepalive.rs

1use bytes::BufMut;
2
3use crate::constants::{HEADER_LEN, MIN_MESSAGE_LEN};
4use crate::error::DecodeError;
5use crate::header::{BgpHeader, MessageType};
6
7/// Validate that a KEEPALIVE message has the correct length.
8/// KEEPALIVE is header-only — exactly 19 bytes, no body.
9///
10/// # Errors
11///
12/// Returns [`DecodeError::InvalidKeepaliveLength`] if the header length is
13/// not exactly 19 bytes.
14pub fn validate_keepalive(header: &BgpHeader) -> Result<(), DecodeError> {
15    if header.length != MIN_MESSAGE_LEN {
16        return Err(DecodeError::InvalidKeepaliveLength {
17            length: header.length,
18        });
19    }
20    Ok(())
21}
22
23/// Encode a KEEPALIVE message (19 bytes: header only).
24pub fn encode_keepalive(buf: &mut impl BufMut) {
25    let header = BgpHeader {
26        length: MIN_MESSAGE_LEN,
27        message_type: MessageType::Keepalive,
28    };
29    header.encode(buf);
30}
31
32/// Size of an encoded KEEPALIVE message.
33pub const KEEPALIVE_LEN: usize = HEADER_LEN;
34
35#[cfg(test)]
36mod tests {
37    use bytes::BytesMut;
38
39    use super::*;
40    use crate::constants::MAX_MESSAGE_LEN;
41    use crate::header::BgpHeader;
42
43    #[test]
44    fn encode_produces_19_bytes() {
45        let mut buf = BytesMut::with_capacity(KEEPALIVE_LEN);
46        encode_keepalive(&mut buf);
47        assert_eq!(buf.len(), 19);
48    }
49
50    #[test]
51    fn encode_decode_roundtrip() {
52        let mut buf = BytesMut::with_capacity(KEEPALIVE_LEN);
53        encode_keepalive(&mut buf);
54        let mut bytes = buf.freeze();
55        let header = BgpHeader::decode(&mut bytes, MAX_MESSAGE_LEN).unwrap();
56        assert_eq!(header.message_type, MessageType::Keepalive);
57        assert_eq!(header.length, 19);
58        validate_keepalive(&header).unwrap();
59    }
60
61    #[test]
62    fn reject_wrong_length() {
63        let header = BgpHeader {
64            length: 20,
65            message_type: MessageType::Keepalive,
66        };
67        assert!(matches!(
68            validate_keepalive(&header),
69            Err(DecodeError::InvalidKeepaliveLength { length: 20 })
70        ));
71    }
72}