From 05777be57026a90b91dcc7ffc624f48acc0e759a Mon Sep 17 00:00:00 2001 From: Alessandro Ghedini Date: Thu, 7 Nov 2019 15:02:01 +0000 Subject: [PATCH] pin Connection Due to the fact that we store a pointer to the Connection object inside its own Handshake context, Connection objects cannot be moved (which is why we return a boxed object from its constructor). Using Pin on it makes the compiler enforce this. Fixes #45. --- README.md | 2 +- examples/http3-server.rs | 4 ++-- examples/server.rs | 2 +- src/ffi.rs | 6 +++--- src/lib.rs | 16 +++++++++------- 5 files changed, 16 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index 3a28be24dc..6955b21818 100644 --- a/README.md +++ b/README.md @@ -207,7 +207,7 @@ be linked directly into C/C++ applications. Building -------- -quiche requires Rust 1.38 or later to build. The latest stable Rust release can +quiche requires Rust 1.39 or later to build. The latest stable Rust release can be installed using [rustup](https://rustup.rs/). Once the Rust build environment is setup, the quiche source code can be fetched diff --git a/examples/http3-server.rs b/examples/http3-server.rs index c6f234aa70..2f17224679 100644 --- a/examples/http3-server.rs +++ b/examples/http3-server.rs @@ -62,7 +62,7 @@ struct PartialResponse { } struct Client { - conn: Box, + conn: std::pin::Pin>, http3_conn: Option, @@ -367,7 +367,7 @@ fn main() { loop { let http3_conn = client.http3_conn.as_mut().unwrap(); - match http3_conn.poll(client.conn.as_mut()) { + match http3_conn.poll(&mut client.conn) { Ok(( stream_id, quiche::h3::Event::Headers { list, .. }, diff --git a/examples/server.rs b/examples/server.rs index 692b02633d..2436fef391 100644 --- a/examples/server.rs +++ b/examples/server.rs @@ -64,7 +64,7 @@ struct PartialResponse { } struct Client { - conn: Box, + conn: std::pin::Pin>, partial_responses: HashMap, } diff --git a/src/ffi.rs b/src/ffi.rs index ba4f7ca4d4..d3df0923bd 100644 --- a/src/ffi.rs +++ b/src/ffi.rs @@ -296,7 +296,7 @@ pub extern fn quiche_accept( }; match accept(scid, odcid, config) { - Ok(c) => Box::into_raw(c), + Ok(c) => Box::into_raw(Pin::into_inner(c)), Err(_) => ptr::null_mut(), } @@ -316,7 +316,7 @@ pub extern fn quiche_connect( let scid = unsafe { slice::from_raw_parts(scid, scid_len) }; match connect(server_name, scid, config) { - Ok(c) => Box::into_raw(c), + Ok(c) => Box::into_raw(Pin::into_inner(c)), Err(_) => ptr::null_mut(), } @@ -373,7 +373,7 @@ pub extern fn quiche_conn_new_with_tls( let tls = unsafe { tls::Handshake::from_ptr(ssl) }; match Connection::with_tls(scid, odcid, config, tls, is_server) { - Ok(c) => Box::into_raw(c), + Ok(c) => Box::into_raw(Pin::into_inner(c)), Err(_) => ptr::null_mut(), } diff --git a/src/lib.rs b/src/lib.rs index fbd8879f53..e549ba4872 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -239,6 +239,8 @@ extern crate log; use std::cmp; use std::time; +use std::pin::Pin; + /// The current QUIC wire version. pub const PROTOCOL_VERSION: u32 = 0xff00_0017; @@ -771,7 +773,7 @@ pub struct Connection { /// ``` pub fn accept( scid: &[u8], odcid: Option<&[u8]>, config: &mut Config, -) -> Result> { +) -> Result>> { let conn = Connection::new(scid, odcid, config, true)?; Ok(conn) @@ -794,7 +796,7 @@ pub fn accept( /// ``` pub fn connect( server_name: Option<&str>, scid: &[u8], config: &mut Config, -) -> Result> { +) -> Result>> { let conn = Connection::new(scid, None, config, false)?; if let Some(server_name) = server_name { @@ -900,7 +902,7 @@ pub fn retry( impl Connection { fn new( scid: &[u8], odcid: Option<&[u8]>, config: &mut Config, is_server: bool, - ) -> Result> { + ) -> Result>> { let tls = config.tls_ctx.new_handshake()?; Connection::with_tls(scid, odcid, config, tls, is_server) } @@ -908,13 +910,13 @@ impl Connection { fn with_tls( scid: &[u8], odcid: Option<&[u8]>, config: &mut Config, tls: tls::Handshake, is_server: bool, - ) -> Result> { + ) -> Result>> { let max_rx_data = config.local_transport_params.initial_max_data; let scid_as_hex: Vec = scid.iter().map(|b| format!("{:02x}", b)).collect(); - let mut conn = Box::new(Connection { + let mut conn = Box::pin(Connection { version: config.version, dcid: Vec::new(), @@ -3167,8 +3169,8 @@ pub mod testing { use super::*; pub struct Pipe { - pub client: Box, - pub server: Box, + pub client: Pin>, + pub server: Pin>, } impl Pipe {