/src/tungstenite-rs/src/protocol/frame/mask.rs
Line | Count | Source |
1 | | /// Generate a random frame mask. |
2 | | #[inline] |
3 | 0 | pub fn generate_mask() -> [u8; 4] { |
4 | 0 | rand::random() |
5 | 0 | } |
6 | | |
7 | | /// Mask/unmask a frame. |
8 | | #[inline] |
9 | 1.68M | pub fn apply_mask(buf: &mut [u8], mask: [u8; 4]) { |
10 | 1.68M | apply_mask_fast32(buf, mask); |
11 | 1.68M | } tungstenite::protocol::frame::mask::apply_mask Line | Count | Source | 9 | 1.68M | pub fn apply_mask(buf: &mut [u8], mask: [u8; 4]) { | 10 | 1.68M | apply_mask_fast32(buf, mask); | 11 | 1.68M | } |
Unexecuted instantiation: tungstenite::protocol::frame::mask::apply_mask Unexecuted instantiation: tungstenite::protocol::frame::mask::apply_mask |
12 | | |
13 | | /// A safe unoptimized mask application. |
14 | | #[inline] |
15 | 3.37M | fn apply_mask_fallback(buf: &mut [u8], mask: [u8; 4]) { |
16 | 3.37M | for (i, byte) in buf.iter_mut().enumerate() { |
17 | 1.09M | *byte ^= mask[i & 3]; |
18 | 1.09M | } |
19 | 3.37M | } tungstenite::protocol::frame::mask::apply_mask_fallback Line | Count | Source | 15 | 3.37M | fn apply_mask_fallback(buf: &mut [u8], mask: [u8; 4]) { | 16 | 3.37M | for (i, byte) in buf.iter_mut().enumerate() { | 17 | 1.09M | *byte ^= mask[i & 3]; | 18 | 1.09M | } | 19 | 3.37M | } |
Unexecuted instantiation: tungstenite::protocol::frame::mask::apply_mask_fallback Unexecuted instantiation: tungstenite::protocol::frame::mask::apply_mask_fallback |
20 | | |
21 | | /// Faster version of `apply_mask()` which operates on 4-byte blocks. |
22 | | #[inline] |
23 | 1.68M | pub fn apply_mask_fast32(buf: &mut [u8], mask: [u8; 4]) { |
24 | 1.68M | let mask_u32 = u32::from_ne_bytes(mask); |
25 | | |
26 | 1.68M | let (prefix, words, suffix) = unsafe { buf.align_to_mut::<u32>() }; |
27 | 1.68M | apply_mask_fallback(prefix, mask); |
28 | 1.68M | let head = prefix.len() & 3; |
29 | 1.68M | let mask_u32 = if head > 0 { |
30 | 337k | if cfg!(target_endian = "big") { |
31 | 0 | mask_u32.rotate_left(8 * head as u32) |
32 | | } else { |
33 | 337k | mask_u32.rotate_right(8 * head as u32) |
34 | | } |
35 | | } else { |
36 | 1.34M | mask_u32 |
37 | | }; |
38 | 10.0M | for word in words.iter_mut() { |
39 | 10.0M | *word ^= mask_u32; |
40 | 10.0M | } |
41 | 1.68M | apply_mask_fallback(suffix, mask_u32.to_ne_bytes()); |
42 | 1.68M | } tungstenite::protocol::frame::mask::apply_mask_fast32 Line | Count | Source | 23 | 1.68M | pub fn apply_mask_fast32(buf: &mut [u8], mask: [u8; 4]) { | 24 | 1.68M | let mask_u32 = u32::from_ne_bytes(mask); | 25 | | | 26 | 1.68M | let (prefix, words, suffix) = unsafe { buf.align_to_mut::<u32>() }; | 27 | 1.68M | apply_mask_fallback(prefix, mask); | 28 | 1.68M | let head = prefix.len() & 3; | 29 | 1.68M | let mask_u32 = if head > 0 { | 30 | 337k | if cfg!(target_endian = "big") { | 31 | 0 | mask_u32.rotate_left(8 * head as u32) | 32 | | } else { | 33 | 337k | mask_u32.rotate_right(8 * head as u32) | 34 | | } | 35 | | } else { | 36 | 1.34M | mask_u32 | 37 | | }; | 38 | 10.0M | for word in words.iter_mut() { | 39 | 10.0M | *word ^= mask_u32; | 40 | 10.0M | } | 41 | 1.68M | apply_mask_fallback(suffix, mask_u32.to_ne_bytes()); | 42 | 1.68M | } |
Unexecuted instantiation: tungstenite::protocol::frame::mask::apply_mask_fast32 Unexecuted instantiation: tungstenite::protocol::frame::mask::apply_mask_fast32 |
43 | | |
44 | | #[cfg(test)] |
45 | | mod tests { |
46 | | use super::*; |
47 | | |
48 | | #[test] |
49 | | fn test_apply_mask() { |
50 | | let mask = [0x6d, 0xb6, 0xb2, 0x80]; |
51 | | let unmasked = [ |
52 | | 0xf3, 0x00, 0x01, 0x02, 0x03, 0x80, 0x81, 0x82, 0xff, 0xfe, 0x00, 0x17, 0x74, 0xf9, |
53 | | 0x12, 0x03, |
54 | | ]; |
55 | | |
56 | | for data_len in 0..=unmasked.len() { |
57 | | let unmasked = &unmasked[0..data_len]; |
58 | | // Check masking with different alignment. |
59 | | for off in 0..=3 { |
60 | | if unmasked.len() < off { |
61 | | continue; |
62 | | } |
63 | | let mut masked = unmasked.to_vec(); |
64 | | apply_mask_fallback(&mut masked[off..], mask); |
65 | | |
66 | | let mut masked_fast = unmasked.to_vec(); |
67 | | apply_mask_fast32(&mut masked_fast[off..], mask); |
68 | | |
69 | | assert_eq!(masked, masked_fast); |
70 | | } |
71 | | } |
72 | | } |
73 | | } |