netstack 0.3.0

A batteries included networking crate for games.
Documentation
use sha2::Sha256;
use hmac::{Hmac, Mac};
use std::io::{self, Write};
use super::{RawPacket, HEADER_SIZE};
use crate::security::Secret;

type HmacSha256 = Hmac<Sha256>;

pub struct OutgoingPacket {
    buffer: [u8; 1500],
    bytes_written: usize,
}

impl OutgoingPacket {
    pub fn new() -> Self {
        Self {
            buffer: [0; 1500],
            bytes_written: HEADER_SIZE,
        }
    }

    pub(crate) fn write_header_and_sign(self, sequence_number: u64, ack_sequence_number: u64, ack_bits: [u8; 4], packet_type: u8, secret: &Secret) -> RawPacket {
        let bytes_written = self.bytes_written;
        let mut packet = RawPacket::new(self.buffer, bytes_written);
        let mut header = packet.get_header_mut();
        
        header.sequence_number = sequence_number;
        header.ack_sequence_number = ack_sequence_number;
        header.ack_bits = ack_bits;
        header.packet_type = packet_type;
        header.body_length = (bytes_written - HEADER_SIZE) as u16;

        let mut mac = HmacSha256::new_varkey(secret.get_bytes()).expect("HmacSha256 can take a key of any size");
        mac.input(&packet.get_buffer()[32..bytes_written]);

        let mut header = packet.get_header_mut();
        header.hmac = mac.result().code().into();

        packet
    }
}

impl Write for OutgoingPacket {
    fn write(&mut self, buf: &[u8]) -> Result<usize, std::io::Error> {
        let len = buf.len();
        if self.bytes_written + len > self.buffer.len() {
            panic!("TODO: cannot write, would exceed buffer");
        }

        self.buffer[self.bytes_written..self.bytes_written + len].copy_from_slice(buf);
        self.bytes_written += len;

        Ok(len)
    }
    
    fn flush(&mut self) -> Result<(), io::Error> {
        Ok(())
    }
}