dope-tls 0.13.0

TCP TLS streams for dope runtime, shin-backed
Documentation
use dope_net::wire::buffered::{Buffer, Scratch};
use dope_net::wire::send::{Plain, Prepared, Storage, Vectored};

use crate::tls::SendState;

pub(crate) trait SendProtocol {
    fn encrypt(&mut self, egress: &mut Buffer<Scratch>, plain: &[u8]) -> usize;
    fn propagate_close(&mut self, egress: &mut Buffer<Scratch>) -> bool;
    fn drain_to_egress(&mut self, egress: &mut Buffer<Scratch>);
    fn send_inflight(&mut self) -> &mut bool;
}

pub(crate) struct Sender<'a, P> {
    protocol: &'a mut P,
}

impl<'a, P: SendProtocol> Sender<'a, P> {
    pub(crate) fn new(protocol: &'a mut P) -> Self {
        Self { protocol }
    }

    pub(crate) fn prepare<'b>(
        &mut self,
        mut send: Storage<'b, SendState>,
        plain: Plain<'b>,
    ) -> Prepared<'b> {
        let consumed = self.protocol.encrypt(&mut send.0, plain.as_slice());
        let close = self.protocol.propagate_close(&mut send.0);
        self.finish(send, consumed, close)
    }

    pub(crate) fn prepare_vectored<'b>(
        &mut self,
        mut send: Storage<'b, SendState>,
        vectored: Vectored<'b>,
    ) -> Prepared<'b> {
        let mut consumed = 0;
        for plain in vectored.iter() {
            if plain.is_empty() {
                continue;
            }
            let current = self.protocol.encrypt(&mut send.0, plain);
            consumed += current;
            if current < plain.len() {
                break;
            }
        }
        let close = self.protocol.propagate_close(&mut send.0);
        self.finish(send, consumed, close)
    }

    pub(crate) fn after_send<'b>(
        &mut self,
        mut send: Storage<'b, SendState>,
        written: usize,
    ) -> Prepared<'b> {
        *self.protocol.send_inflight() = false;
        send.0.consume(written);
        self.protocol.drain_to_egress(&mut send.0);
        let close = self.protocol.propagate_close(&mut send.0);
        self.finish(send, 0, close)
    }

    pub(crate) fn flush<'b>(&mut self, mut send: Storage<'b, SendState>) -> Prepared<'b> {
        self.protocol.encrypt(&mut send.0, &[]);
        let close = self.protocol.propagate_close(&mut send.0);
        self.finish(send, 0, close)
    }

    pub(crate) fn finish<'b>(
        &mut self,
        send: Storage<'b, SendState>,
        consumed: usize,
        close: bool,
    ) -> Prepared<'b> {
        *self.protocol.send_inflight() = !send.0.is_empty();
        let prepared = send.buffered(consumed);
        if close {
            prepared.close_after()
        } else {
            prepared
        }
    }
}