1mod builder;
8mod error;
9mod model;
10
11mod crc32c;
12pub(crate) use crc32c::Crc32cHasher;
13
14pub use crate::protocol::ip::{IPv4, IPv6};
15pub use builder::{Builder, WriteToHeader, Writer};
16pub use error::ParseError;
17pub use model::{
18 AddressFamily, Addresses, Command, Crc32cStatus, Header, PROTOCOL_PREFIX, Protocol, Type,
19 TypeLengthValue, TypeLengthValues, Unix, Version,
20};
21use model::{MINIMUM_LENGTH, MINIMUM_TLV_LENGTH};
22use std::borrow::Cow;
23use std::net::{Ipv4Addr, Ipv6Addr};
24
25const LEFT_MASK: u8 = 0xF0;
27const RIGHT_MASK: u8 = 0x0F;
29const VERSION_COMMAND: usize = PROTOCOL_PREFIX.len();
31const ADDRESS_FAMILY_PROTOCOL: usize = VERSION_COMMAND + 1;
33const LENGTH: usize = ADDRESS_FAMILY_PROTOCOL + 1;
35
36fn parse_addresses(address_family: AddressFamily, bytes: &[u8]) -> Addresses {
38 match address_family {
39 AddressFamily::Unspecified => Addresses::Unspecified,
40 AddressFamily::IPv4 => {
41 let source_address = Ipv4Addr::new(bytes[0], bytes[1], bytes[2], bytes[3]);
42 let destination_address = Ipv4Addr::new(bytes[4], bytes[5], bytes[6], bytes[7]);
43 let source_port = u16::from_be_bytes([bytes[8], bytes[9]]);
44 let destination_port = u16::from_be_bytes([bytes[10], bytes[11]]);
45
46 Addresses::IPv4(IPv4 {
47 source_address,
48 destination_address,
49 source_port,
50 destination_port,
51 })
52 }
53 AddressFamily::IPv6 => {
54 let mut address = [0; 16];
55
56 address[..].copy_from_slice(&bytes[..16]);
57 let source_address = Ipv6Addr::from(address);
58
59 address[..].copy_from_slice(&bytes[16..32]);
60 let destination_address = Ipv6Addr::from(address);
61
62 let source_port = u16::from_be_bytes([bytes[32], bytes[33]]);
63 let destination_port = u16::from_be_bytes([bytes[34], bytes[35]]);
64
65 Addresses::IPv6(IPv6 {
66 source_address,
67 destination_address,
68 source_port,
69 destination_port,
70 })
71 }
72 AddressFamily::Unix => {
73 let mut source = [0; 108];
74 let mut destination = [0; 108];
75
76 source[..].copy_from_slice(&bytes[..108]);
77 destination[..].copy_from_slice(&bytes[108..]);
78
79 Addresses::Unix(Unix {
80 source,
81 destination,
82 })
83 }
84 }
85}
86
87impl<'a> TryFrom<&'a [u8]> for Header<'a> {
88 type Error = ParseError;
89
90 fn try_from(input: &'a [u8]) -> Result<Self, Self::Error> {
91 if input.len() < PROTOCOL_PREFIX.len() {
92 if PROTOCOL_PREFIX.starts_with(input) {
93 return Err(ParseError::Incomplete(input.len()));
94 } else {
95 return Err(ParseError::Prefix);
96 }
97 }
98
99 if &input[..VERSION_COMMAND] != PROTOCOL_PREFIX {
100 return Err(ParseError::Prefix);
101 }
102
103 if input.len() < MINIMUM_LENGTH {
104 return Err(ParseError::Incomplete(input.len()));
105 }
106
107 let version = match input[VERSION_COMMAND] & LEFT_MASK {
108 0x20 => Version::Two,
109 v => return Err(ParseError::Version(v)),
110 };
111 let command = match input[VERSION_COMMAND] & RIGHT_MASK {
112 0x00 => Command::Local,
113 0x01 => Command::Proxy,
114 c => return Err(ParseError::Command(c)),
115 };
116
117 let address_family = match input[ADDRESS_FAMILY_PROTOCOL] & LEFT_MASK {
118 0x00 => AddressFamily::Unspecified,
119 0x10 => AddressFamily::IPv4,
120 0x20 => AddressFamily::IPv6,
121 0x30 => AddressFamily::Unix,
122 a => return Err(ParseError::AddressFamily(a)),
123 };
124 let protocol = match input[ADDRESS_FAMILY_PROTOCOL] & RIGHT_MASK {
125 0x00 => Protocol::Unspecified,
126 0x01 => Protocol::Stream,
127 0x02 => Protocol::Datagram,
128 p => return Err(ParseError::Protocol(p)),
129 };
130
131 let length = u16::from_be_bytes([input[LENGTH], input[LENGTH + 1]]) as usize;
132 let address_family_bytes = address_family.byte_length().unwrap_or_default();
133
134 if length < address_family_bytes {
135 return Err(ParseError::InvalidAddresses(length, address_family_bytes));
136 }
137
138 let full_length = MINIMUM_LENGTH + length;
139
140 if input.len() < full_length {
141 return Err(ParseError::Partial(input.len() - MINIMUM_LENGTH, length));
142 }
143
144 let header = &input[..full_length];
145 let addresses = parse_addresses(
146 address_family,
147 &header[MINIMUM_LENGTH..MINIMUM_LENGTH + address_family_bytes],
148 );
149
150 Ok(Header {
151 header: Cow::Borrowed(header),
152 version,
153 command,
154 protocol,
155 addresses,
156 })
157 }
158}
159
160#[cfg(test)]
161mod tests {
162 use super::*;
163 use model::{Type, TypeLengthValue};
164
165 #[test]
166 fn no_tlvs() {
167 let mut input: Vec<u8> = Vec::with_capacity(PROTOCOL_PREFIX.len());
168
169 input.extend_from_slice(PROTOCOL_PREFIX);
170 input.push(0x21);
171 input.push(0x11);
172 input.extend([0, 12]);
173 input.extend([127, 0, 0, 1]);
174 input.extend([127, 0, 0, 2]);
175 input.extend([0, 80]);
176 input.extend([1, 187]);
177
178 let expected = Header {
179 header: Cow::Borrowed(input.as_slice()),
180 version: Version::Two,
181 command: Command::Proxy,
182 protocol: Protocol::Stream,
183 addresses: IPv4::new([127, 0, 0, 1], [127, 0, 0, 2], 80, 443).into(),
184 };
185 let actual = Header::try_from(input.as_slice()).unwrap();
186
187 assert_eq!(actual, expected);
188 assert!(actual.tlvs().next().is_none());
189 assert_eq!(actual.length(), 12);
190 assert_eq!(actual.address_family(), AddressFamily::IPv4);
191 assert_eq!(
192 actual.address_bytes(),
193 &[127, 0, 0, 1, 127, 0, 0, 2, 0, 80, 1, 187]
194 );
195 assert!(actual.tlv_bytes().is_empty());
196 assert_eq!(actual.as_bytes(), input.as_slice());
197 }
198
199 #[test]
200 fn no_tlvs_unspec() {
201 let mut input: Vec<u8> = Vec::with_capacity(PROTOCOL_PREFIX.len());
202
203 input.extend_from_slice(PROTOCOL_PREFIX);
204 input.push(0x21);
205 input.push(0x00);
206 input.extend([0, 12]);
207 input.extend([127, 0, 0, 1]);
208 input.extend([127, 0, 0, 2]);
209 input.extend([0, 80]);
210 input.extend([1, 187]);
211
212 let expected = Header {
213 header: input.as_slice().into(),
214 version: Version::Two,
215 command: Command::Proxy,
216 protocol: Protocol::Unspecified,
217 addresses: Addresses::Unspecified,
218 };
219 let actual = Header::try_from(input.as_slice()).unwrap();
220
221 assert_eq!(actual, expected);
222 assert!(actual.tlvs().next().is_none());
223 assert_eq!(actual.length(), 12);
224 assert_eq!(actual.address_family(), AddressFamily::Unspecified);
225 assert_eq!(
226 actual.address_bytes(),
227 &[127, 0, 0, 1, 127, 0, 0, 2, 0, 80, 1, 187]
228 );
229 assert!(actual.tlv_bytes().is_empty());
230 assert_eq!(actual.as_bytes(), input.as_slice());
231 }
232
233 #[test]
234 fn no_tlvs_unspec_stream() {
235 let mut input: Vec<u8> = Vec::with_capacity(PROTOCOL_PREFIX.len());
236
237 input.extend_from_slice(PROTOCOL_PREFIX);
238 input.push(0x21);
239 input.push(0x01);
240 input.extend([0, 8]);
241 input.extend([127, 0, 0, 1]);
242 input.extend([127, 0, 0, 2]);
243
244 let expected = Header {
245 header: Cow::Borrowed(input.as_slice()),
246 version: Version::Two,
247 command: Command::Proxy,
248 protocol: Protocol::Stream,
249 addresses: Addresses::Unspecified,
250 };
251 let actual = Header::try_from(input.as_slice()).unwrap();
252
253 assert_eq!(actual, expected);
254 assert!(actual.tlvs().next().is_none());
255 assert_eq!(actual.length(), 8);
256 assert_eq!(actual.address_family(), AddressFamily::Unspecified);
257 assert_eq!(actual.address_bytes(), &[127, 0, 0, 1, 127, 0, 0, 2]);
258 assert!(actual.tlv_bytes().is_empty());
259 assert_eq!(actual.as_bytes(), input.as_slice());
260 }
261
262 #[test]
263 fn no_tlvs_unspec_ipv4() {
264 let mut input: Vec<u8> = Vec::with_capacity(PROTOCOL_PREFIX.len());
265
266 input.extend_from_slice(PROTOCOL_PREFIX);
267 input.push(0x21);
268 input.push(0x10);
269 input.extend([0, 8]);
270 input.extend([127, 0, 0, 1]);
271 input.extend([127, 0, 0, 2]);
272
273 let actual = Header::try_from(input.as_slice()).unwrap_err();
274
275 assert_eq!(actual, ParseError::InvalidAddresses(8, 12));
276 }
277
278 #[test]
279 fn invalid_version() {
280 let mut input: Vec<u8> = Vec::with_capacity(PROTOCOL_PREFIX.len());
281
282 input.extend_from_slice(PROTOCOL_PREFIX);
283 input.push(0x11);
284 input.push(0x11);
285 input.extend([0, 12]);
286 input.extend([127, 0, 0, 1]);
287 input.extend([127, 0, 0, 2]);
288 input.extend([0, 80]);
289 input.extend([1, 187]);
290
291 let actual = Header::try_from(input.as_slice()).unwrap_err();
292
293 assert_eq!(actual, ParseError::Version(0x10));
294 }
295
296 #[test]
297 fn invalid_address_family() {
298 let mut input: Vec<u8> = Vec::with_capacity(PROTOCOL_PREFIX.len());
299
300 input.extend_from_slice(PROTOCOL_PREFIX);
301 input.push(0x21);
302 input.push(0x51);
303 input.extend([0, 12]);
304 input.extend([127, 0, 0, 1]);
305 input.extend([127, 0, 0, 2]);
306 input.extend([0, 80]);
307 input.extend([1, 187]);
308
309 let actual = Header::try_from(input.as_slice()).unwrap_err();
310
311 assert_eq!(actual, ParseError::AddressFamily(0x50));
312 }
313
314 #[test]
315 fn invalid_command() {
316 let mut input: Vec<u8> = Vec::with_capacity(PROTOCOL_PREFIX.len());
317
318 input.extend_from_slice(PROTOCOL_PREFIX);
319 input.push(0x23);
320 input.push(0x11);
321 input.extend([0, 12]);
322 input.extend([127, 0, 0, 1]);
323 input.extend([127, 0, 0, 2]);
324 input.extend([0, 80]);
325 input.extend([1, 187]);
326
327 let actual = Header::try_from(input.as_slice()).unwrap_err();
328
329 assert_eq!(actual, ParseError::Command(0x03));
330 }
331
332 #[test]
333 fn invalid_protocol() {
334 let mut input: Vec<u8> = Vec::with_capacity(PROTOCOL_PREFIX.len());
335
336 input.extend_from_slice(PROTOCOL_PREFIX);
337 input.push(0x20);
338 input.push(0x17);
339 input.extend([0, 12]);
340 input.extend([127, 0, 0, 1]);
341 input.extend([127, 0, 0, 2]);
342 input.extend([0, 80]);
343 input.extend([1, 187]);
344
345 let actual = Header::try_from(input.as_slice()).unwrap_err();
346
347 assert_eq!(actual, ParseError::Protocol(0x07));
348 }
349
350 #[test]
351 fn proxy_with_extra() {
352 let mut input: Vec<u8> = Vec::with_capacity(PROTOCOL_PREFIX.len());
353
354 input.extend_from_slice(PROTOCOL_PREFIX);
355 input.push(0x21);
356 input.push(0x11);
357 input.extend([0, 12]);
358 input.extend([127, 0, 0, 1]);
359 input.extend([127, 0, 0, 2]);
360 input.extend([0, 80]);
361 input.extend([1, 187]);
362 input.extend([42]);
363
364 let header = &input[..input.len() - 1];
365 let expected = Header {
366 header: header.into(),
367 version: Version::Two,
368 command: Command::Proxy,
369 protocol: Protocol::Stream,
370 addresses: IPv4::new([127, 0, 0, 1], [127, 0, 0, 2], 80, 443).into(),
371 };
372 let actual = Header::try_from(input.as_slice()).unwrap();
373
374 assert_eq!(actual, expected);
375 assert!(actual.tlvs().next().is_none());
376 assert_eq!(actual.length(), 12);
377 assert_eq!(actual.address_family(), AddressFamily::IPv4);
378 assert_eq!(
379 actual.address_bytes(),
380 &[127, 0, 0, 1, 127, 0, 0, 2, 0, 80, 1, 187]
381 );
382 assert!(actual.tlv_bytes().is_empty());
383 assert_eq!(actual.as_bytes(), header);
384 }
385
386 #[test]
387 fn with_tlvs() {
388 let source_address = [
389 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
390 0xFF, 0xF2,
391 ];
392 let destination_address = [
393 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
394 0xFF, 0xF1,
395 ];
396 let mut input: Vec<u8> = Vec::with_capacity(PROTOCOL_PREFIX.len());
397
398 input.extend_from_slice(PROTOCOL_PREFIX);
399 input.push(0x21);
400 input.push(0x21);
401 input.extend([0, 45]);
402 input.extend(source_address);
403 input.extend(destination_address);
404 input.extend([0, 80]);
405 input.extend([1, 187]);
406 input.extend([1, 0, 1, 5]);
407 input.extend([3, 0, 2, 5, 5]);
408
409 let expected = Header {
410 header: input.as_slice().into(),
411 version: Version::Two,
412 command: Command::Proxy,
413 protocol: Protocol::Stream,
414 addresses: IPv6::new(source_address, destination_address, 80, 443).into(),
415 };
416 let expected_tlvs = vec![
417 Ok(TypeLengthValue::new(Type::ALPN, &[5])),
418 Ok(TypeLengthValue::new(Type::CRC32C, &[5, 5])),
419 ];
420
421 let actual = Header::try_from(input.as_slice()).unwrap();
422 let actual_tlvs: Vec<Result<TypeLengthValue<'_>, ParseError>> = actual.tlvs().collect();
423
424 assert_eq!(actual, expected);
425 assert_eq!(actual_tlvs, expected_tlvs);
426 assert_eq!(actual.length(), 45);
427 assert_eq!(actual.address_family(), AddressFamily::IPv6);
428 assert_eq!(
429 actual.address_bytes(),
430 &[
431 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
432 0xFF, 0xF2, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
433 0xFF, 0xFF, 0xFF, 0xF1, 0, 80, 1, 187
434 ]
435 );
436 assert_eq!(actual.tlv_bytes(), &[1, 0, 1, 5, 3, 0, 2, 5, 5]);
437 assert_eq!(actual.as_bytes(), input.as_slice());
438 }
439
440 #[test]
441 fn tlvs_with_extra() {
442 let source_address = [
443 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
444 0xFF, 0xFF,
445 ];
446 let destination_address = [
447 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
448 0xFF, 0xF1,
449 ];
450 let mut input: Vec<u8> = Vec::with_capacity(PROTOCOL_PREFIX.len());
451
452 input.extend_from_slice(PROTOCOL_PREFIX);
453 input.push(0x21);
454 input.push(0x21);
455 input.extend([0, 45]);
456 input.extend(source_address);
457 input.extend(destination_address);
458 input.extend([0, 80]);
459 input.extend([1, 187]);
460 input.extend([1, 0, 1, 5]);
461 input.extend([4, 0, 2, 5, 5]);
462 input.extend([2, 0, 2, 5, 5]);
463
464 let header = &input[..input.len() - 5];
465 let expected = Header {
466 header: header.into(),
467 version: Version::Two,
468 command: Command::Proxy,
469 protocol: Protocol::Stream,
470 addresses: IPv6::new(source_address, destination_address, 80, 443).into(),
471 };
472 let expected_tlvs = vec![
473 Ok(TypeLengthValue::new(Type::ALPN, &[5])),
474 Ok(TypeLengthValue::new(Type::NoOp, &[5, 5])),
475 ];
476
477 let actual = Header::try_from(input.as_slice()).unwrap();
478 let actual_tlvs: Vec<Result<TypeLengthValue<'_>, ParseError>> = actual.tlvs().collect();
479
480 assert_eq!(actual, expected);
481 assert_eq!(actual_tlvs, expected_tlvs);
482 assert_eq!(actual.length(), 45);
483 assert_eq!(actual.address_family(), AddressFamily::IPv6);
484 assert_eq!(
485 actual.address_bytes(),
486 &[
487 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
488 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
489 0xFF, 0xFF, 0xFF, 0xF1, 0, 80, 1, 187
490 ]
491 );
492 assert_eq!(actual.tlv_bytes(), &[1, 0, 1, 5, 4, 0, 2, 5, 5]);
493 assert_eq!(actual.as_bytes(), header);
494 }
495
496 #[test]
497 fn unix_tlvs_with_extra() {
498 let source_address = [0xFFu8; 108];
499 let destination_address = [0xAAu8; 108];
500 let mut input: Vec<u8> = Vec::with_capacity(PROTOCOL_PREFIX.len());
501
502 input.extend_from_slice(PROTOCOL_PREFIX);
503 input.push(0x21);
504 input.push(0x30);
505 input.extend([0, 225]);
506 input.extend(source_address);
507 input.extend(destination_address);
508 input.extend([2, 0, 2, 5, 5]);
509 input.extend([48, 0, 1, 5]);
510 input.extend([1, 0, 2, 5, 5]);
511
512 let header = &input[..input.len() - 5];
513 let expected = Header {
514 header: header.into(),
515 version: Version::Two,
516 command: Command::Proxy,
517 protocol: Protocol::Unspecified,
518 addresses: Unix::new(source_address, destination_address).into(),
519 };
520 let mut expected_address_bytes =
521 Vec::with_capacity(source_address.len() + destination_address.len());
522 expected_address_bytes.extend(source_address);
523 expected_address_bytes.extend(destination_address);
524
525 let expected_tlvs = vec![
526 Ok(TypeLengthValue::new(Type::Authority, &[5, 5])),
527 Ok(TypeLengthValue::new(Type::NetworkNamespace, &[5])),
528 ];
529
530 let actual = Header::try_from(input.as_slice()).unwrap();
531 let actual_tlvs: Vec<Result<TypeLengthValue<'_>, ParseError>> = actual.tlvs().collect();
532
533 assert_eq!(actual, expected);
534 assert_eq!(actual_tlvs, expected_tlvs);
535 assert_eq!(actual.length(), 225);
536 assert_eq!(actual.address_family(), AddressFamily::Unix);
537 assert_eq!(actual.address_bytes(), expected_address_bytes.as_slice());
538 assert_eq!(actual.tlv_bytes(), &[2, 0, 2, 5, 5, 48, 0, 1, 5]);
539 assert_eq!(actual.as_bytes(), header);
540 }
541
542 #[test]
543 fn with_tlvs_without_ports() {
544 let source_address = [
545 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
546 0xFF, 0xFF,
547 ];
548 let destination_address = [
549 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
550 0xFF, 0xF1,
551 ];
552 let mut input: Vec<u8> = Vec::with_capacity(PROTOCOL_PREFIX.len());
553
554 input.extend_from_slice(PROTOCOL_PREFIX);
555 input.push(0x21);
556 input.push(0x20);
557 input.extend([0, 41]);
558 input.extend(source_address);
559 input.extend(destination_address);
560 input.extend([1, 0, 1, 5]);
561 input.extend([3, 0, 2, 5, 5]);
562
563 let expected = Header {
564 header: input.as_slice().into(),
565 version: Version::Two,
566 command: Command::Proxy,
567 protocol: Protocol::Unspecified,
568 addresses: IPv6::new(source_address, destination_address, 256, 261).into(),
569 };
570 let expected_tlvs = vec![Ok(TypeLengthValue::new(Type::CRC32C, &[5, 5]))];
571
572 let actual = Header::try_from(input.as_slice()).unwrap();
573 let actual_tlvs: Vec<Result<TypeLengthValue<'_>, ParseError>> = actual.tlvs().collect();
574
575 assert_eq!(actual, expected);
576 assert_eq!(actual_tlvs, expected_tlvs);
577 assert_eq!(actual.length(), 41);
578 assert_eq!(actual.address_family(), AddressFamily::IPv6);
579 assert_eq!(
580 actual.address_bytes(),
581 &[
582 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
583 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
584 0xFF, 0xFF, 0xFF, 0xF1, 1, 0, 1, 5
585 ]
586 );
587 assert_eq!(actual.tlv_bytes(), &[3, 0, 2, 5, 5]);
588 assert_eq!(actual.as_bytes(), input.as_slice());
589 }
590
591 #[test]
592 fn partial_tlv() {
593 let mut input: Vec<u8> = Vec::with_capacity(PROTOCOL_PREFIX.len());
594
595 input.extend_from_slice(PROTOCOL_PREFIX);
596 input.push(0x21);
597 input.push(0x11);
598 input.extend([0, 15]);
599 input.extend([127, 0, 0, 1]);
600 input.extend([127, 0, 0, 2]);
601 input.extend([0, 80]);
602 input.extend([1, 187]);
603 input.extend([1, 0, 1]);
604
605 let header = Header::try_from(input.as_slice()).unwrap();
606 let mut tlvs = header.tlvs();
607
608 assert_eq!(tlvs.next().unwrap(), Err(ParseError::InvalidTLV(1, 1)));
609 assert_eq!(tlvs.next(), None);
610 }
611
612 #[test]
613 fn missing_tlvs() {
614 let mut input: Vec<u8> = Vec::with_capacity(PROTOCOL_PREFIX.len());
615
616 input.extend_from_slice(PROTOCOL_PREFIX);
617 input.push(0x21);
618 input.push(0x11);
619 input.extend([0, 17]);
620 input.extend([127, 0, 0, 1]);
621 input.extend([127, 0, 0, 2]);
622 input.extend([0, 80]);
623 input.extend([1, 187]);
624 input.extend([1, 0, 1]);
625
626 assert_eq!(
627 Header::try_from(&input[..]).unwrap_err(),
628 ParseError::Partial(15, 17)
629 );
630 }
631
632 #[test]
633 fn partial_address() {
634 let mut input: Vec<u8> = Vec::with_capacity(PROTOCOL_PREFIX.len());
635
636 input.extend_from_slice(PROTOCOL_PREFIX);
637 input.push(0x21);
638 input.push(0x11);
639 input.extend([0, 12]);
640 input.extend([127, 0, 0, 1]);
641 input.extend([127, 0, 0, 2]);
642 input.extend([0, 80]);
643
644 assert_eq!(
645 Header::try_from(&input[..]).unwrap_err(),
646 ParseError::Partial(10, 12)
647 );
648 }
649
650 #[test]
651 fn no_address() {
652 let mut input: Vec<u8> = Vec::with_capacity(PROTOCOL_PREFIX.len());
653
654 input.extend_from_slice(PROTOCOL_PREFIX);
655 input.push(0x20);
656 input.push(0x02);
657 input.extend([0, 0]);
658 input.extend([0, 80]);
659
660 let header = &input[..input.len() - 2];
661 let expected = Header {
662 header: header.into(),
663 version: Version::Two,
664 command: Command::Local,
665 protocol: Protocol::Datagram,
666 addresses: Addresses::Unspecified,
667 };
668
669 let actual = Header::try_from(input.as_slice()).unwrap();
670 let actual_tlvs: Vec<Result<TypeLengthValue<'_>, ParseError>> = actual.tlvs().collect();
671
672 assert_eq!(actual, expected);
673 assert_eq!(actual_tlvs, vec![]);
674 assert_eq!(actual.length(), 0);
675 assert_eq!(actual.address_family(), AddressFamily::Unspecified);
676 assert!(actual.address_bytes().is_empty());
677 assert!(actual.tlv_bytes().is_empty());
678 assert_eq!(actual.as_bytes(), header);
679 }
680
681 #[test]
682 fn unspecified_address_family() {
683 let mut input: Vec<u8> = Vec::with_capacity(PROTOCOL_PREFIX.len());
684
685 input.extend_from_slice(PROTOCOL_PREFIX);
686 input.push(0x20);
687 input.push(0x02);
688 input.extend([0, 12]);
689 input.extend([127, 0, 0, 1]);
690 input.extend([127, 0, 0, 2]);
691 input.extend([0, 80]);
692 input.extend([0xbb, 1]);
693
694 let expected = Header {
695 header: input.as_slice().into(),
696 version: Version::Two,
697 command: Command::Local,
698 protocol: Protocol::Datagram,
699 addresses: Addresses::Unspecified,
700 };
701 let actual = Header::try_from(input.as_slice()).unwrap();
702
703 assert_eq!(actual, expected);
704 assert!(actual.tlvs().next().is_none());
705 assert_eq!(actual.length(), 12);
706 assert_eq!(actual.address_family(), AddressFamily::Unspecified);
707 assert_eq!(
708 actual.address_bytes(),
709 &[127, 0, 0, 1, 127, 0, 0, 2, 0, 80, 0xbb, 1]
710 );
711 assert!(actual.tlv_bytes().is_empty());
712 assert_eq!(actual.as_bytes(), input.as_slice());
713 }
714
715 #[test]
716 fn missing_address() {
717 let mut input: Vec<u8> = Vec::with_capacity(PROTOCOL_PREFIX.len());
718
719 input.extend_from_slice(PROTOCOL_PREFIX);
720 input.push(0x20);
721 input.push(0x22);
722 input.extend([0, 0]);
723 input.extend([0, 80]);
724
725 assert_eq!(
726 Header::try_from(&input[..]).unwrap_err(),
727 ParseError::InvalidAddresses(0, AddressFamily::IPv6.byte_length().unwrap_or_default())
728 );
729 }
730
731 #[test]
732 fn not_prefixed() {
733 assert_eq!(
734 Header::try_from(b"\r\n\r\n\x01\r\nQUIT\n".as_slice()).unwrap_err(),
735 ParseError::Prefix
736 );
737 assert_eq!(
738 Header::try_from(b"\r\n\r\n\x01".as_slice()).unwrap_err(),
739 ParseError::Prefix
740 );
741 }
742
743 #[test]
744 fn incomplete() {
745 assert_eq!(
746 Header::try_from([0x0D, 0x0A, 0x0D, 0x0A, 0x00].as_slice()).unwrap_err(),
747 ParseError::Incomplete(5)
748 );
749 assert_eq!(
750 Header::try_from(PROTOCOL_PREFIX).unwrap_err(),
751 ParseError::Incomplete(PROTOCOL_PREFIX.len())
752 );
753 }
754}