Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ env:
RUST_BACKTRACE: 1
# Pin the nightly toolchain to prevent breakage.
# This should be occasionally updated.
RUST_NIGHTLY_TOOLCHAIN: nightly-2023-02-20
RUST_NIGHTLY_TOOLCHAIN: nightly-2023-06-12
CDN: https://dnglbrstg7yg.cloudfront.net
# enable unstable features for testing
S2N_UNSTABLE_CRYPTO_OPT_TX: 100
Expand Down Expand Up @@ -260,8 +260,9 @@ jobs:
miri:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
crate: [quic/s2n-quic-core]
crate: [quic/s2n-quic-core, quic/s2n-quic-platform]
steps:
- uses: actions/checkout@v3
with:
Expand Down Expand Up @@ -679,8 +680,9 @@ jobs:
kani:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
crate: [quic/s2n-quic-core, tools/xdp/s2n-quic-xdp]
crate: [quic/s2n-quic-core, quic/s2n-quic-platform, tools/xdp/s2n-quic-xdp]
steps:
- uses: actions/checkout@v3
with:
Expand Down
34 changes: 34 additions & 0 deletions quic/s2n-quic-core/src/io/tx.rs
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,40 @@ impl<Handle: path::Handle, Payload: AsRef<[u8]>> Message for (Handle, Payload) {
}
}

impl<Handle: path::Handle, Payload: AsRef<[u8]>> Message
for (Handle, ExplicitCongestionNotification, Payload)
{
type Handle = Handle;

fn path_handle(&self) -> &Self::Handle {
&self.0
}

fn ecn(&mut self) -> ExplicitCongestionNotification {
self.1
}

fn delay(&mut self) -> Duration {
Default::default()
}

fn ipv6_flow_label(&mut self) -> u32 {
0
}

fn can_gso(&self, segment_len: usize, _segment_count: usize) -> bool {
segment_len >= self.2.as_ref().len()
}

fn write_payload(
&mut self,
mut buffer: PayloadBuffer,
_gso_offset: usize,
) -> Result<usize, Error> {
buffer.write(self.2.as_ref())
}
}

#[cfg(test)]
mod tests {
use super::*;
Expand Down
13 changes: 13 additions & 0 deletions quic/s2n-quic-platform/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,17 +16,30 @@ fn main() -> Result<(), Error> {
}
}

let is_miri = std::env::var("CARGO_CFG_MIRI").is_ok();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can't use cfg!(miri) for this?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The cfg isn't passed to build scripts themselves, since they run on a different "platform" than the code that they're compiling.


match env.target_os.as_str() {
"linux" => {
supports("gso");
supports("gro");
supports("mtu_disc");
supports("pktinfo");
supports("tos");

// miri doesn't support the way we detect syscall support so override it
if is_miri {
supports("socket_msg");
supports("socket_mmsg");
}
}
"macos" => {
supports("pktinfo");
supports("tos");

// miri doesn't support the way we detect syscall support so override it
if is_miri {
supports("socket_msg");
}
}
"android" => {
supports("mtu_disc");
Expand Down
4 changes: 3 additions & 1 deletion quic/s2n-quic-platform/src/io/testing/network.rs
Original file line number Diff line number Diff line change
Expand Up @@ -431,6 +431,8 @@ mod tests {
addrs.push(buffers.generate_addr());
}

assert_debug_snapshot!(addrs);
if !cfg!(miri) {
assert_debug_snapshot!(addrs);
}
}
}
8 changes: 7 additions & 1 deletion quic/s2n-quic-platform/src/io/tokio/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ use core::{
use s2n_quic_core::{
endpoint::{self, CloseError},
event,
inet::ExplicitCongestionNotification,
io::{rx, tx},
path::Handle as _,
time::{Clock, Duration, Timestamp},
Expand Down Expand Up @@ -75,7 +76,8 @@ impl<const IS_SERVER: bool> Endpoint for TestEndpoint<IS_SERVER> {
_ => {
let payload = id.to_be_bytes();
let addr = self.handle;
let msg = (addr, payload);
let ecn = ExplicitCongestionNotification::Ect0;
let msg = (addr, ecn, payload);
if queue.push(msg).is_ok() {
*tx_time = Some(now);
} else {
Expand Down Expand Up @@ -208,11 +210,13 @@ static IPV4_LOCALHOST: &str = "127.0.0.1:0";
static IPV6_LOCALHOST: &str = "[::1]:0";

#[tokio::test]
#[cfg_attr(miri, ignore)]
async fn ipv4_test() -> io::Result<()> {
test(IPV4_LOCALHOST, None, IPV4_LOCALHOST, None).await
}

#[tokio::test]
#[cfg_attr(miri, ignore)]
async fn ipv4_two_socket_test() -> io::Result<()> {
test(
IPV4_LOCALHOST,
Expand All @@ -224,6 +228,7 @@ async fn ipv4_two_socket_test() -> io::Result<()> {
}

#[tokio::test]
#[cfg_attr(miri, ignore)]
async fn ipv6_test() -> io::Result<()> {
let result = test(IPV6_LOCALHOST, None, IPV6_LOCALHOST, None).await;

Expand All @@ -237,6 +242,7 @@ async fn ipv6_test() -> io::Result<()> {
}

#[tokio::test]
#[cfg_attr(miri, ignore)]
async fn ipv6_two_socket_test() -> io::Result<()> {
let result = test(
IPV6_LOCALHOST,
Expand Down
46 changes: 44 additions & 2 deletions quic/s2n-quic-platform/src/message.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0

use core::{cell::UnsafeCell, ffi::c_void, pin::Pin};
use core::{alloc::Layout, ffi::c_void, ptr::NonNull};
use s2n_quic_core::{inet::datagram, io::tx, path};

#[cfg(any(s2n_quic_platform_socket_msg, s2n_quic_platform_socket_mmsg))]
Expand All @@ -25,7 +25,49 @@ pub mod default {
}
}

pub type Storage = Pin<Box<[UnsafeCell<u8>]>>;
/// Tracks allocations of message ring buffer state
pub struct Storage {
ptr: NonNull<u8>,
layout: Layout,
}

impl Storage {
#[inline]
pub fn new(layout: Layout) -> Self {
unsafe {
let ptr = alloc::alloc::alloc_zeroed(layout);
let ptr = NonNull::new(ptr).expect("could not allocate message storage");
Self { layout, ptr }
}
}

#[inline]
pub(crate) fn as_ptr(&self) -> *mut u8 {
self.ptr.as_ptr()
}

/// Asserts that the pointer is in bounds of the allocation
#[inline]
pub(crate) fn check_bounds<T: Sized>(&self, ptr: *mut T) {
let start = self.as_ptr();
let end = unsafe {
// Safety: pointer is allocated with the self.layout
start.add(self.layout.size())
};
let allocation_range = start..=end;
let actual_end_ptr = ptr as *mut u8;
debug_assert!(allocation_range.contains(&actual_end_ptr));
}
}

impl Drop for Storage {
fn drop(&mut self) {
unsafe {
// Safety: pointer was allocated with self.layout
alloc::alloc::dealloc(self.as_ptr(), self.layout)
}
}
}

/// An abstract message that can be sent and received on a network
pub trait Message: 'static + Copy {
Expand Down
Loading