Skip to content

Commit

Permalink
Merge branch 'main' into add_active_migration
Browse files Browse the repository at this point in the history
  • Loading branch information
masa-koz committed Jan 10, 2025
2 parents 64a35a7 + bffa118 commit aaf479d
Show file tree
Hide file tree
Showing 65 changed files with 13,006 additions and 1,130 deletions.
17 changes: 16 additions & 1 deletion .github/workflows/cargo.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,20 @@ jobs:
strategy:
matrix:
os: [ubuntu-latest, windows-latest, macos-latest, macos-latest-xlarge]
features: ["", "--features static"]
features: ["", "--features static", "--features schannel", "--features schannel,static", "--features overwrite"]
exclude:
- os: ubuntu-latest
features: "--features schannel"
- os: ubuntu-latest
features: "--features schannel,static"
- os: macos-latest
features: "--features schannel"
- os: macos-latest
features: "--features schannel,static"
- os: macos-latest-xlarge
features: "--features schannel"
- os: macos-latest-xlarge
features: "--features schannel,static"
runs-on: ${{ matrix.os }}
name: Cargo
steps:
Expand Down Expand Up @@ -47,6 +60,8 @@ jobs:
run: cargo clippy --all-targets -- -D warnings
- name: Cargo build
run: cargo build --all ${{ matrix.features }}
- name: Check all generated files with git
run: git diff --exit-code
- name: Cargo test
run: cargo test --all ${{ matrix.features }}
- name: Cargo Publish (dry run)
Expand Down
2 changes: 2 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,8 @@ set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG ${QUIC_OUTPUT_DIR})

set(QUIC_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/src/inc)

include(GNUInstallDirs)

