Skip to content

Commit 8da4578

Browse files
committed
Port CRC optimizations from webrtc-rs/sctp made by
@KillingSpark Changes from webrtc-rs/webrtc#569 and webrtc-rs/webrtc#364
1 parent 2295ae3 commit 8da4578

File tree

4 files changed

+16
-18
lines changed

4 files changed

+16
-18
lines changed

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ rand = "0.8.5"
1818
slab = "0.4.9"
1919
thiserror = "1.0.58"
2020
log = "0.4.21"
21-
crc = "3.0.1"
21+
crc = "3.2.1"
2222

2323
[dev-dependencies]
2424
assert_matches = "1.5.0"

src/chunk/chunk_payload_data.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -224,7 +224,7 @@ impl Chunk for ChunkPayloadData {
224224
writer.put_u16(self.stream_identifier);
225225
writer.put_u16(self.stream_sequence_number);
226226
writer.put_u32(self.payload_type as u32);
227-
writer.extend(self.user_data.clone());
227+
writer.extend_from_slice(&self.user_data);
228228

229229
Ok(writer.len())
230230
}

src/packet.rs

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ use crate::error::{Error, Result};
1818
use crate::util::*;
1919

2020
use bytes::{Buf, BufMut, Bytes, BytesMut};
21-
use crc::{Crc, CRC_32_ISCSI};
2221
use std::fmt;
2322

2423
///Packet represents an SCTP packet, defined in https://tools.ietf.org/html/rfc4960#section-3
@@ -278,30 +277,29 @@ impl Packet {
278277
writer.put_u16(self.common_header.destination_port);
279278
writer.put_u32(self.common_header.verification_tag);
280279

280+
// This is where the checksum will be written
281+
let checksum_pos = writer.len();
282+
writer.extend_from_slice(&[0, 0, 0, 0]);
283+
281284
// Populate chunks
282-
let mut raw = BytesMut::new();
283285
for c in &self.chunks {
284-
let chunk_raw = c.marshal()?;
285-
raw.extend(chunk_raw);
286+
c.marshal_to(writer)?;
286287

287-
let padding_needed = get_padding_size(raw.len());
288+
let padding_needed = get_padding_size(writer.len());
288289
if padding_needed != 0 {
289-
raw.extend(vec![0u8; padding_needed]);
290+
// padding needed if < 4 because we pad to 4
291+
writer.extend_from_slice(&[0u8; 16][..padding_needed]);
290292
}
291293
}
292-
let raw = raw.freeze();
293294

294-
let hasher = Crc::<u32>::new(&CRC_32_ISCSI);
295-
let mut digest = hasher.digest();
295+
let mut digest = ISCSI_CRC.digest();
296296
digest.update(writer);
297-
digest.update(&FOUR_ZEROES);
298-
digest.update(&raw[..]);
299297
let checksum = digest.finalize();
300298

301299
// Checksum is already in BigEndian
302300
// Using LittleEndian stops it from being flipped
303-
writer.put_u32_le(checksum);
304-
writer.extend(raw);
301+
let checksum_place = &mut writer[checksum_pos..checksum_pos + 4];
302+
checksum_place.copy_from_slice(&checksum.to_le_bytes());
305303

306304
Ok(writer.len())
307305
}

src/util.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use crate::shared::AssociationId;
22

33
use bytes::Bytes;
4-
use crc::{Crc, CRC_32_ISCSI};
4+
use crc::{Crc, Table, CRC_32_ISCSI};
55
use std::time::Duration;
66

77
/// This function is non-inline to prevent the optimizer from looking inside it.
@@ -81,11 +81,11 @@ pub(crate) fn get_padding_size(len: usize) -> usize {
8181
/// Allocate and zero this data once.
8282
/// We need to use it for the checksum and don't want to allocate/clear each time.
8383
pub(crate) static FOUR_ZEROES: Bytes = Bytes::from_static(&[0, 0, 0, 0]);
84+
pub(crate) const ISCSI_CRC: Crc<u32, Table<16>> = Crc::<u32, Table<16>>::new(&CRC_32_ISCSI);
8485

8586
/// Fastest way to do a crc32 without allocating.
8687
pub(crate) fn generate_packet_checksum(raw: &Bytes) -> u32 {
87-
let hasher = Crc::<u32>::new(&CRC_32_ISCSI);
88-
let mut digest = hasher.digest();
88+
let mut digest = ISCSI_CRC.digest();
8989
digest.update(&raw[0..8]);
9090
digest.update(&FOUR_ZEROES[..]);
9191
digest.update(&raw[12..]);

0 commit comments

Comments
 (0)