@@ -110,6 +110,35 @@ impl Kcp {
110110 self . output_cb = Some ( output_cb) ;
111111 }
112112
113+ /// Installs a KCP 2.0 congestion control implementation.
114+ ///
115+ /// # Safety
116+ ///
117+ /// KCP stores the provided operations pointer and calls it from C. The caller must ensure the
118+ /// `IKCPOPS` value outlives every `Kcp` using it, and that its callbacks preserve KCP's aliasing
119+ /// and thread-safety requirements.
120+ pub unsafe fn set_congestion_control (
121+ & mut self ,
122+ ops : Option < & ' static IKCPOPS > ,
123+ ) -> Result < ( ) , Error > {
124+ let ops = ops. map_or ( std:: ptr:: null ( ) , |ops| ops as * const IKCPOPS ) ;
125+ let ret = unsafe { ikcp_setcc ( self . kcp , ops) } ;
126+ if ret < 0 {
127+ Err ( anyhow:: anyhow!( "setcc failed, return: {}" , ret) . into ( ) )
128+ } else {
129+ Ok ( ( ) )
130+ }
131+ }
132+
133+ pub fn reset_congestion_control ( & mut self ) -> Result < ( ) , Error > {
134+ let ret = unsafe { ikcp_setcc ( self . kcp , std:: ptr:: null ( ) ) } ;
135+ if ret < 0 {
136+ Err ( anyhow:: anyhow!( "reset setcc failed, return: {}" , ret) . into ( ) )
137+ } else {
138+ Ok ( ( ) )
139+ }
140+ }
141+
113142 pub fn handle_input ( & mut self , data : & [ u8 ] ) -> Result < ( ) , Error > {
114143 let ret = unsafe { ikcp_input ( self . kcp , data. as_ptr ( ) as * const _ , data. len ( ) as _ ) } ;
115144 if ret < 0 {
@@ -220,3 +249,15 @@ impl Drop for Kcp {
220249 }
221250 }
222251}
252+
253+ #[ cfg( test) ]
254+ mod tests {
255+ use super :: * ;
256+
257+ #[ test]
258+ fn reset_congestion_control_uses_builtin_algorithm ( ) {
259+ let mut kcp = Kcp :: new ( KcpConfig :: new ( 1 ) ) . unwrap ( ) ;
260+
261+ kcp. reset_congestion_control ( ) . unwrap ( ) ;
262+ }
263+ }
0 commit comments