1use crate::types::{Bandwidth, Mid, Pid, Prio, Promises, Sid};
2use bytes::{Buf, BufMut, Bytes, BytesMut};
3
4const FRAME_HANDSHAKE: u8 = 1;
6const FRAME_INIT: u8 = 2;
7const FRAME_SHUTDOWN: u8 = 3;
8const FRAME_OPEN_STREAM: u8 = 4;
9const FRAME_CLOSE_STREAM: u8 = 5;
10const FRAME_DATA_HEADER: u8 = 6;
11const FRAME_DATA: u8 = 7;
12const FRAME_RAW: u8 = 8;
13#[derive(Debug, PartialEq, Eq, Clone)]
18pub enum InitFrame {
19 Handshake {
20 magic_number: [u8; 7],
21 version: [u32; 3],
22 },
23 Init {
24 pid: Pid,
25 secret: u128,
26 },
27 Raw(Vec<u8>),
30}
31
32#[derive(Debug, PartialEq, Eq, Clone)]
34pub enum OTFrame {
35 Shutdown, OpenStream {
38 sid: Sid,
39 prio: Prio,
40 promises: Promises,
41 guaranteed_bandwidth: Bandwidth,
42 },
43 CloseStream {
44 sid: Sid,
45 },
46 DataHeader {
47 mid: Mid,
48 sid: Sid,
49 length: u64,
50 },
51 Data {
52 mid: Mid,
53 data: Bytes,
54 },
55}
56
57#[derive(Debug, PartialEq, Eq, Clone)]
59pub enum ITFrame {
60 Shutdown, OpenStream {
63 sid: Sid,
64 prio: Prio,
65 promises: Promises,
66 guaranteed_bandwidth: Bandwidth,
67 },
68 CloseStream {
69 sid: Sid,
70 },
71 DataHeader {
72 mid: Mid,
73 sid: Sid,
74 length: u64,
75 },
76 Data {
77 mid: Mid,
78 data: BytesMut,
79 },
80}
81
82impl InitFrame {
83 pub(crate) const HANDSHAKE_CNS: usize = 19;
85 pub(crate) const INIT_CNS: usize = 32;
86 pub(crate) const RAW_CNS: usize = 2;
88
89 pub(crate) fn write_bytes(self, bytes: &mut BytesMut) {
91 match self {
92 InitFrame::Handshake {
93 magic_number,
94 version,
95 } => {
96 bytes.put_u8(FRAME_HANDSHAKE);
97 bytes.put_slice(&magic_number);
98 bytes.put_u32_le(version[0]);
99 bytes.put_u32_le(version[1]);
100 bytes.put_u32_le(version[2]);
101 },
102 InitFrame::Init { pid, secret } => {
103 bytes.put_u8(FRAME_INIT);
104 pid.to_bytes(bytes);
105 bytes.put_u128_le(secret);
106 },
107 InitFrame::Raw(data) => {
108 bytes.put_u8(FRAME_RAW);
109 bytes.put_u16_le(data.len() as u16);
110 bytes.put_slice(&data);
111 },
112 }
113 }
114
115 pub(crate) fn read_frame(bytes: &mut BytesMut) -> Option<Self> {
116 let frame_no = match bytes.first() {
117 Some(&f) => f,
118 None => return None,
119 };
120 let frame = match frame_no {
121 FRAME_HANDSHAKE => {
122 if bytes.len() < Self::HANDSHAKE_CNS + 1 {
123 return None;
124 }
125 bytes.advance(1);
126 let mut magic_number_bytes = bytes.copy_to_bytes(7);
127 let mut magic_number = [0u8; 7];
128 magic_number_bytes.copy_to_slice(&mut magic_number);
129 InitFrame::Handshake {
130 magic_number,
131 version: [bytes.get_u32_le(), bytes.get_u32_le(), bytes.get_u32_le()],
132 }
133 },
134 FRAME_INIT => {
135 if bytes.len() < Self::INIT_CNS + 1 {
136 return None;
137 }
138 bytes.advance(1);
139 InitFrame::Init {
140 pid: Pid::from_bytes(bytes),
141 secret: bytes.get_u128_le(),
142 }
143 },
144 FRAME_RAW => {
145 if bytes.len() < Self::RAW_CNS + 1 {
146 return None;
147 }
148 bytes.advance(1);
149 let length = bytes.get_u16_le() as usize;
150 let max_length = length.min(bytes.len());
152 let mut data = vec![0; max_length];
153 data.copy_from_slice(&bytes[..max_length]);
154 InitFrame::Raw(data)
155 },
156 _ => InitFrame::Raw(bytes.to_vec()),
157 };
158 Some(frame)
159 }
160}
161
162pub(crate) const TCP_CLOSE_STREAM_CNS: usize = 8;
163pub(crate) const TCP_DATA_CNS: usize = 10;
165pub(crate) const TCP_DATA_HEADER_CNS: usize = 24;
166pub(crate) const TCP_OPEN_STREAM_CNS: usize = 18;
167pub(crate) const TCP_SHUTDOWN_CNS: usize = 0;
169
170impl OTFrame {
171 pub fn write_bytes(self, bytes: &mut BytesMut) {
172 match self {
173 Self::Shutdown => {
174 bytes.put_u8(FRAME_SHUTDOWN);
175 },
176 Self::OpenStream {
177 sid,
178 prio,
179 promises,
180 guaranteed_bandwidth,
181 } => {
182 bytes.put_u8(FRAME_OPEN_STREAM);
183 sid.to_bytes(bytes);
184 bytes.put_u8(prio);
185 bytes.put_u8(promises.to_le_bytes()[0]);
186 bytes.put_u64_le(guaranteed_bandwidth);
187 },
188 Self::CloseStream { sid } => {
189 bytes.put_u8(FRAME_CLOSE_STREAM);
190 sid.to_bytes(bytes);
191 },
192 Self::DataHeader { mid, sid, length } => {
193 bytes.put_u8(FRAME_DATA_HEADER);
194 bytes.put_u64_le(mid);
195 sid.to_bytes(bytes);
196 bytes.put_u64_le(length);
197 },
198 Self::Data { mid, data } => {
199 bytes.put_u8(FRAME_DATA);
200 bytes.put_u64_le(mid);
201 bytes.put_u16_le(data.len() as u16);
202 bytes.put_slice(&data);
203 },
204 }
205 }
206}
207
208impl ITFrame {
209 pub(crate) fn read_frame(bytes: &mut BytesMut) -> Result<Option<Self>, ()> {
212 let frame_no = match bytes.first() {
213 Some(&f) => f,
214 None => return Ok(None),
215 };
216 let size = match frame_no {
217 FRAME_SHUTDOWN => TCP_SHUTDOWN_CNS,
218 FRAME_OPEN_STREAM => TCP_OPEN_STREAM_CNS,
219 FRAME_CLOSE_STREAM => TCP_CLOSE_STREAM_CNS,
220 FRAME_DATA_HEADER => TCP_DATA_HEADER_CNS,
221 FRAME_DATA => {
222 if bytes.len() < 9 + 1 + 1 {
223 return Ok(None);
224 }
225 u16::from_le_bytes([bytes[8 + 1], bytes[9 + 1]]) as usize + TCP_DATA_CNS
226 },
227 _ => return Err(()),
228 };
229
230 if bytes.len() < size + 1 {
231 return Ok(None);
232 }
233
234 let frame = match frame_no {
235 FRAME_SHUTDOWN => {
236 let _ = bytes.split_to(size + 1);
237 Self::Shutdown
238 },
239 FRAME_OPEN_STREAM => {
240 let mut bytes = bytes.split_to(size + 1);
241 bytes.advance(1);
242 Self::OpenStream {
243 sid: Sid::from_bytes(&mut bytes),
244 prio: bytes.get_u8(),
245 promises: Promises::from_bits_truncate(bytes.get_u8()),
246 guaranteed_bandwidth: bytes.get_u64_le(),
247 }
248 },
249 FRAME_CLOSE_STREAM => {
250 let mut bytes = bytes.split_to(size + 1);
251 bytes.advance(1);
252 Self::CloseStream {
253 sid: Sid::from_bytes(&mut bytes),
254 }
255 },
256 FRAME_DATA_HEADER => {
257 let mut bytes = bytes.split_to(size + 1);
258 bytes.advance(1);
259 Self::DataHeader {
260 mid: bytes.get_u64_le(),
261 sid: Sid::from_bytes(&mut bytes),
262 length: bytes.get_u64_le(),
263 }
264 },
265 FRAME_DATA => {
266 bytes.advance(1);
267 let mid = bytes.get_u64_le();
268 let length = bytes.get_u16_le();
269 debug_assert_eq!(length as usize, size - TCP_DATA_CNS);
270 let data = bytes.split_to(length as usize);
271 Self::Data { mid, data }
272 },
273 _ => unreachable!("Frame::to_frame should be handled before!"),
274 };
275 Ok(Some(frame))
276 }
277}
278
279#[expect(unused_variables)]
280impl PartialEq<ITFrame> for OTFrame {
281 fn eq(&self, other: &ITFrame) -> bool {
282 match self {
283 Self::Shutdown => matches!(other, ITFrame::Shutdown),
284 Self::OpenStream {
285 sid,
286 prio,
287 promises,
288 guaranteed_bandwidth,
289 } => matches!(other, ITFrame::OpenStream {
290 sid,
291 prio,
292 promises,
293 guaranteed_bandwidth,
294 }),
295 Self::CloseStream { sid } => matches!(other, ITFrame::CloseStream { sid }),
296 Self::DataHeader { mid, sid, length } => {
297 matches!(other, ITFrame::DataHeader { mid, sid, length })
298 },
299 Self::Data { mid, data } => matches!(other, ITFrame::Data { mid, data }),
300 }
301 }
302}
303
304#[cfg(test)]
305mod tests {
306 use super::*;
307 use crate::types::{VELOREN_MAGIC_NUMBER, VELOREN_NETWORK_VERSION};
308
309 fn get_initframes() -> Vec<InitFrame> {
310 vec![
311 InitFrame::Handshake {
312 magic_number: VELOREN_MAGIC_NUMBER,
313 version: VELOREN_NETWORK_VERSION,
314 },
315 InitFrame::Init {
316 pid: Pid::fake(0),
317 secret: 0u128,
318 },
319 InitFrame::Raw(vec![1, 2, 3]),
320 ]
321 }
322
323 fn get_otframes() -> Vec<OTFrame> {
324 vec![
325 OTFrame::OpenStream {
326 sid: Sid::new(1337),
327 prio: 14,
328 promises: Promises::GUARANTEED_DELIVERY,
329 guaranteed_bandwidth: 1_000_000,
330 },
331 OTFrame::DataHeader {
332 sid: Sid::new(1337),
333 mid: 0,
334 length: 36,
335 },
336 OTFrame::Data {
337 mid: 0,
338 data: Bytes::from(&[77u8; 20][..]),
339 },
340 OTFrame::Data {
341 mid: 0,
342 data: Bytes::from(&[42u8; 16][..]),
343 },
344 OTFrame::CloseStream {
345 sid: Sid::new(1337),
346 },
347 OTFrame::Shutdown,
348 ]
349 }
350
351 #[test]
352 fn initframe_individual() {
353 let dupl = |frame: InitFrame| {
354 let mut buffer = BytesMut::with_capacity(1500);
355 InitFrame::write_bytes(frame, &mut buffer);
356 InitFrame::read_frame(&mut buffer)
357 };
358
359 for frame in get_initframes() {
360 println!("initframe: {:?}", &frame);
361 assert_eq!(Some(frame.clone()), dupl(frame));
362 }
363 }
364
365 #[test]
366 fn initframe_multiple() {
367 let mut buffer = BytesMut::with_capacity(3000);
368
369 let mut frames = get_initframes();
370 for f in &frames {
372 InitFrame::write_bytes(f.clone(), &mut buffer);
373 }
374
375 let mut framesd = frames
377 .iter()
378 .map(|&_| InitFrame::read_frame(&mut buffer))
379 .collect::<Vec<_>>();
380
381 for (f, fd) in frames.drain(..).zip(framesd.drain(..)) {
383 println!("initframe: {:?}", &f);
384 assert_eq!(Some(f), fd);
385 }
386 }
387
388 #[test]
389 fn frame_individual() {
390 let dupl = |frame: OTFrame| {
391 let mut buffer = BytesMut::with_capacity(1500);
392 OTFrame::write_bytes(frame, &mut buffer);
393 ITFrame::read_frame(&mut buffer)
394 };
395
396 for frame in get_otframes() {
397 println!("frame: {:?}", &frame);
398 assert_eq!(frame.clone(), dupl(frame).expect("ERR").expect("NONE"));
399 }
400 }
401
402 #[test]
403 fn frame_multiple() {
404 let mut buffer = BytesMut::with_capacity(3000);
405
406 let mut frames = get_otframes();
407 for f in &frames {
409 OTFrame::write_bytes(f.clone(), &mut buffer);
410 }
411
412 let mut framesd = frames
414 .iter()
415 .map(|&_| ITFrame::read_frame(&mut buffer))
416 .collect::<Vec<_>>();
417
418 for (f, fd) in frames.drain(..).zip(framesd.drain(..)) {
420 println!("frame: {:?}", &f);
421 assert_eq!(f, fd.expect("ERR").expect("NONE"));
422 }
423 }
424
425 #[test]
426 fn frame_exact_size() {
427 const SIZE: usize = TCP_CLOSE_STREAM_CNS+1;
428 let mut buffer = BytesMut::with_capacity(SIZE);
429
430 let frame1 = OTFrame::CloseStream { sid: Sid::new(2) };
431 OTFrame::write_bytes(frame1.clone(), &mut buffer);
432 assert_eq!(buffer.len(), SIZE);
433 let mut deque = buffer.iter().copied().collect();
434 let frame2 = ITFrame::read_frame(&mut deque);
435 assert_eq!(frame1, frame2.expect("ERR").expect("NONE"));
436 }
437
438 #[test]
439 fn initframe_too_short_buffer() {
440 let mut buffer = BytesMut::with_capacity(10);
441
442 let frame1 = InitFrame::Handshake {
443 magic_number: VELOREN_MAGIC_NUMBER,
444 version: VELOREN_NETWORK_VERSION,
445 };
446 InitFrame::write_bytes(frame1, &mut buffer);
447 }
448
449 #[test]
450 fn initframe_too_less_data() {
451 let mut buffer = BytesMut::with_capacity(20);
452
453 let frame1 = InitFrame::Handshake {
454 magic_number: VELOREN_MAGIC_NUMBER,
455 version: VELOREN_NETWORK_VERSION,
456 };
457 InitFrame::write_bytes(frame1, &mut buffer);
458 buffer.truncate(6); let frame1d = InitFrame::read_frame(&mut buffer);
460 assert_eq!(frame1d, None);
461 }
462
463 #[test]
464 fn initframe_rubbish() {
465 let mut buffer = BytesMut::from(&b"dtrgwcser"[..]);
466 assert_eq!(
467 InitFrame::read_frame(&mut buffer),
468 Some(InitFrame::Raw(b"dtrgwcser".to_vec()))
469 );
470 }
471
472 #[test]
473 fn initframe_attack_too_much_length() {
474 let mut buffer = BytesMut::with_capacity(50);
475
476 let frame1 = InitFrame::Raw(b"foobar".to_vec());
477 InitFrame::write_bytes(frame1.clone(), &mut buffer);
478 buffer[1] = 255;
479 let framed = InitFrame::read_frame(&mut buffer);
480 assert_eq!(framed, Some(frame1));
481 }
482
483 #[test]
484 fn initframe_attack_too_low_length() {
485 let mut buffer = BytesMut::with_capacity(50);
486
487 let frame1 = InitFrame::Raw(b"foobar".to_vec());
488 InitFrame::write_bytes(frame1, &mut buffer);
489 buffer[1] = 3;
490 let framed = InitFrame::read_frame(&mut buffer);
491 assert_eq!(framed, Some(InitFrame::Raw(b"foo".to_vec())));
493 }
494
495 #[test]
496 fn frame_too_short_buffer() {
497 let mut buffer = BytesMut::with_capacity(10);
498
499 let frame1 = OTFrame::OpenStream {
500 sid: Sid::new(88),
501 promises: Promises::ENCRYPTED,
502 prio: 88,
503 guaranteed_bandwidth: 1_000_000,
504 };
505 OTFrame::write_bytes(frame1, &mut buffer);
506 }
507
508 #[test]
509 fn frame_too_less_data() {
510 let mut buffer = BytesMut::with_capacity(20);
511
512 let frame1 = OTFrame::OpenStream {
513 sid: Sid::new(88),
514 promises: Promises::ENCRYPTED,
515 prio: 88,
516 guaranteed_bandwidth: 1_000_000,
517 };
518 OTFrame::write_bytes(frame1, &mut buffer);
519 buffer.truncate(6); let frame1d = ITFrame::read_frame(&mut buffer);
521 assert_eq!(frame1d, Ok(None));
522 }
523
524 #[test]
525 fn frame_rubish() {
526 let mut buffer = BytesMut::from(&b"dtrgwcser"[..]);
527 assert_eq!(ITFrame::read_frame(&mut buffer), Err(()));
528 }
529
530 #[test]
531 fn frame_attack_too_much_length() {
532 let mut buffer = BytesMut::with_capacity(50);
533
534 let frame1 = OTFrame::Data {
535 mid: 7u64,
536 data: Bytes::from(&b"foobar"[..]),
537 };
538
539 OTFrame::write_bytes(frame1, &mut buffer);
540 buffer[9] = 255;
541 let framed = ITFrame::read_frame(&mut buffer);
542 assert_eq!(framed, Ok(None));
543 }
544
545 #[test]
546 fn frame_attack_too_low_length() {
547 let mut buffer = BytesMut::with_capacity(50);
548
549 let frame1 = OTFrame::Data {
550 mid: 7u64,
551 data: Bytes::from(&b"foobar"[..]),
552 };
553
554 OTFrame::write_bytes(frame1, &mut buffer);
555 buffer[9] = 3;
556 let framed = ITFrame::read_frame(&mut buffer);
557 assert_eq!(
558 framed,
559 Ok(Some(ITFrame::Data {
560 mid: 7u64,
561 data: BytesMut::from(&b"foo"[..]),
562 }))
563 );
564 let framed = ITFrame::read_frame(&mut buffer);
566 assert_eq!(framed, Err(()));
567 }
568}