Pārlūkot izejas kodu

added CRC32 checksum and a justfile

master
Isabelle L. pirms 5 gadiem
vecāks
revīzija
18b3c7c1e4
5 mainītis faili ar 69 papildinājumiem un 31 dzēšanām
  1. +1
    -0
      Cargo.toml
  2. +8
    -6
      README.md
  3. +4
    -0
      justfile
  4. +54
    -23
      src/lib.rs
  5. +2
    -2
      src/message.rs

+ 1
- 0
Cargo.toml Parādīt failu

@@ -14,3 +14,4 @@ chrono = "0.4.11"
ring = "0.16.13" ring = "0.16.13"
anyhow = "1.0.30" anyhow = "1.0.30"
thiserror = "1.0.17" thiserror = "1.0.17"
crc32fast = "1.2.0"

+ 8
- 6
README.md Parādīt failu

@@ -5,9 +5,11 @@
I don't know whether or not this is a super practical way of doing things I don't know whether or not this is a super practical way of doing things
but i'm lazy and it seems to work so gonna roll with it lol but i'm lazy and it seems to work so gonna roll with it lol


| segment size | usage |
|--------------|-------------------------------------|
| 1 byte | u8 signifies the type of packet |
| 8 byte | u64 length of the packet contents |
| 32 byte | SHA256 packet contents checksum |
| `u64::MAX` | packet contents |
| segment size | usage |
|--------------|--------------------------------------------|
| 1 byte | u8 signifies the type of packet |
| 8 byte | u64 length of the packet contents |
| 4 byte | CRC32 packet contents checksum |
| 32 byte | SHA256 packet contents integrity check |
| `u64::MAX` | packet contents |


+ 4
- 0
justfile Parādīt failu

@@ -0,0 +1,4 @@
alias b := build

build:
cargo build

+ 54
- 23
src/lib.rs Parādīt failu

@@ -5,12 +5,13 @@
//! I don't know whether or not this is a super practical way of doing things //! I don't know whether or not this is a super practical way of doing things
//! but i'm lazy and it seems to work so gonna roll with it lol //! but i'm lazy and it seems to work so gonna roll with it lol
//! //!
//! | segment size | usage |
//! |--------------|-------------------------------------|
//! | 1 byte | u8 signifies the type of packet |
//! | 8 byte | u64 length of the packet contents |
//! | 32 byte | SHA256 packet contents checksum |
//! | `u64::MAX` | packet contents |
//! | segment size | usage |
//! |--------------|--------------------------------------------|
//! | 1 byte | u8 signifies the type of packet |
//! | 8 byte | u64 length of the packet contents |
//! | 4 byte | CRC32 packet contents checksum |
//! | 32 byte | SHA256 packet contents integrity check |
//! | `u64::MAX` | packet contents |
//! //!


