@@ -3,10 +3,7 @@ use ironrdp_core::{Decode as _, MonotonicInstant, ReadCursor, WriteBuf, decode};
33use ironrdp_dvc:: { DrdynvcClient , DvcClientProcessor , DynamicChannelMut , DynamicChannelRef } ;
44use ironrdp_pdu:: gcc:: { ChannelName , Monitor } ;
55use ironrdp_pdu:: mcs:: { DisconnectProviderUltimatum , DisconnectReason , McsMessage , SendDataIndicationCtx } ;
6- use ironrdp_pdu:: rdp:: autodetect:: {
7- AutoDetectReqPdu , AutoDetectRequest , AutoDetectResponse , AutoDetectRspPdu , BW_RESULTS_CONNECT_TIME ,
8- BW_RESULTS_CONTINUOUS , BW_START_CONNECT_TIME , BW_START_RELIABLE_UDP , BW_STOP_CONNECT_TIME , BW_STOP_RELIABLE_UDP ,
9- } ;
6+ use ironrdp_pdu:: rdp:: autodetect:: { AutoDetectReqPdu , AutoDetectRequest , AutoDetectRspPdu } ;
107use ironrdp_pdu:: rdp:: client_info:: CompressionType ;
118use ironrdp_pdu:: rdp:: headers:: {
129 BasicSecurityHeader , BasicSecurityHeaderFlags , CompressionFlags , IoChannelPdu , ShareDataCtx , ShareDataPdu ,
@@ -21,6 +18,7 @@ use ironrdp_svc::{
2118} ;
2219use tracing:: debug;
2320
21+ use crate :: autodetect:: AutoDetectResponder ;
2422use crate :: { SessionError , SessionErrorExt as _, SessionResult , reason_err} ;
2523
2624/// X224 Processor output
@@ -110,13 +108,7 @@ pub struct Processor {
110108 io_channel_id : u16 ,
111109 message_channel_id : Option < u16 > ,
112110 share_id : u32 ,
113- bandwidth : Option < BandwidthMeasurement > ,
114- }
115-
116- struct BandwidthMeasurement {
117- started_at : MonotonicInstant ,
118- bytes : u32 ,
119- continuous : bool ,
111+ auto_detect : AutoDetectResponder ,
120112}
121113
122114impl Processor {
@@ -133,7 +125,7 @@ impl Processor {
133125 io_channel_id,
134126 message_channel_id,
135127 share_id,
136- bandwidth : None ,
128+ auto_detect : AutoDetectResponder :: default ( ) ,
137129 }
138130 }
139131
@@ -477,11 +469,7 @@ impl Processor {
477469 /// Counts session bytes after transport/security headers while a continuous
478470 /// bandwidth window is open ([MS-RDPBCGR] 3.2.5.14).
479471 pub ( crate ) fn record_bandwidth_bytes ( & mut self , bytes : usize ) {
480- if let Some ( measurement) = self . bandwidth . as_mut ( ) . filter ( |measurement| measurement. continuous ) {
481- measurement. bytes = measurement
482- . bytes
483- . saturating_add ( u32:: try_from ( bytes) . unwrap_or ( u32:: MAX ) ) ;
484- }
472+ self . auto_detect . record_bytes ( bytes) ;
485473 }
486474
487475 /// Process a PDU received on the MCS message channel: auto-detect
@@ -539,76 +527,12 @@ impl Processor {
539527
540528 let req = decode :: < AutoDetectReqPdu > ( data_ctx. user_data ) . map_err ( SessionError :: decode) ?;
541529
542- let response = match req. request {
543- AutoDetectRequest :: RttRequest { sequence_number, .. } => {
544- AutoDetectResponse :: RttResponse { sequence_number }
545- }
546- AutoDetectRequest :: BandwidthMeasureStart { request_type, .. }
547- if matches ! ( request_type, BW_START_CONNECT_TIME | BW_START_RELIABLE_UDP ) =>
548- {
549- self . bandwidth = received_at. map ( |started_at| BandwidthMeasurement {
550- started_at,
551- bytes : 0 ,
552- continuous : request_type == BW_START_RELIABLE_UDP ,
553- } ) ;
554- return Ok ( Vec :: new ( ) ) ;
555- }
556- AutoDetectRequest :: BandwidthMeasurePayload { payload, .. } => {
557- if let Some ( measurement) = self . bandwidth . as_mut ( ) . filter ( |measurement| !measurement. continuous ) {
558- // [MS-RDPBCGR] 3.2.5.14 counts the eight-byte auto-detect
559- // header as well as payloadLength, but not the security header.
560- measurement. bytes = measurement
561- . bytes
562- . saturating_add ( u32:: try_from ( payload. len ( ) ) . unwrap_or ( u32:: MAX ) . saturating_add ( 8 ) ) ;
563- }
564- return Ok ( Vec :: new ( ) ) ;
565- }
566- AutoDetectRequest :: BandwidthMeasureStop {
567- sequence_number,
568- request_type,
569- payload,
570- } if matches ! ( request_type, BW_STOP_CONNECT_TIME | BW_STOP_RELIABLE_UDP ) => {
571- let continuous = request_type == BW_STOP_RELIABLE_UDP ;
572- let measurement = self
573- . bandwidth
574- . take ( )
575- . filter ( |measurement| measurement. continuous == continuous) ;
576- let stop_bytes = if continuous {
577- 0
578- } else {
579- u32:: try_from ( payload. as_ref ( ) . map_or ( 0 , Vec :: len) )
580- . unwrap_or ( u32:: MAX )
581- . saturating_add ( 8 )
582- } ;
583- let ( time_delta_ms, byte_count) = match ( measurement, received_at) {
584- ( Some ( measurement) , Some ( stopped_at) ) => (
585- u32:: try_from ( stopped_at. duration_since ( measurement. started_at ) . as_millis ( ) )
586- . unwrap_or ( u32:: MAX )
587- . max ( 1 ) ,
588- measurement. bytes . saturating_add ( stop_bytes) ,
589- ) ,
590- _ => ( 1 , stop_bytes) ,
591- } ;
592- AutoDetectResponse :: BandwidthMeasureResults {
593- sequence_number,
594- response_type : if continuous {
595- BW_RESULTS_CONTINUOUS
596- } else {
597- BW_RESULTS_CONNECT_TIME
598- } ,
599- time_delta_ms,
600- byte_count,
601- }
602- }
603- req @ AutoDetectRequest :: NetworkCharacteristicsResult { .. } => {
604- debug ! ( ?req, "Received network characteristics from server" ) ;
605- return Ok ( vec ! [ ProcessorOutput :: AutoDetect ( req) ] ) ;
606- }
607- req => {
608- // Lossy variants belong to a lossy tunnel, never this channel.
609- debug ! ( ?req, "Ignoring auto-detect request for another transport" ) ;
610- return Ok ( Vec :: new ( ) ) ;
611- }
530+ if let request @ AutoDetectRequest :: NetworkCharacteristicsResult { .. } = req. request {
531+ debug ! ( ?request, "Received network characteristics from server" ) ;
532+ return Ok ( vec ! [ ProcessorOutput :: AutoDetect ( request) ] ) ;
533+ }
534+ let Some ( response) = self . auto_detect . respond ( req. request , received_at) else {
535+ return Ok ( Vec :: new ( ) ) ;
612536 } ;
613537 debug ! ( ?response, "Responding to an auto-detect request" ) ;
614538 let mut frame = WriteBuf :: new ( ) ;
0 commit comments