diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index 5e3a263..51676af 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -129,6 +129,11 @@ jobs: - name: Test run: cargo test --target ${{ matrix.target }} --verbose ${{ matrix.profile == 'release' && '--release' || '' }} + - name: Install CMake 4 + uses: step-security/get-cmake@v4 + with: + cmakeVersion: "^4.0.0" + - name: Build KCP native test run: | cmake -S kcp -B kcp/build -DBUILD_TESTING=ON diff --git a/kcp b/kcp index f4f3a89..32da082 160000 --- a/kcp +++ b/kcp @@ -1 +1 @@ -Subproject commit f4f3a89cc632647dabdcb146932d2afd5591e62e +Subproject commit 32da082e529a26730aea3eb19922f80634ee6dea diff --git a/src/ffi_safe.rs b/src/ffi_safe.rs index a927bea..3cb4af1 100644 --- a/src/ffi_safe.rs +++ b/src/ffi_safe.rs @@ -110,6 +110,35 @@ impl Kcp { self.output_cb = Some(output_cb); } + /// Installs a KCP 2.0 congestion control implementation. + /// + /// # Safety + /// + /// KCP stores the provided operations pointer and calls it from C. The caller must ensure the + /// `IKCPOPS` value outlives every `Kcp` using it, and that its callbacks preserve KCP's aliasing + /// and thread-safety requirements. + pub unsafe fn set_congestion_control( + &mut self, + ops: Option<&'static IKCPOPS>, + ) -> Result<(), Error> { + let ops = ops.map_or(std::ptr::null(), |ops| ops as *const IKCPOPS); + let ret = unsafe { ikcp_setcc(self.kcp, ops) }; + if ret < 0 { + Err(anyhow::anyhow!("setcc failed, return: {}", ret).into()) + } else { + Ok(()) + } + } + + pub fn reset_congestion_control(&mut self) -> Result<(), Error> { + let ret = unsafe { ikcp_setcc(self.kcp, std::ptr::null()) }; + if ret < 0 { + Err(anyhow::anyhow!("reset setcc failed, return: {}", ret).into()) + } else { + Ok(()) + } + } + pub fn handle_input(&mut self, data: &[u8]) -> Result<(), Error> { let ret = unsafe { ikcp_input(self.kcp, data.as_ptr() as *const _, data.len() as _) }; if ret < 0 { @@ -220,3 +249,15 @@ impl Drop for Kcp { } } } + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn reset_congestion_control_uses_builtin_algorithm() { + let mut kcp = Kcp::new(KcpConfig::new(1)).unwrap(); + + kcp.reset_congestion_control().unwrap(); + } +} diff --git a/src/lib.rs b/src/lib.rs index 6cb89fb..9fc4e31 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,4 +1,4 @@ -mod ffi; +pub mod ffi; mod state; pub mod endpoint;