1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
use std::marker::PhantomData;

// FIXME: for some reason, the compiler says BufMut and Emitable are unused, but they _are_ used.
// These traits need to be in scope for some methods to be called.

use bytes::{BufMut, BytesMut};
use tokio_io::codec::{Decoder, Encoder};

use {Emitable, Error, NetlinkBuffer};

pub struct NetlinkCodec<T> {
    phantom: PhantomData<T>,
}

impl<T> Default for NetlinkCodec<T> {
    fn default() -> Self {
        Self::new()
    }
}
impl<T> NetlinkCodec<T> {
    pub fn new() -> Self {
        NetlinkCodec {
            phantom: PhantomData,
        }
    }
}

impl Decoder for NetlinkCodec<NetlinkBuffer<Vec<u8>>> {
    type Item = NetlinkBuffer<Vec<u8>>;
    type Error = Error;
    fn decode(&mut self, src: &mut BytesMut) -> Result<Option<Self::Item>, Self::Error> {
        let len = match NetlinkBuffer::new_checked(src.as_ref()) {
            Ok(buf) => buf.length() as usize,
            Err(Error::Truncated) => return Ok(None),
            Err(e) => panic!("Unknown error while reading packet: {}", e),
        };
        let bytes = src.split_to(len);
        Ok(Some(NetlinkBuffer::new(bytes.to_vec())))
    }
}

impl<T: AsRef<[u8]>> Encoder for NetlinkCodec<NetlinkBuffer<T>> {
    type Item = NetlinkBuffer<T>;
    type Error = Error;

    fn encode(&mut self, msg: Self::Item, buf: &mut BytesMut) -> Result<(), Self::Error> {
        buf.extend_from_slice(msg.into_inner().as_ref());
        Ok(())
    }
}

#[cfg(feature = "rtnl_support")]
mod rtnl {
    use super::*;
    use packet::rtnl::Message;

    impl Decoder for NetlinkCodec<Message> {
        type Item = Message;
        type Error = Error;

        fn decode(&mut self, src: &mut BytesMut) -> Result<Option<Self::Item>, Self::Error> {
            let len = match NetlinkBuffer::new_checked(src.as_ref()) {
                Ok(buf) => buf.length() as usize,
                Err(Error::Truncated) => {
                    return Ok(None);
                }
                Err(e) => panic!("Unknown error while reading packet: {}", e),
            };
            let bytes = src.split_to(len);
            Ok(Some(Message::from_bytes(&bytes).unwrap()))
        }
    }
    impl Encoder for NetlinkCodec<Message> {
        type Item = Message;
        type Error = Error;

        fn encode(&mut self, msg: Self::Item, buf: &mut BytesMut) -> Result<(), Self::Error> {
            let msg_len = msg.buffer_len();
            // FIXME: we should have a max length for the buffer
            while buf.remaining_mut() < msg_len {
                let new_len = buf.len() + 2048;
                buf.resize(new_len, 0);
            }
            unsafe {
                let size = msg.to_bytes(&mut buf.bytes_mut()[..])?;
                buf.advance_mut(size);
            }
            Ok(())
        }
    }
}