Skip to content

Commit

Permalink
Port CRC optimizations from webrtc-rs/sctp made by
Browse files Browse the repository at this point in the history
  • Loading branch information
xnorpx committed May 16, 2024
1 parent 2295ae3 commit 8da4578
Show file tree
Hide file tree
Showing 4 changed files with 16 additions and 18 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ rand = "0.8.5"
slab = "0.4.9"
thiserror = "1.0.58"
log = "0.4.21"
crc = "3.0.1"
crc = "3.2.1"

[dev-dependencies]
assert_matches = "1.5.0"
Expand Down
2 changes: 1 addition & 1 deletion src/chunk/chunk_payload_data.rs
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,7 @@ impl Chunk for ChunkPayloadData {
writer.put_u16(self.stream_identifier);
writer.put_u16(self.stream_sequence_number);
writer.put_u32(self.payload_type as u32);
writer.extend(self.user_data.clone());
writer.extend_from_slice(&self.user_data);

Ok(writer.len())
}
Expand Down
24 changes: 11 additions & 13 deletions src/packet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ use crate::error::{Error, Result};
use crate::util::*;

use bytes::{Buf, BufMut, Bytes, BytesMut};
use crc::{Crc, CRC_32_ISCSI};
use std::fmt;

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

// This is where the checksum will be written
let checksum_pos = writer.len();
writer.extend_from_slice(&[0, 0, 0, 0]);

// Populate chunks
let mut raw = BytesMut::new();
for c in &self.chunks {
let chunk_raw = c.marshal()?;
raw.extend(chunk_raw);
c.marshal_to(writer)?;

let padding_needed = get_padding_size(raw.len());
let padding_needed = get_padding_size(writer.len());
if padding_needed != 0 {
raw.extend(vec![0u8; padding_needed]);
// padding needed if < 4 because we pad to 4
writer.extend_from_slice(&[0u8; 16][..padding_needed]);
}
}
let raw = raw.freeze();

let hasher = Crc::<u32>::new(&CRC_32_ISCSI);
let mut digest = hasher.digest();
let mut digest = ISCSI_CRC.digest();
digest.update(writer);
digest.update(&FOUR_ZEROES);
digest.update(&raw[..]);
let checksum = digest.finalize();

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

Ok(writer.len())
}
Expand Down
6 changes: 3 additions & 3 deletions src/util.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::shared::AssociationId;

use bytes::Bytes;
use crc::{Crc, CRC_32_ISCSI};
use crc::{Crc, Table, CRC_32_ISCSI};
use std::time::Duration;

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

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

0 comments on commit 8da4578

Please sign in to comment.