if (WIN32)
set(QUIC_WARNING_FLAGS /WX /W4 /sdl /wd4206 CACHE INTERNAL "")
set(QUIC_COMMON_FLAGS "")
Expand Down
6 changes: 5 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ include = [
"/submodules/openssl/VMS",
"/submodules/xdp-for-windows/published/external",
"/scripts/build.rs",
"/src/*.rs",
"/src/**/*.rs",
"/src/bin",
"/src/core",
"/src/inc",
Expand All @@ -46,11 +46,15 @@ include = [

[features]
default = []
schannel = []
static = []
preview-api = []
# Overwrite generated binding by reruning the bindgen
overwrite = [ "dep:bindgen" ]

[build-dependencies]
cmake = "0.1"
bindgen = { version = "0.71", optional = true }

[dependencies]
bitfield = "0.17.0"
Expand Down
31 changes: 30 additions & 1 deletion docs/api/DatagramSend.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,36 @@ QUIC_STATUS
# Parameters
**TODO**
`Connection`
The current established connection.
`Buffers`
An array of `QUIC_BUFFER` structs that each contain a pointer and length to app data to send on the stream. This may be `NULL` **only** if `BufferCount` is zero.
`BufferCount`
The number of `QUIC_BUFFER` structs in the `Buffers` array. This may be zero.
`Flags`
The set of flags that controls the behavior of `DatagramSend`:
Value | Meaning
--- | ---
**QUIC_SEND_FLAG_NONE**<br>0 | No special behavior. Data is not allowed in 0-RTT by default.
**QUIC_SEND_FLAG_ALLOW_0_RTT**<br>1 | Indicates that the data is allowed to be sent in 0-RTT (if available). Makes no guarantee the data will be sent in 0-RTT. Additionally, even if 0-RTT keys are available the data may end up being sent in 1-RTT for multiple reasons.
**QUIC_SEND_FLAG_START**<br>2 | **Unused and ignored** for `DatagramSend`
**QUIC_SEND_FLAG_FIN**<br>4 | **Unused and ignored** for `DatagramSend`
**QUIC_SEND_FLAG_DGRAM_PRIORITY**<br>8 | Sets a priority to ensure a datagram is sent before others.
**QUIC_SEND_FLAG_DELAY_SEND**<br>16 | **Unused and ignored** for `DatagramSend`
**QUIC_SEND_FLAG_CANCEL_ON_LOSS**<br>32 | **Unused and ignored** for `DatagramSend`
**QUIC_SEND_FLAG_CANCEL_ON_BLOCKED**<br>64 | Allows MsQuic to drop frames when all the data that could be sent has been flushed out, but there are still some frames remaining in the queue.
`ClientSendContext`
The app context pointer (possibly null) to be associated with the send.
# Return Value
Expand Down
1 change: 1 addition & 0 deletions docs/api/StreamSend.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ Value | Meaning
**QUIC_SEND_FLAG_DGRAM_PRIORITY**<br>8 | **Unused and ignored** for `StreamSend`
**QUIC_SEND_FLAG_DELAY_SEND**<br>16 | Provides a hint to MsQuic to indicate the data does not need to be sent immediately, likely because more is soon to follow.
**QUIC_SEND_FLAG_CANCEL_ON_LOSS**<br>32 | Informs MsQuic to irreversibly mark the associated stream to be canceled when packet loss has been detected on it. I.e., all sends on a given stream are subject to this behavior from the moment the flag has been supplied for the first time.
**QUIC_SEND_FLAG_CANCEL_ON_BLOCKED**<br>64 | **Unused and ignored** for `StreamSend` for now
`ClientSendContext`
Expand Down
49 changes: 48 additions & 1 deletion scripts/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,12 @@ fn main() {
let mut config = Config::new(".");
config
.define("QUIC_ENABLE_LOGGING", logging_enabled)
.define("QUIC_TLS", "openssl")
.define("QUIC_OUTPUT_DIR", quic_output_dir.to_str().unwrap());
if cfg!(feature = "schannel") {
config.define("QUIC_TLS", "schannel");
} else {
config.define("QUIC_TLS", "openssl");
}
if cfg!(feature = "static") {
config.define("QUIC_BUILD_SHARED", "off");
}
Expand Down Expand Up @@ -59,4 +63,47 @@ fn main() {
}
println!("cargo:rustc-link-lib=static=msquic");
}

#[cfg(all(feature = "overwrite", not(target_os = "macos")))]
overwrite_bindgen();
}

/// Read the c header and generate rust bindings.
/// TODO: macos currently uses linux bindings.
#[cfg(all(feature = "overwrite", not(target_os = "macos")))]
fn overwrite_bindgen() {
let manifest_dir = std::path::PathBuf::from(env::var("CARGO_MANIFEST_DIR").unwrap());
let root_dir = manifest_dir;
// include msquic headers
let inc_dir = root_dir.join("src").join("inc");

// The bindgen::Builder is the main entry point
// to bindgen, and lets you build up options for
// the resulting bindings.
let bindings = bindgen::Builder::default()
// The input header we would like to generate
// bindings for.
.header(root_dir.join("src/ffi/wrapper.hpp").to_str().unwrap())
.clang_arg(format!("-I{}", inc_dir.to_string_lossy()))
.allowlist_recursively(false)
.allowlist_item("QUIC.*|BOOLEAN|BYTE|HQUIC|HRESULT")
.blocklist_type("QUIC_ADDR")
// Tell cargo to invalidate the built crate whenever any of the
// included header files changed.
.parse_callbacks(Box::new(bindgen::CargoCallbacks::new()))
// Finish the builder and generate the bindings.
.generate()
// Unwrap the Result and panic on failure.
.expect("Unable to generate bindings");

// Write bindings to the sys mod.
let out_path = root_dir.join("src/ffi");
#[cfg(target_os = "windows")]
let binding_file = "win_bindings.rs";
#[cfg(target_os = "linux")]
let binding_file = "linux_bindings.rs";
// TODO: support macos.
bindings
.write_to_file(out_path.join(binding_file))
.expect("Couldn't write bindings!");
}
16 changes: 11 additions & 5 deletions src/bin/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ endif()

if(BUILD_SHARED_LIBS)
add_library(msquic SHARED ${SOURCES})
add_library(msquic::msquic ALIAS msquic)
target_include_directories(msquic PUBLIC $<INSTALL_INTERFACE:include>)
target_link_libraries(msquic PRIVATE core msquic_platform inc warnings logging base_link main_binary_link_args)
set_target_properties(msquic PROPERTIES OUTPUT_NAME ${QUIC_LIBRARY_NAME})
Expand Down Expand Up @@ -251,8 +252,6 @@ elseif (CX_PLATFORM STREQUAL "darwin")
PROPERTIES LINK_FLAGS "-exported_symbols_list \"${CMAKE_CURRENT_SOURCE_DIR}/darwin/exports.txt\"")
endif()

