ndn_ndnlp/
lib.rs

1use bytes::{Buf, BufMut, Bytes, BytesMut};
2use ndn_protocol::{Data, Interest};
3use ndn_tlv::{find_tlv, GenericTlv, NonNegativeInteger, Tlv, TlvDecode, TlvEncode, VarNum};
4
5#[derive(Tlv, Debug, Clone, PartialEq, Eq, Hash)]
6pub enum Packet {
7    Interest(Interest<Bytes>),
8    Data(Data<Bytes>),
9    LpPacket(LpPacket),
10}
11
12#[derive(Debug, Clone, PartialEq, Eq, Hash)]
13pub struct UnknownHeader(pub GenericTlv<Bytes>);
14
15#[derive(Debug, Clone, PartialEq, Eq, Hash)]
16pub struct LpPacket {
17    pub sequence: Option<Sequence>,
18    pub frag_index: Option<FragIndex>,
19    pub frag_count: Option<FragCount>,
20    pub nack: Option<Nack>,
21    pub other_headers: Vec<UnknownHeader>,
22    pub fragment: Option<Fragment>,
23    // Any modification here likely needs an adjustment to Tlv/TlvDecode/TlvEncode impls
24}
25
26#[derive(Tlv, Debug, Clone, PartialEq, Eq, Hash)]
27#[tlv(80)]
28pub struct Fragment {
29    pub data: Bytes,
30}
31
32#[derive(Tlv, Debug, Clone, PartialEq, Eq, Hash)]
33#[tlv(81)]
34pub struct Sequence(pub Bytes);
35
36#[derive(Tlv, Debug, Clone, Copy, PartialEq, Eq, Hash)]
37#[tlv(82)]
38pub struct FragIndex(pub NonNegativeInteger);
39
40#[derive(Tlv, Debug, Clone, Copy, PartialEq, Eq, Hash)]
41#[tlv(83)]
42pub struct FragCount(pub NonNegativeInteger);
43
44#[derive(Tlv, Debug, Clone, Copy, PartialEq, Eq, Hash)]
45#[tlv(800)]
46pub struct Nack;
47
48impl UnknownHeader {
49    pub fn is_critical(&self) -> bool {
50        let typ = self.0.typ.value();
51        !(typ >= 800 && typ <= 959 && typ & 0b11 == 0)
52    }
53}
54
55impl Packet {
56    pub fn make_nack<T>(interest: Interest<T>) -> Self
57    where
58        T: TlvEncode,
59    {
60        Self::LpPacket(LpPacket {
61            sequence: None,
62            frag_index: None,
63            frag_count: None,
64            nack: Some(Nack),
65            other_headers: vec![],
66            fragment: Some(Fragment {
67                data: interest.encode(),
68            }),
69        })
70    }
71}
72
73impl LpPacket {
74    pub fn seq_num(&self) -> Option<Bytes> {
75        self.sequence.as_ref().map(|x| x.0.clone())
76    }
77
78    pub fn frag_info(&self) -> Option<(NonNegativeInteger, NonNegativeInteger)> {
79        Some((self.frag_index?.0, self.frag_count?.0))
80    }
81
82    pub fn is_nack(&self) -> bool {
83        self.nack.is_some()
84    }
85
86    pub fn other_headers(&self) -> &Vec<UnknownHeader> {
87        &self.other_headers
88    }
89
90    pub fn fragment(&self) -> Option<Bytes> {
91        self.fragment.as_ref().map(|x| x.data.clone())
92    }
93}
94
95impl Tlv for LpPacket {
96    const TYP: usize = 100;
97
98    fn inner_size(&self) -> usize {
99        self.sequence.size()
100            + self.frag_index.size()
101            + self.frag_count.size()
102            + self.nack.size()
103            + self.other_headers.size()
104            + self.fragment.size()
105    }
106}
107
108impl TlvDecode for LpPacket {
109    fn decode(bytes: &mut Bytes) -> ndn_tlv::Result<Self> {
110        let mut cur = bytes.clone();
111        find_tlv::<Self>(&mut cur, true)?;
112
113        let typ = VarNum::decode(&mut cur)?.into();
114        if typ != Self::TYP {
115            return Err(ndn_tlv::TlvError::TypeMismatch {
116                expected: Self::TYP,
117                found: typ,
118            });
119        }
120
121        let len = VarNum::decode(&mut cur)?.into();
122        if cur.remaining() < len {
123            return Err(ndn_tlv::TlvError::UnexpectedEndOfStream);
124        }
125        let mut inner_data = cur.split_to(len);
126
127        let mut other_headers = Vec::new();
128
129        // 80-100 headers
130        let sequence = Option::<Sequence>::decode(&mut inner_data)?;
131        let frag_index = Option::<FragIndex>::decode(&mut inner_data)?;
132        let frag_count = Option::<FragCount>::decode(&mut inner_data)?;
133
134        while inner_data.has_remaining() {
135            let mut header_cur = inner_data.clone();
136            let header_ty: usize = VarNum::decode(&mut header_cur)?.into();
137            if header_ty > 100 {
138                break;
139            }
140            let header = UnknownHeader::decode(&mut inner_data)?;
141            other_headers.push(header);
142        }
143
144        // 800-1000 headers
145        let nack = Option::<Nack>::decode(&mut inner_data)?;
146
147        while inner_data.has_remaining() {
148            let mut header_cur = inner_data.clone();
149            let header_ty: usize = VarNum::decode(&mut header_cur)?.into();
150            if header_ty < 800 {
151                break;
152            }
153            let header = UnknownHeader::decode(&mut inner_data)?;
154            other_headers.push(header);
155        }
156
157        let fragment = Option::<Fragment>::decode(&mut inner_data)?;
158        bytes.advance(bytes.remaining() - cur.remaining());
159        Ok(Self {
160            sequence,
161            frag_index,
162            frag_count,
163            nack,
164            other_headers,
165            fragment,
166        })
167    }
168}
169
170impl TlvEncode for LpPacket {
171    fn encode(&self) -> Bytes {
172        let mut bytes = BytesMut::with_capacity(self.size());
173        bytes.put(VarNum::from(Self::TYP).encode());
174        bytes.put(VarNum::from(self.inner_size()).encode());
175
176        let mut headers = self.other_headers.clone();
177        headers.sort_by_key(|x| x.0.typ);
178
179        // 80-100 headers
180        bytes.put(self.sequence.encode());
181        bytes.put(self.frag_index.encode());
182        bytes.put(self.frag_count.encode());
183        for header in &headers {
184            if header.0.typ.value() <= 100 {
185                bytes.put(header.encode());
186            }
187        }
188
189        // 800-1000 headers
190        bytes.put(self.nack.encode());
191        for header in &headers {
192            if header.0.typ.value() >= 800 {
193                bytes.put(header.encode());
194            }
195        }
196
197        // fragment
198        bytes.put(self.fragment.encode());
199
200        bytes.freeze()
201    }
202
203    fn size(&self) -> usize {
204        VarNum::from(Self::TYP).size() + VarNum::from(self.inner_size()).size() + self.inner_size()
205    }
206}
207
208impl TlvDecode for UnknownHeader {
209    fn decode(bytes: &mut Bytes) -> ndn_tlv::Result<Self> {
210        let mut cur = bytes.clone();
211        let typ = VarNum::decode(&mut cur)?.into();
212
213        if (typ <= 80 || typ >= 100) && (typ < 800 || typ > 1000) {
214            // NDNLPv2 reseres 80-100 and 800-1000
215            // Anything outside that range is invalid
216            // 80 is the Fragment, not a header, therefore invalid
217            // 100 is the entire LpPacket, also invalid
218            // Everything else may be a header and will be treated as such
219            return Err(ndn_tlv::TlvError::TypeMismatch {
220                expected: 0,
221                found: typ,
222            });
223        }
224
225        Ok(Self(GenericTlv::decode(bytes)?))
226    }
227}
228
229impl TlvEncode for UnknownHeader {
230    fn encode(&self) -> Bytes {
231        self.0.encode()
232    }
233
234    fn size(&self) -> usize {
235        self.0.size()
236    }
237}
238
239#[cfg(test)]
240mod tests {
241    use ndn_protocol::Name;
242
243    use super::*;
244
245    #[test]
246    fn nack() {
247        let interest: Interest<()> = Interest::new(Name::from_str("/test/nack").unwrap());
248        let mut nack = Packet::make_nack(interest.clone());
249        match nack {
250            Packet::LpPacket(ref mut packet) => {
251                packet.other_headers.push(UnknownHeader(GenericTlv {
252                    typ: VarNum::new(1000),
253                    len: VarNum::new(0),
254                    content: Bytes::new(),
255                }));
256
257                packet.other_headers.push(UnknownHeader(GenericTlv {
258                    typ: VarNum::new(999),
259                    len: VarNum::new(0),
260                    content: Bytes::new(),
261                }));
262
263                packet.other_headers.push(UnknownHeader(GenericTlv {
264                    typ: VarNum::new(95),
265                    len: VarNum::new(0),
266                    content: Bytes::new(),
267                }));
268            }
269            _ => unreachable!(),
270        }
271        let nack2 = LpPacket::decode(&mut nack.encode()).unwrap();
272
273        assert!(nack2.is_nack());
274        assert_eq!(nack2.other_headers.len(), 3);
275        assert_eq!(nack2.other_headers[0].0.typ.value(), 95);
276        assert_eq!(nack2.other_headers[1].0.typ.value(), 999);
277        assert_eq!(nack2.other_headers[2].0.typ.value(), 1000);
278
279        let mut fragment = nack2.fragment().unwrap();
280        let interest2 = Interest::decode(&mut fragment).unwrap();
281        assert_eq!(interest, interest2);
282    }
283}