Fix (maybe) issue about first frame being dropped on new client

pull/38/head
Chip Senkbeil 3 years ago
parent 4c69584f63
commit 4c249abf6a
No known key found for this signature in database
GPG Key ID: 35EF1F8EC72A4131

@ -77,6 +77,7 @@ impl Transport {
}
/// Splits transport into read and write halves
#[allow(dead_code)]
pub fn split(self) -> (TransportReadHalf, TransportWriteHalf) {
let key = self.key;
let parts = self.inner.into_parts();
@ -86,6 +87,13 @@ impl Transport {
// into the new framed instances. This means we are dropping our old buffer
// data (I think). This shouldn't be a problem since we are splitting
// immediately, but it would be nice to cover this properly one day
//
// From initial testing, this may actually be a problem where part of a frame
// arrives so quickly that we lose the first message. So recommendation for
// now is to create the frame halves separately first so we have no
// chance of building a partial frame
//
// See https://github.com/tokio-rs/tokio/issues/4000
let t_read = TransportReadHalf {
inner: FramedRead::new(read_half, parts.codec),
key: Arc::clone(&key),
@ -106,6 +114,14 @@ pub struct TransportWriteHalf {
}
impl TransportWriteHalf {
/// Creates a new transport write half directly from a TCP write half
pub fn new(write_half: tcp::OwnedWriteHalf, key: Arc<SecretKey>) -> Self {
Self {
inner: FramedWrite::new(write_half, DistantCodec),
key,
}
}
/// Sends some data across the wire
pub async fn send<T: Serialize>(&mut self, data: T) -> Result<(), TransportError> {
// Serialize, encrypt, and then (TODO) sign
@ -127,6 +143,14 @@ pub struct TransportReadHalf {
}
impl TransportReadHalf {
/// Creates a new transport read half directly from a TCP read half
pub fn new(read_half: tcp::OwnedReadHalf, key: Arc<SecretKey>) -> Self {
Self {
inner: FramedRead::new(read_half, DistantCodec),
key,
}
}
/// Receives some data from out on the wire, waiting until it's available,
/// returning none if the transport is now closed
pub async fn receive<T: DeserializeOwned>(&mut self) -> Result<Option<T>, TransportError> {

@ -1,6 +1,6 @@
use crate::{
data::{Request, Response},
net::{Transport, TransportReadHalf, TransportWriteHalf},
net::{TransportReadHalf, TransportWriteHalf},
opt::{CommonOpt, ConvertToIpAddrError, ListenSubcommand},
};
use derive_more::{Display, Error, From};
@ -132,7 +132,9 @@ async fn run_async(cmd: ListenSubcommand, _opt: CommonOpt, is_forked: bool) -> R
// Build a transport around the client, splitting into read and write halves so we can
// handle input and output concurrently
let (t_read, t_write) = Transport::new(client, Arc::clone(&key)).split();
let (r, w) = client.into_split();
let t_read = TransportReadHalf::new(r, Arc::clone(&key));
let t_write = TransportWriteHalf::new(w, Arc::clone(&key));
let (tx, rx) = mpsc::channel(cmd.max_msg_capacity as usize);
// Spawn a new task that loops to handle requests from the client

Loading…
Cancel
Save