include(GNUInstallDirs)

file(GLOB PUBLIC_HEADERS "../inc/*.h" "../inc/*.hpp")

if(QUIC_TLS STREQUAL "openssl" OR QUIC_TLS STREQUAL "openssl3")
Expand All @@ -264,11 +263,18 @@ if(WIN32)
endif()

if(BUILD_SHARED_LIBS)
install(TARGETS msquic msquic_platform inc logging_inc warnings main_binary_link_args ${OTHER_TARGETS} EXPORT msquic DESTINATION lib)
install(TARGETS msquic msquic_platform inc logging_inc warnings main_binary_link_args ${OTHER_TARGETS}
EXPORT msquic
RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}"
LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}"
ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}"
)
else()
install(FILES ${QUIC_STATIC_LIBRARY} DESTINATION lib)
install(FILES "${QUIC_STATIC_LIBRARY}"
DESTINATION lib
)
endif()
install(FILES ${PUBLIC_HEADERS} DESTINATION include)
install(FILES ${PUBLIC_HEADERS} DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}")

configure_file(msquic-config.cmake.in ${CMAKE_BINARY_DIR}/msquic-config.cmake @ONLY)

Expand Down
12 changes: 7 additions & 5 deletions src/bin/msquic-config.cmake.in
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@ include(CMakeFindDependencyMacro)

include("${CMAKE_CURRENT_LIST_DIR}/msquic.cmake")

foreach(_t IN ITEMS msquic msquic_platform)
if(TARGET msquic::${_t} AND NOT TARGET ${_t})
add_library(${_t} ALIAS msquic::${_t})
endif()
endforeach()
# Legacy names
if(NOT TARGET msquic)
add_library(msquic ALIAS msquic::msquic)
endif()
if(NOT TARGET msquic_platform)
add_library(msquic_platform ALIAS msquic::platform)
endif()
83 changes: 73 additions & 10 deletions src/core/ack_tracker.c
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,73 @@ QuicAckTrackerAddPacketNumber(
!RangeUpdated;
}

//
// This function implements the logic defined in Section 6.2 [draft-ietf-quic-frequence-10]
// to determine if the reordering threshold has been hit.
//
BOOLEAN
QuicAckTrackerDidHitReorderingThreshold(
_In_ QUIC_ACK_TRACKER* Tracker,
_In_ uint8_t ReorderingThreshold
)
{
if (ReorderingThreshold == 0 || QuicRangeSize(&Tracker->PacketNumbersToAck) < 2) {
return FALSE;
}

const uint64_t LargestUnacked = QuicRangeGetMax(&Tracker->PacketNumbersToAck);
const uint64_t SmallestTracked = QuicRangeGet(&Tracker->PacketNumbersToAck, 0)->Low;

//
// Largest Reported is equal to the largest packet number acknowledged minus the
// Reordering Threshold. If the difference between the largest packet number
// acknowledged and the Reordering Threshold is smaller than the smallest packet
// in the ack tracker, then the largest reported is the smallest packet in the ack
// tracker.
//

const uint64_t LargestReported =
(Tracker->LargestPacketNumberAcknowledged >= SmallestTracked + ReorderingThreshold) ?
Tracker->LargestPacketNumberAcknowledged - ReorderingThreshold + 1 :
SmallestTracked;

//
// Loop through all previous ACK ranges (before last) to find the smallest missing
// packet number that is after the largest reported packet number. If the difference
// between that missing number and the largest unack'ed number is more than the
// reordering threshold, then the condition has been met to send an immediate
// acknowledgement.
//

for (uint32_t Index = QuicRangeSize(&Tracker->PacketNumbersToAck) - 1; Index > 0; --Index) {
const uint64_t RangeStart = QuicRangeGet(&Tracker->PacketNumbersToAck, Index)->Low;

if (LargestReported >= RangeStart) {
//
// Since we are only looking for packets more than LargestReported, we return
// false here.
//
return FALSE;
}

//
// Check if largest reported packet is missing. In that case, the smallest missing
// packet becomes the largest reported packet.
//

uint64_t PreviousSmallestMissing = QuicRangeGetHigh(QuicRangeGet(&Tracker->PacketNumbersToAck, Index - 1)) + 1;
if (LargestReported > PreviousSmallestMissing) {
PreviousSmallestMissing = LargestReported;
}

if (LargestUnacked - PreviousSmallestMissing >= ReorderingThreshold) {
return TRUE;
}
}

return FALSE;
}

