added crypt_buf_ptr to EncryptedWriteHalf

no-dual
Avril 4 years ago
parent 9836850691
commit 2056ff6a58
Signed by: flanchan
GPG Key ID: 284488987C31F630

@ -214,4 +214,5 @@ pub mod bytes
} }
} }
pub mod slice; mod slice;
pub use slice::*;

@ -20,6 +20,13 @@ pub trait AsyncStream: AsyncRead + AsyncWrite{}
impl<T: AsyncRead + AsyncWrite + ?Sized> AsyncStream for T{} impl<T: AsyncRead + AsyncWrite + ?Sized> AsyncStream for T{}
/// Inner rsa data for encrypted stream read+write halves /// Inner rsa data for encrypted stream read+write halves
///
/// # Exchange / mutation
/// For split streams, this becomes immutable. If exchange has not been performed by the combined stream before splitting, then it is impossible for the split Read and Write halves to form EncryptedRead and EncryptedWrite instances on top of themselves.
/// The stream must be re-joined, exchanged, and then split again in this case.
/// Therefore exchange should happen before the original stream is split at all.
///
/// Only the combined stream can mutate this structure. The halves hold it behind an immutable shared reference.
struct EncryptedStreamMeta struct EncryptedStreamMeta
{ {
us: RsaPrivateKey, us: RsaPrivateKey,
@ -31,7 +38,11 @@ struct EncryptedStreamMeta
pub struct WriteHalf<S> pub struct WriteHalf<S>
where S: AsyncWrite where S: AsyncWrite
{ {
meta: Arc<EncryptedStreamMeta>, /// Shared reference to the RSA data of the backing stream, held by both Write and Read halves.
///
/// # Immutability of this metadata
/// Exchange can only happen on the combined Read+Write stream, so we don't need ayn mutability of `meta` here. Mutating `meta` happens only when it's owned by the combined stream (not in an `Arc`, which is only used to share it between the Read and Write half).
meta: Arc<EncryptedStreamMeta>,
#[pin] backing_write: S,//Box<dual::DualStream<S>>, #[pin] backing_write: S,//Box<dual::DualStream<S>>,
} }
@ -40,8 +51,36 @@ where S: AsyncWrite
pub struct EncryptedWriteHalf<'a, S> pub struct EncryptedWriteHalf<'a, S>
where S: AsyncWrite, where S: AsyncWrite,
{ {
/// Used to transform input `buf` into `self.crypt_buffer` before polling a write to `backing_write` with the newly filled `self.crypt_buffer`.
/// See below 2 fields.
cipher: Crypter, cipher: Crypter,
// Buffer for when `backing.poll_write()` returns `Pending`.
/// Slice pointer of the input `buf` that corresponds to the transformed data in `crypt_buf`.
/// Used to check if a `Pending` write was cancelled, by comparing if the input `buf` slice of this next write is different from the last one (which's data is stored in this field after the poll becomes `Pending`.)
///
/// # Usage
/// Before checking is `crypt_buffer` is empty and that we should re-poll the backing stream with it, we check the input `buf` against this value.
/// If they differ, then the `Pending` result from the last poll was discarded, and we clear the `crypt_buffer` and re-encrypt the new `buf` into it.
///
/// After a `Pending` write to `backing_write`, a `SliceMeta` from the input `buf` is written to this field.
/// If it was *not* a `Pending` poll result, then this field is re-set to `Default` (an invalid `null` value).
///
/// This compares **pointer** and **length** identity of the slice. (See `SliceMeta` for more information.)
/// Which is a faster method of determining if the buffer has changed than applying `Hash` to the whole buffer each time `poll_write` is called just to compare.
///
/// # Initialised
/// Initialised as `Default` (`null`).
/// Will be `null` if `crypt_buffer` is empty (i.e. a non-`Pending` poll result).
crypt_buf_ptr: SliceMeta<u8>,
/// Buffer written to when encrypting the input `buf`.
///
/// It is cleared after a `Ready` `poll_write()` on `backing_write`.
/// On a `Pending` write, this buffer is resized to only fit the transformed data written to it, and left as it is until the next call to `poll_write`.
///
/// If the poll was not discarded (see above field), on the next call to this instance's `poll_write` we just immediatly re-poll `backing_write` with this buffer.
/// If it was disarded. We re-set this buffer and transform the new input `buf` into it as if the previous poll returned `Ready`.
///
/// This exists so we don't have to transform the entire `buf` on every poll. We can just transform it once and then wait until it is `Ready` before discarding the data (`.empty()`) and allowing new data to fill it on the next, fresh `poll_write`.
crypt_buffer: Vec<u8>, crypt_buffer: Vec<u8>,
backing: &'a mut WriteHalf<S>, backing: &'a mut WriteHalf<S>,

Loading…
Cancel
Save