use futures_util::io::{AsyncReadExt, AsyncWriteExt}; use futures_util::io::{AsyncReadExt, AsyncWriteExt};
@@ -35,21 +36,33 @@ pub trait Sendable: Sized {
/// data to be sent /// data to be sent
pub struct Packet { pub struct Packet {
kind: PacketKind, kind: PacketKind,
checksum: Vec<u8>,
integrity_hash: Vec<u8>,
contents: Vec<u8>, contents: Vec<u8>,
} }


impl Packet { impl Packet {
/// create a new `Packet` /// create a new `Packet`
pub fn new(kind: PacketKind, contents: Vec<u8>) -> Packet { pub fn new(kind: PacketKind, contents: Vec<u8>) -> Packet {
let checksum = digest::digest(&digest::SHA256, &contents).as_ref().to_vec();
let integrity_hash = digest::digest(&digest::SHA256, &contents).as_ref().to_vec();
Packet { Packet {
kind, kind,
checksum,
integrity_hash,
contents, contents,
} }
} }


// generate a checksum from the packet
fn generate_checksum(&self) -> u32 {
// combine integrity hash and contents
let mut hash_and_contents = self.integrity_hash.clone();
hash_and_contents.extend_from_slice(&self.contents);

// generate checksum
let mut hasher = crc32fast::Hasher::new();
hasher.update(hash_and_contents.as_ref());
hasher.finalize()
}

fn to_network_packet(&self) -> NetworkPacket { fn to_network_packet(&self) -> NetworkPacket {
let mut contents: Vec<u8> = Vec::new(); let mut contents: Vec<u8> = Vec::new();


@@ -61,29 +74,43 @@ impl Packet {
contents.extend_from_slice(&contents_length.to_le_bytes()); contents.extend_from_slice(&contents_length.to_le_bytes());


// write checksum // write checksum
contents.extend_from_slice(&self.checksum.as_ref());
let checksum = self.generate_checksum();
contents.extend_from_slice(&checksum.to_le_bytes());


// write contents
// write hash and contents
contents.extend_from_slice(&self.integrity_hash);
contents.extend_from_slice(&self.contents); contents.extend_from_slice(&self.contents);


NetworkPacket(contents) NetworkPacket(contents)
} }


/// verifies SHA256 checksum
/// verifies SHA256 integrity
pub fn verify_integrity(&self) -> Result<()> { pub fn verify_integrity(&self) -> Result<()> {
let found = digest::digest(&digest::SHA256, &self.contents)
let expected = digest::digest(&digest::SHA256, &self.contents)
.as_ref() .as_ref()
.to_vec(); .to_vec();
if found == self.checksum {

if expected == self.integrity_hash {
Ok(()) Ok(())
} else { } else {
Err(IlmpError::BadChecksumIntegrity {
expected: self.checksum.clone(),
found,
Err(IlmpError::BadHashIntegrity {
found: self.integrity_hash.clone(),
expected,
} }
.into()) .into())
} }
} }

/// verifies CRC32 checksum
pub fn verify_checksum(&self, expected: u32) -> Result<()> {
let found = self.generate_checksum();

if found == expected {
Ok(())
} else {
Err(IlmpError::BadChecksumIntegrity { expected, found })
}
}
} }


/// kinds of packets that can be sent /// kinds of packets that can be sent
@@ -108,7 +135,9 @@ impl PacketKind {
#[derive(Error, Debug)] #[derive(Error, Debug)]
pub enum IlmpError { pub enum IlmpError {
#[error("checksum integrity check failed: (expected {expected:?} found {found:?})")] #[error("checksum integrity check failed: (expected {expected:?} found {found:?})")]
BadChecksumIntegrity { expected: Vec<u8>, found: Vec<u8> },
BadChecksumIntegrity { expected: u32, found: u32 },
#[error("hash integrity check failed: (expected {expected:?} found {found:?})")]
BadHashIntegrity { expected: Vec<u8>, found: Vec<u8> },
#[error("std::io error")] #[error("std::io error")]
// external error conversions // external error conversions
StdIo(#[from] std::io::Error), StdIo(#[from] std::io::Error),
@@ -125,17 +154,18 @@ pub async fn read<S>(stream: &mut S) -> Result<Option<Packet>>
where where
S: AsyncReadExt + Unpin, S: AsyncReadExt + Unpin,
{ {
let mut info_buf = [0u8; 9];
let mut info_buf = [0u8; 13];
let check = stream.read(&mut info_buf).await?; let check = stream.read(&mut info_buf).await?;
if check == 0 { if check == 0 {
return Ok(None); return Ok(None);
} }


let kind = PacketKind::from_u8(info_buf[0]).unwrap(); let kind = PacketKind::from_u8(info_buf[0]).unwrap();
let length = u32::from_le_bytes(info_buf[1..9].try_into().unwrap()) as usize;
let length = u64::from_le_bytes(info_buf[1..9].try_into().unwrap()) as usize;
let checksum = u32::from_le_bytes(info_buf[10..14].try_into().unwrap());


let mut checksum: Vec<u8> = vec![0; 32];
stream.read(&mut checksum).await?;
let mut integrity_hash: Vec<u8> = vec![0; 32];
stream.read(&mut integrity_hash).await?;


let mut contents: Vec<u8> = vec![0; length]; let mut contents: Vec<u8> = vec![0; length];
stream.read(&mut contents).await?; stream.read(&mut contents).await?;
@@ -143,9 +173,10 @@ where
let packet = Packet { let packet = Packet {
kind, kind,
contents, contents,
checksum,
integrity_hash,
}; };
packet.verify_integrity()?; packet.verify_integrity()?;
packet.verify_checksum(checksum)?;


Ok(Some(packet)) Ok(Some(packet))
} }


+ 2
- 2
src/message.rs Parādīt failu

@@ -31,12 +31,12 @@ impl Message {
impl crate::Sendable for Message { impl crate::Sendable for Message {
fn to_packet(&self) -> Result<Packet> { fn to_packet(&self) -> Result<Packet> {
let contents: Vec<u8> = serde_json::to_string(&self)?.into_bytes(); let contents: Vec<u8> = serde_json::to_string(&self)?.into_bytes();
let checksum = digest::digest(&digest::SHA256, &contents).as_ref().to_vec();
let integrity_hash = digest::digest(&digest::SHA256, &contents).as_ref().to_vec();
let kind = PacketKind::Message; let kind = PacketKind::Message;


Ok(Packet { Ok(Packet {
kind, kind,
checksum,
integrity_hash,
contents, contents,
}) })
} }


Notiek ielāde…
Atcelt
Saglabāt