_IRQL_requires_max_(DISPATCH_LEVEL)
void
QuicAckTrackerAckPacket(
Expand Down Expand Up @@ -182,10 +249,10 @@ QuicAckTrackerAckPacket(
// 1. The packet included an IMMEDIATE_ACK frame.
// 2. ACK delay is disabled (MaxAckDelayMs == 0).
// 3. We have received 'PacketTolerance' ACK eliciting packets.
// 4. We received an ACK eliciting packet that doesn't directly follow the
// previously received packet number. So we assume there might have
// been loss and should indicate this info to the peer. This logic is
// disabled if 'IgnoreReordering' is TRUE.
// 4. We have received an ACK eliciting packet that is out of order and the
// gap between the smallest Unreported Missing packet and the Largest
// Unacked is greater than or equal to the Reordering Threshold value. This logic is
// disabled if the Reordering Threshold is 0.
// 5. The delayed ACK timer fires after the configured time.
//
// If we don't queue an immediate ACK and this is the first ACK eliciting
Expand All @@ -195,12 +262,8 @@ QuicAckTrackerAckPacket(
if (AckType == QUIC_ACK_TYPE_ACK_IMMEDIATE ||
Connection->Settings.MaxAckDelayMs == 0 ||
(Tracker->AckElicitingPacketsToAcknowledge >= (uint16_t)Connection->PacketTolerance) ||
(!Connection->State.IgnoreReordering &&
(NewLargestPacketNumber &&
QuicRangeSize(&Tracker->PacketNumbersToAck) > 1 && // There are more than two ranges, i.e. a gap somewhere.
QuicRangeGet(
&Tracker->PacketNumbersToAck,
QuicRangeSize(&Tracker->PacketNumbersToAck) - 1)->Count == 1))) { // The gap is right before the last packet number.
(NewLargestPacketNumber &&
QuicAckTrackerDidHitReorderingThreshold(Tracker, Connection->ReorderingThreshold))) {
//
// Send the ACK immediately.
//
Expand Down
14 changes: 14 additions & 0 deletions src/core/ack_tracker.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@
--*/

#if defined(__cplusplus)
extern "C" {
#endif

typedef struct QUIC_ACK_TRACKER {

//
Expand Down Expand Up @@ -91,6 +95,12 @@ QuicAckTrackerAddPacketNumber(
_In_ uint64_t PacketNumber
);

BOOLEAN
QuicAckTrackerDidHitReorderingThreshold(
_In_ QUIC_ACK_TRACKER* Tracker,
_In_ uint8_t ReorderingThreshold
);

typedef enum QUIC_ACK_TYPE {
QUIC_ACK_TYPE_NON_ACK_ELICITING,
QUIC_ACK_TYPE_ACK_ELICITING,
Expand Down Expand Up @@ -146,3 +156,7 @@ QuicAckTrackerHasPacketsToAck(
!Tracker->AlreadyWrittenAckFrame &&
QuicRangeSize(&Tracker->PacketNumbersToAck) != 0;
}

#if defined(__cplusplus)
}
#endif
Loading

0 comments on commit aaf479d

Please sign in to comment.