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 }
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 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 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 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 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 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 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}