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