1 use super::*; 2 3 /////////////////////////////////////////////////////////////////// 4 //chunk_type_test 5 /////////////////////////////////////////////////////////////////// 6 use super::chunk_type::*; 7 8 #[test] 9 fn test_chunk_type_string() -> Result<()> { 10 let tests = vec![ 11 (CT_PAYLOAD_DATA, "DATA"), 12 (CT_INIT, "INIT"), 13 (CT_INIT_ACK, "INIT-ACK"), 14 (CT_SACK, "SACK"), 15 (CT_HEARTBEAT, "HEARTBEAT"), 16 (CT_HEARTBEAT_ACK, "HEARTBEAT-ACK"), 17 (CT_ABORT, "ABORT"), 18 (CT_SHUTDOWN, "SHUTDOWN"), 19 (CT_SHUTDOWN_ACK, "SHUTDOWN-ACK"), 20 (CT_ERROR, "ERROR"), 21 (CT_COOKIE_ECHO, "COOKIE-ECHO"), 22 (CT_COOKIE_ACK, "COOKIE-ACK"), 23 (CT_ECNE, "ECNE"), 24 (CT_CWR, "CWR"), 25 (CT_SHUTDOWN_COMPLETE, "SHUTDOWN-COMPLETE"), 26 (CT_RECONFIG, "RECONFIG"), 27 (CT_FORWARD_TSN, "FORWARD-TSN"), 28 (ChunkType(255), "Unknown ChunkType: 255"), 29 ]; 30 31 for (ct, expected) in tests { 32 assert_eq!( 33 ct.to_string(), 34 expected, 35 "failed to stringify chunkType {}, expected {}", 36 ct, 37 expected 38 ); 39 } 40 41 Ok(()) 42 } 43 44 /////////////////////////////////////////////////////////////////// 45 //chunk_abort_test 46 /////////////////////////////////////////////////////////////////// 47 use super::chunk_abort::*; 48 use crate::error_cause::*; 49 50 #[test] 51 fn test_abort_chunk_one_error_cause() -> Result<()> { 52 let abort1 = ChunkAbort { 53 error_causes: vec![ErrorCause { 54 code: PROTOCOL_VIOLATION, 55 ..Default::default() 56 }], 57 }; 58 59 let b = abort1.marshal()?; 60 let abort2 = ChunkAbort::unmarshal(&b)?; 61 62 assert_eq!(1, abort2.error_causes.len(), "should have only one cause"); 63 assert_eq!( 64 abort1.error_causes[0].error_cause_code(), 65 abort2.error_causes[0].error_cause_code(), 66 "errorCause code should match" 67 ); 68 69 Ok(()) 70 } 71 72 #[test] 73 fn test_abort_chunk_many_error_causes() -> Result<()> { 74 let abort1 = ChunkAbort { 75 error_causes: vec![ 76 ErrorCause { 77 code: INVALID_MANDATORY_PARAMETER, 78 ..Default::default() 79 }, 80 ErrorCause { 81 code: UNRECOGNIZED_CHUNK_TYPE, 82 ..Default::default() 83 }, 84 ErrorCause { 85 code: PROTOCOL_VIOLATION, 86 ..Default::default() 87 }, 88 ], 89 }; 90 91 let b = abort1.marshal()?; 92 let abort2 = ChunkAbort::unmarshal(&b)?; 93 assert_eq!(3, abort2.error_causes.len(), "should have only one cause"); 94 for (i, error_cause) in abort1.error_causes.iter().enumerate() { 95 assert_eq!( 96 error_cause.error_cause_code(), 97 abort2.error_causes[i].error_cause_code(), 98 "errorCause code should match" 99 ); 100 } 101 102 Ok(()) 103 } 104 105 /////////////////////////////////////////////////////////////////// 106 //chunk_error_test 107 /////////////////////////////////////////////////////////////////// 108 use super::chunk_error::*; 109 use bytes::BufMut; 110 use lazy_static::lazy_static; 111 112 const CHUNK_FLAGS: u8 = 0x00; 113 static ORG_UNRECOGNIZED_CHUNK: Bytes = 114 Bytes::from_static(&[0xc0, 0x0, 0x0, 0x8, 0x0, 0x0, 0x0, 0x3]); 115 116 lazy_static! { 117 static ref RAW_IN: Bytes = { 118 let mut raw = BytesMut::new(); 119 raw.put_u8(CT_ERROR.0); 120 raw.put_u8(CHUNK_FLAGS); 121 raw.extend(vec![0x00, 0x10, 0x00, 0x06, 0x00, 0x0c]); 122 raw.extend(ORG_UNRECOGNIZED_CHUNK.clone()); 123 raw.freeze() 124 }; 125 } 126 127 #[test] 128 fn test_chunk_error_unrecognized_chunk_type_unmarshal() -> Result<()> { 129 let c = ChunkError::unmarshal(&RAW_IN)?; 130 assert_eq!(CT_ERROR, c.header().typ, "chunk type should be ERROR"); 131 assert_eq!(1, c.error_causes.len(), "there should be on errorCause"); 132 133 let ec = &c.error_causes[0]; 134 assert_eq!( 135 UNRECOGNIZED_CHUNK_TYPE, 136 ec.error_cause_code(), 137 "cause code should be unrecognizedChunkType" 138 ); 139 assert_eq!( 140 ec.raw, ORG_UNRECOGNIZED_CHUNK, 141 "should have valid unrecognizedChunk" 142 ); 143 144 Ok(()) 145 } 146 147 #[test] 148 fn test_chunk_error_unrecognized_chunk_type_marshal() -> Result<()> { 149 let ec_unrecognized_chunk_type = ErrorCause { 150 code: UNRECOGNIZED_CHUNK_TYPE, 151 raw: ORG_UNRECOGNIZED_CHUNK.clone(), 152 }; 153 154 let ec = ChunkError { 155 error_causes: vec![ec_unrecognized_chunk_type], 156 }; 157 158 let raw = ec.marshal()?; 159 assert_eq!(raw, *RAW_IN, "unexpected serialization result"); 160 161 Ok(()) 162 } 163 164 #[test] 165 fn test_chunk_error_unrecognized_chunk_type_marshal_with_cause_value_being_nil() -> Result<()> { 166 let expected = 167 Bytes::from_static(&[CT_ERROR.0, CHUNK_FLAGS, 0x00, 0x08, 0x00, 0x06, 0x00, 0x04]); 168 let ec_unrecognized_chunk_type = ErrorCause { 169 code: UNRECOGNIZED_CHUNK_TYPE, 170 ..Default::default() 171 }; 172 173 let ec = ChunkError { 174 error_causes: vec![ec_unrecognized_chunk_type], 175 }; 176 177 let raw = ec.marshal()?; 178 assert_eq!(raw, expected, "unexpected serialization result"); 179 180 Ok(()) 181 } 182 183 /////////////////////////////////////////////////////////////////// 184 //chunk_forward_tsn_test 185 /////////////////////////////////////////////////////////////////// 186 use super::chunk_forward_tsn::*; 187 188 static CHUNK_FORWARD_TSN_BYTES: Bytes = 189 Bytes::from_static(&[0xc0, 0x0, 0x0, 0x8, 0x0, 0x0, 0x0, 0x3]); 190 191 #[test] 192 fn test_chunk_forward_tsn_success() -> Result<()> { 193 let tests = vec![ 194 CHUNK_FORWARD_TSN_BYTES.clone(), 195 Bytes::from_static(&[0xc0, 0x0, 0x0, 0xc, 0x0, 0x0, 0x0, 0x3, 0x0, 0x4, 0x0, 0x5]), 196 Bytes::from_static(&[ 197 0xc0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x3, 0x0, 0x4, 0x0, 0x5, 0x0, 0x6, 0x0, 0x7, 198 ]), 199 ]; 200 201 for binary in tests { 202 let actual = ChunkForwardTsn::unmarshal(&binary)?; 203 let b = actual.marshal()?; 204 assert_eq!(binary, b, "test not equal"); 205 } 206 207 Ok(()) 208 } 209 210 #[test] 211 fn test_chunk_forward_tsn_unmarshal_failure() -> Result<()> { 212 let tests = vec![ 213 ("chunk header to short", Bytes::from_static(&[0xc0])), 214 ( 215 "missing New Cumulative TSN", 216 Bytes::from_static(&[0xc0, 0x0, 0x0, 0x4]), 217 ), 218 ( 219 "missing stream sequence", 220 Bytes::from_static(&[ 221 0xc0, 0x0, 0x0, 0xe, 0x0, 0x0, 0x0, 0x3, 0x0, 0x4, 0x0, 0x5, 0x0, 0x6, 222 ]), 223 ), 224 ]; 225 226 for (name, binary) in tests { 227 let result = ChunkForwardTsn::unmarshal(&binary); 228 assert!(result.is_err(), "expected unmarshal: {} to fail.", name); 229 } 230 231 Ok(()) 232 } 233 234 /////////////////////////////////////////////////////////////////// 235 //chunk_reconfig_test 236 /////////////////////////////////////////////////////////////////// 237 use super::chunk_reconfig::*; 238 239 static TEST_CHUNK_RECONFIG_PARAM_A: Bytes = Bytes::from_static(&[ 240 0x0, 0xd, 0x0, 0x16, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, 0x3, 0x0, 0x4, 0x0, 241 0x5, 0x0, 0x6, 242 ]); 243 244 static TEST_CHUNK_RECONFIG_PARAM_B: Bytes = Bytes::from_static(&[ 245 0x0, 0xd, 0x0, 0x10, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, 0x3, 246 ]); 247 248 static TEST_CHUNK_RECONFIG_RESPONCE: Bytes = 249 Bytes::from_static(&[0x0, 0x10, 0x0, 0xc, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x1]); 250 251 lazy_static! { 252 static ref TEST_CHUNK_RECONFIG_BYTES: Vec<Bytes> = { 253 let mut tests = vec![]; 254 { 255 let mut test = BytesMut::new(); 256 test.extend(vec![0x82, 0x0, 0x0, 0x1a]); 257 test.extend(TEST_CHUNK_RECONFIG_PARAM_A.clone()); 258 tests.push(test.freeze()); 259 } 260 { 261 let mut test = BytesMut::new(); 262 test.extend(vec![0x82, 0x0, 0x0, 0x14]); 263 test.extend(TEST_CHUNK_RECONFIG_PARAM_B.clone()); 264 tests.push(test.freeze()); 265 } 266 { 267 let mut test = BytesMut::new(); 268 test.extend(vec![0x82, 0x0, 0x0, 0x10]); 269 test.extend(TEST_CHUNK_RECONFIG_RESPONCE.clone()); 270 tests.push(test.freeze()); 271 } 272 { 273 let mut test = BytesMut::new(); 274 test.extend(vec![0x82, 0x0, 0x0, 0x2c]); 275 test.extend(TEST_CHUNK_RECONFIG_PARAM_A.clone()); 276 test.extend(vec![0u8; 2]); 277 test.extend(TEST_CHUNK_RECONFIG_PARAM_B.clone()); 278 tests.push(test.freeze()); 279 } 280 { 281 let mut test = BytesMut::new(); 282 test.extend(vec![0x82, 0x0, 0x0, 0x2a]); 283 test.extend(TEST_CHUNK_RECONFIG_PARAM_B.clone()); 284 test.extend(TEST_CHUNK_RECONFIG_PARAM_A.clone()); 285 tests.push(test.freeze()); 286 } 287 288 tests 289 }; 290 } 291 292 #[test] 293 fn test_chunk_reconfig_success() -> Result<()> { 294 for (i, binary) in TEST_CHUNK_RECONFIG_BYTES.iter().enumerate() { 295 let actual = ChunkReconfig::unmarshal(binary)?; 296 let b = actual.marshal()?; 297 assert_eq!(*binary, b, "test {} not equal: {:?} vs {:?}", i, *binary, b); 298 } 299 300 Ok(()) 301 } 302 303 #[test] 304 fn test_chunk_reconfig_unmarshal_failure() -> Result<()> { 305 let mut test = BytesMut::new(); 306 test.extend(vec![0x82, 0x0, 0x0, 0x18]); 307 test.extend(TEST_CHUNK_RECONFIG_PARAM_B.clone()); 308 test.extend(vec![0x0, 0xd, 0x0, 0x0]); 309 let tests = vec![ 310 ("chunk header to short", Bytes::from_static(&[0x82])), 311 ( 312 "missing parse param type (A)", 313 Bytes::from_static(&[0x82, 0x0, 0x0, 0x4]), 314 ), 315 ( 316 "wrong param (A)", 317 Bytes::from_static(&[0x82, 0x0, 0x0, 0x8, 0x0, 0xd, 0x0, 0x0]), 318 ), 319 ("wrong param (B)", test.freeze()), 320 ]; 321 322 for (name, binary) in tests { 323 let result = ChunkReconfig::unmarshal(&binary); 324 assert!(result.is_err(), "expected unmarshal: {} to fail.", name); 325 } 326 327 Ok(()) 328 } 329 330 /////////////////////////////////////////////////////////////////// 331 //chunk_shutdown_test 332 /////////////////////////////////////////////////////////////////// 333 use super::chunk_shutdown::*; 334 335 #[test] 336 fn test_chunk_shutdown_success() -> Result<()> { 337 let tests = vec![Bytes::from_static(&[ 338 0x07, 0x00, 0x00, 0x08, 0x12, 0x34, 0x56, 0x78, 339 ])]; 340 341 for binary in tests { 342 let actual = ChunkShutdown::unmarshal(&binary)?; 343 let b = actual.marshal()?; 344 assert_eq!(binary, b, "test not equal"); 345 } 346 347 Ok(()) 348 } 349 350 #[test] 351 fn test_chunk_shutdown_failure() -> Result<()> { 352 let tests = vec![ 353 ( 354 "length too short", 355 Bytes::from_static(&[0x07, 0x00, 0x00, 0x07, 0x12, 0x34, 0x56, 0x78]), 356 ), 357 ( 358 "length too long", 359 Bytes::from_static(&[0x07, 0x00, 0x00, 0x09, 0x12, 0x34, 0x56, 0x78]), 360 ), 361 ( 362 "payload too short", 363 Bytes::from_static(&[0x07, 0x00, 0x00, 0x08, 0x12, 0x34, 0x56]), 364 ), 365 ( 366 "payload too long", 367 Bytes::from_static(&[0x07, 0x00, 0x00, 0x08, 0x12, 0x34, 0x56, 0x78, 0x9f]), 368 ), 369 ( 370 "invalid type", 371 Bytes::from_static(&[0x08, 0x00, 0x00, 0x08, 0x12, 0x34, 0x56, 0x78]), 372 ), 373 ]; 374 375 for (name, binary) in tests { 376 let result = ChunkShutdown::unmarshal(&binary); 377 assert!(result.is_err(), "expected unmarshal: {} to fail.", name); 378 } 379 380 Ok(()) 381 } 382 383 /////////////////////////////////////////////////////////////////// 384 //chunk_shutdown_ack_test 385 /////////////////////////////////////////////////////////////////// 386 use super::chunk_shutdown_ack::*; 387 388 #[test] 389 fn test_chunk_shutdown_ack_success() -> Result<()> { 390 let tests = vec![Bytes::from_static(&[0x08, 0x00, 0x00, 0x04])]; 391 392 for binary in tests { 393 let actual = ChunkShutdownAck::unmarshal(&binary)?; 394 let b = actual.marshal()?; 395 assert_eq!(binary, b, "test not equal"); 396 } 397 398 Ok(()) 399 } 400 401 #[test] 402 fn test_chunk_shutdown_ack_failure() -> Result<()> { 403 let tests = vec![ 404 ("length too short", Bytes::from_static(&[0x08, 0x00, 0x00])), 405 ( 406 "length too long", 407 Bytes::from_static(&[0x08, 0x00, 0x00, 0x04, 0x12]), 408 ), 409 ( 410 "invalid type", 411 Bytes::from_static(&[0x0f, 0x00, 0x00, 0x04]), 412 ), 413 ]; 414 415 for (name, binary) in tests { 416 let result = ChunkShutdownAck::unmarshal(&binary); 417 assert!(result.is_err(), "expected unmarshal: {} to fail.", name); 418 } 419 420 Ok(()) 421 } 422 423 /////////////////////////////////////////////////////////////////// 424 //chunk_shutdown_complete_test 425 /////////////////////////////////////////////////////////////////// 426 use super::chunk_shutdown_complete::*; 427 428 #[test] 429 fn test_chunk_shutdown_complete_success() -> Result<()> { 430 let tests = vec![Bytes::from_static(&[0x0e, 0x00, 0x00, 0x04])]; 431 432 for binary in tests { 433 let actual = ChunkShutdownComplete::unmarshal(&binary)?; 434 let b = actual.marshal()?; 435 assert_eq!(binary, b, "test not equal"); 436 } 437 438 Ok(()) 439 } 440 441 #[test] 442 fn test_chunk_shutdown_complete_failure() -> Result<()> { 443 let tests = vec![ 444 ("length too short", Bytes::from_static(&[0x0e, 0x00, 0x00])), 445 ( 446 "length too long", 447 Bytes::from_static(&[0x0e, 0x00, 0x00, 0x04, 0x12]), 448 ), 449 ( 450 "invalid type", 451 Bytes::from_static(&[0x0f, 0x00, 0x00, 0x04]), 452 ), 453 ]; 454 455 for (name, binary) in tests { 456 let result = ChunkShutdownComplete::unmarshal(&binary); 457 assert!(result.is_err(), "expected unmarshal: {} to fail.", name); 458 } 459 460 Ok(()) 461 } 462 463 /////////////////////////////////////////////////////////////////// 464 //chunk_test 465 /////////////////////////////////////////////////////////////////// 466 use crate::chunk::chunk_init::*; 467 use crate::chunk::chunk_payload_data::*; 468 use crate::chunk::chunk_selective_ack::ChunkSelectiveAck; 469 use crate::packet::*; 470 use crate::param::param_outgoing_reset_request::ParamOutgoingResetRequest; 471 use crate::param::param_state_cookie::*; 472 473 #[test] 474 fn test_init_chunk() -> Result<()> { 475 let raw_pkt = Bytes::from_static(&[ 476 0x13, 0x88, 0x13, 0x88, 0x00, 0x00, 0x00, 0x00, 0x81, 0x46, 0x9d, 0xfc, 0x01, 0x00, 0x00, 477 0x56, 0x55, 0xb9, 0x64, 0xa5, 0x00, 0x02, 0x00, 0x00, 0x04, 0x00, 0x08, 0x00, 0xe8, 0x6d, 478 0x10, 0x30, 0xc0, 0x00, 0x00, 0x04, 0x80, 0x08, 0x00, 0x09, 0xc0, 0x0f, 0xc1, 0x80, 0x82, 479 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x24, 0x9f, 0xeb, 0xbb, 0x5c, 0x50, 0xc9, 0xbf, 0x75, 480 0x9c, 0xb1, 0x2c, 0x57, 0x4f, 0xa4, 0x5a, 0x51, 0xba, 0x60, 0x17, 0x78, 0x27, 0x94, 0x5c, 481 0x31, 0xe6, 0x5d, 0x5b, 0x09, 0x47, 0xe2, 0x22, 0x06, 0x80, 0x04, 0x00, 0x06, 0x00, 0x01, 482 0x00, 0x00, 0x80, 0x03, 0x00, 0x06, 0x80, 0xc1, 0x00, 0x00, 483 ]); 484 let pkt = Packet::unmarshal(&raw_pkt)?; 485 486 if let Some(c) = pkt.chunks[0].as_any().downcast_ref::<ChunkInit>() { 487 assert_eq!( 488 c.initiate_tag, 1438213285, 489 "Unmarshal passed for SCTP packet, but got incorrect initiate tag exp: {} act: {}", 490 1438213285, c.initiate_tag 491 ); 492 assert_eq!(c.advertised_receiver_window_credit, 131072, "Unmarshal passed for SCTP packet, but got incorrect advertisedReceiverWindowCredit exp: {} act: {}", 131072, c.advertised_receiver_window_credit); 493 assert_eq!(c.num_outbound_streams, 1024, "Unmarshal passed for SCTP packet, but got incorrect numOutboundStreams tag exp:{} act: {}", 1024, c.num_outbound_streams); 494 assert_eq!( 495 c.num_inbound_streams, 2048, 496 "Unmarshal passed for SCTP packet, but got incorrect numInboundStreams exp: {} act: {}", 497 2048, c.num_inbound_streams 498 ); 499 assert_eq!( 500 c.initial_tsn, 3899461680u32, 501 "Unmarshal passed for SCTP packet, but got incorrect initialTSN exp: {} act: {}", 502 3899461680u32, c.initial_tsn 503 ); 504 } else { 505 assert!(false, "Failed to cast Chunk -> Init"); 506 } 507 508 Ok(()) 509 } 510 511 #[test] 512 fn test_init_ack() -> Result<()> { 513 let raw_pkt = Bytes::from_static(&[ 514 0x13, 0x88, 0x13, 0x88, 0xce, 0x15, 0x79, 0xa2, 0x96, 0x19, 0xe8, 0xb2, 0x02, 0x00, 0x00, 515 0x1c, 0xeb, 0x81, 0x4e, 0x01, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x08, 0x00, 0x50, 0xdf, 516 0x90, 0xd9, 0x00, 0x07, 0x00, 0x08, 0x94, 0x06, 0x2f, 0x93, 517 ]); 518 let pkt = Packet::unmarshal(&raw_pkt)?; 519 assert!( 520 pkt.chunks[0].as_any().downcast_ref::<ChunkInit>().is_some(), 521 "Failed to cast Chunk -> Init" 522 ); 523 524 Ok(()) 525 } 526 527 #[test] 528 fn test_chrome_chunk1_init() -> Result<()> { 529 let raw_pkt = Bytes::from_static(&[ 530 0x13, 0x88, 0x13, 0x88, 0x00, 0x00, 0x00, 0x00, 0xbc, 0xb3, 0x45, 0xa2, 0x01, 0x00, 0x00, 531 0x56, 0xce, 0x15, 0x79, 0xa2, 0x00, 0x02, 0x00, 0x00, 0x04, 0x00, 0x08, 0x00, 0x94, 0x57, 532 0x95, 0xc0, 0xc0, 0x00, 0x00, 0x04, 0x80, 0x08, 0x00, 0x09, 0xc0, 0x0f, 0xc1, 0x80, 0x82, 533 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x24, 0xff, 0x5c, 0x49, 0x19, 0x4a, 0x94, 0xe8, 0x2a, 534 0xec, 0x58, 0x55, 0x62, 0x29, 0x1f, 0x8e, 0x23, 0xcd, 0x7c, 0xe8, 0x46, 0xba, 0x58, 0x1b, 535 0x3d, 0xab, 0xd7, 0x7e, 0x50, 0xf2, 0x41, 0xb1, 0x2e, 0x80, 0x04, 0x00, 0x06, 0x00, 0x01, 536 0x00, 0x00, 0x80, 0x03, 0x00, 0x06, 0x80, 0xc1, 0x00, 0x00, 537 ]); 538 let pkt = Packet::unmarshal(&raw_pkt)?; 539 let raw_pkt2 = pkt.marshal()?; 540 assert_eq!(raw_pkt, raw_pkt2); 541 542 Ok(()) 543 } 544 545 #[test] 546 fn test_chrome_chunk2_init_ack() -> Result<()> { 547 let raw_pkt = Bytes::from_static(&[ 548 0x13, 0x88, 0x13, 0x88, 0xce, 0x15, 0x79, 0xa2, 0xb5, 0xdb, 0x2d, 0x93, 0x02, 0x00, 0x01, 549 0x90, 0x9b, 0xd5, 0xb3, 0x6f, 0x00, 0x02, 0x00, 0x00, 0x04, 0x00, 0x08, 0x00, 0xef, 0xb4, 550 0x72, 0x87, 0xc0, 0x00, 0x00, 0x04, 0x80, 0x08, 0x00, 0x09, 0xc0, 0x0f, 0xc1, 0x80, 0x82, 551 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x24, 0x2e, 0xf9, 0x9c, 0x10, 0x63, 0x72, 0xed, 0x0d, 552 0x33, 0xc2, 0xdc, 0x7f, 0x9f, 0xd7, 0xef, 0x1b, 0xc9, 0xc4, 0xa7, 0x41, 0x9a, 0x07, 0x68, 553 0x6b, 0x66, 0xfb, 0x6a, 0x4e, 0x32, 0x5d, 0xe4, 0x25, 0x80, 0x04, 0x00, 0x06, 0x00, 0x01, 554 0x00, 0x00, 0x80, 0x03, 0x00, 0x06, 0x80, 0xc1, 0x00, 0x00, 0x00, 0x07, 0x01, 0x38, 0x4b, 555 0x41, 0x4d, 0x45, 0x2d, 0x42, 0x53, 0x44, 0x20, 0x31, 0x2e, 0x31, 0x00, 0x00, 0x00, 0x00, 556 0x9c, 0x1e, 0x49, 0x5b, 0x00, 0x00, 0x00, 0x00, 0xd2, 0x42, 0x06, 0x00, 0x00, 0x00, 0x00, 557 0x00, 0x60, 0xea, 0x00, 0x00, 0xc4, 0x13, 0x3d, 0xe9, 0x86, 0xb1, 0x85, 0x75, 0xa2, 0x79, 558 0x15, 0xce, 0x9b, 0xd5, 0xb3, 0x6f, 0x20, 0xe0, 0x9f, 0x89, 0xe0, 0x27, 0x00, 0x00, 0x00, 559 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x20, 0xe0, 0x9f, 0x89, 560 0xe0, 0x27, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 561 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0x88, 0x13, 0x88, 0x00, 0x00, 0x01, 0x00, 0x01, 0x01, 562 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x56, 0xce, 0x15, 0x79, 0xa2, 0x00, 563 0x02, 0x00, 0x00, 0x04, 0x00, 0x08, 0x00, 0x94, 0x57, 0x95, 0xc0, 0xc0, 0x00, 0x00, 0x04, 564 0x80, 0x08, 0x00, 0x09, 0xc0, 0x0f, 0xc1, 0x80, 0x82, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 565 0x24, 0xff, 0x5c, 0x49, 0x19, 0x4a, 0x94, 0xe8, 0x2a, 0xec, 0x58, 0x55, 0x62, 0x29, 0x1f, 566 0x8e, 0x23, 0xcd, 0x7c, 0xe8, 0x46, 0xba, 0x58, 0x1b, 0x3d, 0xab, 0xd7, 0x7e, 0x50, 0xf2, 567 0x41, 0xb1, 0x2e, 0x80, 0x04, 0x00, 0x06, 0x00, 0x01, 0x00, 0x00, 0x80, 0x03, 0x00, 0x06, 568 0x80, 0xc1, 0x00, 0x00, 0x02, 0x00, 0x01, 0x90, 0x9b, 0xd5, 0xb3, 0x6f, 0x00, 0x02, 0x00, 569 0x00, 0x04, 0x00, 0x08, 0x00, 0xef, 0xb4, 0x72, 0x87, 0xc0, 0x00, 0x00, 0x04, 0x80, 0x08, 570 0x00, 0x09, 0xc0, 0x0f, 0xc1, 0x80, 0x82, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x24, 0x2e, 571 0xf9, 0x9c, 0x10, 0x63, 0x72, 0xed, 0x0d, 0x33, 0xc2, 0xdc, 0x7f, 0x9f, 0xd7, 0xef, 0x1b, 572 0xc9, 0xc4, 0xa7, 0x41, 0x9a, 0x07, 0x68, 0x6b, 0x66, 0xfb, 0x6a, 0x4e, 0x32, 0x5d, 0xe4, 573 0x25, 0x80, 0x04, 0x00, 0x06, 0x00, 0x01, 0x00, 0x00, 0x80, 0x03, 0x00, 0x06, 0x80, 0xc1, 574 0x00, 0x00, 0xca, 0x0c, 0x21, 0x11, 0xce, 0xf4, 0xfc, 0xb3, 0x66, 0x99, 0x4f, 0xdb, 0x4f, 575 0x95, 0x6b, 0x6f, 0x3b, 0xb1, 0xdb, 0x5a, 576 ]); 577 let pkt = Packet::unmarshal(&raw_pkt)?; 578 let raw_pkt2 = pkt.marshal()?; 579 assert_eq!(raw_pkt, raw_pkt2); 580 581 Ok(()) 582 } 583 584 #[test] 585 fn test_init_marshal_unmarshal() -> Result<()> { 586 let mut p = Packet { 587 destination_port: 1, 588 source_port: 1, 589 verification_tag: 123, 590 chunks: vec![], 591 }; 592 593 let mut init_ack = ChunkInit { 594 is_ack: true, 595 initiate_tag: 123, 596 advertised_receiver_window_credit: 1024, 597 num_outbound_streams: 1, 598 num_inbound_streams: 1, 599 initial_tsn: 123, 600 params: vec![], 601 }; 602 603 let cookie = Box::new(ParamStateCookie::new()); 604 init_ack.params.push(cookie); 605 606 p.chunks.push(Box::new(init_ack)); 607 608 let raw_pkt = p.marshal()?; 609 let pkt = Packet::unmarshal(&raw_pkt)?; 610 611 if let Some(c) = pkt.chunks[0].as_any().downcast_ref::<ChunkInit>() { 612 assert_eq!( 613 c.initiate_tag, 123, 614 "Unmarshal passed for SCTP packet, but got incorrect initiate tag exp: {} act: {}", 615 123, c.initiate_tag 616 ); 617 assert_eq!(c.advertised_receiver_window_credit, 1024, "Unmarshal passed for SCTP packet, but got incorrect advertisedReceiverWindowCredit exp: {} act: {}", 1024, c.advertised_receiver_window_credit); 618 assert_eq!(c.num_outbound_streams, 1, "Unmarshal passed for SCTP packet, but got incorrect numOutboundStreams tag exp:{} act: {}", 1, c.num_outbound_streams); 619 assert_eq!( 620 c.num_inbound_streams, 1, 621 "Unmarshal passed for SCTP packet, but got incorrect numInboundStreams exp: {} act: {}", 622 1, c.num_inbound_streams 623 ); 624 assert_eq!( 625 c.initial_tsn, 123, 626 "Unmarshal passed for SCTP packet, but got incorrect initialTSN exp: {} act: {}", 627 123, c.initial_tsn 628 ); 629 } else { 630 assert!(false, "Failed to cast Chunk -> InitAck"); 631 } 632 633 Ok(()) 634 } 635 636 #[test] 637 fn test_payload_data_marshal_unmarshal() -> Result<()> { 638 let raw_pkt = Bytes::from_static(&[ 639 0x13, 0x88, 0x13, 0x88, 0xfc, 0xd6, 0x3f, 0xc6, 0xbe, 0xfa, 0xdc, 0x52, 0x0a, 0x00, 0x00, 640 0x24, 0x9b, 0x28, 0x7e, 0x48, 0xa3, 0x7b, 0xc1, 0x83, 0xc4, 0x4b, 0x41, 0x04, 0xa4, 0xf7, 641 0xed, 0x4c, 0x93, 0x62, 0xc3, 0x49, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 642 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x1f, 0xa8, 0x79, 0xa1, 0xc7, 0x00, 0x01, 0x00, 0x00, 643 0x00, 0x00, 0x00, 0x32, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 644 0x00, 0x66, 0x6f, 0x6f, 0x00, 645 ]); 646 let pkt = Packet::unmarshal(&raw_pkt)?; 647 assert!( 648 pkt.chunks[1] 649 .as_any() 650 .downcast_ref::<ChunkPayloadData>() 651 .is_some(), 652 "Failed to cast Chunk -> PayloadData" 653 ); 654 Ok(()) 655 } 656 657 #[test] 658 fn test_select_ack_chunk() -> Result<()> { 659 let raw_pkt = Bytes::from_static(&[ 660 0x13, 0x88, 0x13, 0x88, 0xc2, 0x98, 0x98, 0x0f, 0x42, 0x31, 0xea, 0x78, 0x03, 0x00, 0x00, 661 0x14, 0x87, 0x73, 0xbd, 0xa4, 0x00, 0x01, 0xfe, 0x74, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 662 0x00, 0x02, 663 ]); 664 let pkt = Packet::unmarshal(&raw_pkt)?; 665 assert!( 666 pkt.chunks[0] 667 .as_any() 668 .downcast_ref::<ChunkSelectiveAck>() 669 .is_some(), 670 "Failed to cast Chunk -> SelectiveAck" 671 ); 672 Ok(()) 673 } 674 675 #[test] 676 fn test_reconfig_chunk() -> Result<()> { 677 let raw_pkt = Bytes::from_static(&[ 678 0x13, 0x88, 0x13, 0x88, 0xb6, 0xa5, 0x12, 0xe5, 0x75, 0x3b, 0x12, 0xd3, 0x82, 0x0, 0x0, 679 0x16, 0x0, 0xd, 0x0, 0x12, 0x4e, 0x1c, 0xb9, 0xe6, 0x3a, 0x74, 0x8d, 0xff, 0x4e, 0x1c, 680 0xb9, 0xe6, 0x0, 0x1, 0x0, 0x0, 681 ]); 682 let pkt = Packet::unmarshal(&raw_pkt)?; 683 if let Some(c) = pkt.chunks[0].as_any().downcast_ref::<ChunkReconfig>() { 684 assert!(c.param_a.is_some(), "param_a must not be none"); 685 assert_eq!( 686 c.param_a 687 .as_ref() 688 .unwrap() 689 .as_any() 690 .downcast_ref::<ParamOutgoingResetRequest>() 691 .unwrap() 692 .stream_identifiers[0], 693 1, 694 "unexpected stream identifier" 695 ); 696 } else { 697 assert!(false, "Failed to cast Chunk -> Reconfig"); 698 } 699 700 Ok(()) 701 } 702 703 #[test] 704 fn test_forward_tsn_chunk() -> Result<()> { 705 let mut raw_pkt = BytesMut::new(); 706 raw_pkt.extend(vec![ 707 0x13, 0x88, 0x13, 0x88, 0xb6, 0xa5, 0x12, 0xe5, 0x1f, 0x9d, 0xa0, 0xfb, 708 ]); 709 raw_pkt.extend(CHUNK_FORWARD_TSN_BYTES.clone()); 710 let raw_pkt = raw_pkt.freeze(); 711 let pkt = Packet::unmarshal(&raw_pkt)?; 712 713 if let Some(c) = pkt.chunks[0].as_any().downcast_ref::<ChunkForwardTsn>() { 714 assert_eq!( 715 c.new_cumulative_tsn, 3, 716 "unexpected New Cumulative TSN: {}", 717 c.new_cumulative_tsn 718 ); 719 } else { 720 assert!(false, "Failed to cast Chunk -> Forward TSN"); 721 } 722 723 Ok(()) 724 } 725 726 #[test] 727 fn test_select_ack_chunk_followed_by_a_payload_data_chunk() -> Result<()> { 728 let raw_pkt = Bytes::from_static(&[ 729 0x13, 0x88, 0x13, 0x88, 0xc2, 0x98, 0x98, 0x0f, 0x58, 0xcf, 0x38, 730 0xC0, // A SACK chunk follows. 731 0x03, 0x00, 0x00, 0x14, 0x87, 0x73, 0xbd, 0xa4, 0x00, 0x01, 0xfe, 0x74, 0x00, 0x01, 0x00, 732 0x00, 0x00, 0x02, 0x00, 0x02, // A payload data chunk follows. 733 0x00, 0x07, 0x00, 0x3B, 0xA4, 0x50, 0x7B, 0xC5, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 734 0x33, 0x7B, 0x22, 0x65, 0x76, 0x65, 0x6E, 0x74, 0x22, 0x3A, 0x22, 0x72, 0x65, 0x73, 0x69, 735 0x7A, 0x65, 0x22, 0x2C, 0x22, 0x77, 0x69, 0x64, 0x74, 0x68, 0x22, 0x3A, 0x36, 0x36, 0x35, 736 0x2C, 0x22, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x22, 0x3A, 0x34, 0x39, 0x39, 0x7D, 0x00, 737 ]); 738 let pkt = Packet::unmarshal(&raw_pkt)?; 739 assert!( 740 pkt.chunks[0] 741 .as_any() 742 .downcast_ref::<ChunkSelectiveAck>() 743 .is_some(), 744 "Failed to cast Chunk -> SelectiveAck" 745 ); 746 assert!( 747 pkt.chunks[1] 748 .as_any() 749 .downcast_ref::<ChunkPayloadData>() 750 .is_some(), 751 "Failed to cast Chunk -> PayloadData" 752 ); 753 Ok(()) 754 } 755