
    i|E                        d dl mZ d dlZd dlZd dlmZmZmZ ddlm	Z	m
Z
mZ ddlmZ ddlmZmZ d	Zd
ZdZdZdZdZdZdZdZdZddZ G d d          Z G d d          Z G d d          ZdS )    )annotationsN)AnyCallableIterable   )QuicPacketPacerQuicRttMonitorRangeSet   )QuicLoggerTrace)QuicDeliveryStateQuicSentPacket   MbP?g      ?gư>g      ?
   g?gffffff?g       @xfloatreturnc                &    | dk     r|  dz   S | dz  S )Nr   gUUUUUU? r   s    N/root/projects/butler/venv/lib64/python3.11/site-packages/qh3/quic/recovery.py_cubic_rootr      s&    1uu")$%%    c                      e Zd ZddZdS )QuicPacketSpacer   Nonec                    d | _         t                      | _        d| _        d| _        d| _        d | _        d| _        d| _        d | _	        i | _
        d S )NFr   )ack_atr
   	ack_queue	discardedexpected_packet_numberlargest_received_packetlargest_received_timeack_eliciting_in_flightlargest_acked_packet	loss_timesent_packetsselfs    r   __init__zQuicPacketSpace.__init__#   sZ    $(!&'#')$37" ()$$%!'+79r   Nr   r   )__name__
__module____qualname__r,   r   r   r   r   r   "   s(        : : : : : :r   r   c                  Z    e Zd ZdZddZdd	Zdd
ZddZddZddZ	ddZ
ddZddZdS ) QuicCongestionControlz.
    Cubic congestion control (RFC 9438).
    max_datagram_sizeintr   r   c                
   || _         t                      | _        d| _        d| _        d| _        d| _        |t          z  | _        d | _	        d| _
        d| _        d| _        | j        | _        d| _        d| _        d| _        d S )N        g{Gz?r   TF)_max_datagram_sizer	   _rtt_monitor_congestion_recovery_start_time_rtt	_last_ackbytes_in_flightK_INITIAL_WINDOWcongestion_windowssthresh_first_slow_start_starting_congestion_avoidance_K_W_max_W_est_cwnd_epoch_t_epoch)r+   r3   s     r   r,   zQuicCongestionControl.__init__7   s    "3*,,/2,	 !25E!E$( "&.3+1 !"r   tr   c                ~    | j         | j        z  }t          || j        z
  dz  z  |z   }t	          || j        z            S )Nr   )rC   r7   	K_CUBIC_CrB   r4   )r+   rG   W_max_segmentstarget_segmentss       r   _W_cubiczQuicCongestionControl._W_cubicK   sA    t'>>#q47{q&88>I?T%<<===r   c                    | j         t          z  | _        d | _        d| _        d| _        d| _        | j        | _        d| _        d| _	        d| _
        d S )NTFr6   r   )r7   r=   r>   r?   r@   rA   rB   rC   rD   rE   rF   r*   s    r   _resetzQuicCongestionControl._resetP   sU    !%!8;K!K!%.3+,r   nowc                    || _         | j        | _        | j        | _        | j        | j        z  }| j        | j        z  }t          ||z
  t          z            | _        d S N)	rF   r>   rE   rD   rC   r7   r   rI   rB   )r+   rO   	W_max_segcwnd_segs       r   _start_epochz"QuicCongestionControl._start_epoch[   sZ    1&K$"99	#d&==y83y@AAr   packetr   c                   | xj         |j        z  c_         |j        | _        | j        | j        | j        k     r| xj        |j        z  c_        d S | j        r4| j        s-d| _        | j        | _        | 	                    |j                   | j        r(d| _        d| _        | 	                    |j                   t          | j        | j        |j        | j        z  z  z             | _        |j        | j        z
  }|                     || j        z             }|| j        k     r| j        }n5|t          d| j        z            k    rt          d| j        z            }n|}|                     |          | j        k     r| j        | _        d S t          | j        || j        z
  | j        | j        z  z  z             | _        d S )NFg      ?)r<   
sent_bytes	sent_timer;   r?   r>   r@   rA   rC   rT   r4   rD   r7   rF   rL   r:   )r+   rU   rG   W_cubictargets        r   on_packet_ackedz%QuicCongestionControl.on_packet_ackedc   s    11)= D$:T]$J$J""f&77"""" % 4d.Q 4).&"4!!&"23332 46;3).&!!&"2333 )V->AW-WXY DK
  4=0AmmA	M22G ////3sT%;;<<<<S4#99:: }}Q$+--)-&&& *-* 66.1GGII* *&&&r   c                    | xj         |j        z  c_         | j        dk    r0|j        | j        z
  }|t          k    r|                                  d S d S d S )Nr6   )r<   rW   r;   rX   K_CUBIC_MAX_IDLE_TIMErN   )r+   rU   elapsed_idles      r   on_packet_sentz$QuicCongestionControl.on_packet_sent   s`     11>C!+dn<L444  44r   packetsIterable[QuicSentPacket]c                :    |D ]}| xj         |j        z  c_         d S rQ   )r<   rW   )r+   r`   rU   s      r   on_packets_expiredz(QuicCongestionControl.on_packets_expired   s5     	6 	6F  F$55   	6 	6r   c                   d}|D ]}| xj         |j        z  c_         |j        }|| j        k    r|| _        | j        | j        k     r(t          | j        dt          z   z  dz            | _        n| j        | _        t          t          | j        t          z            | j	        t          z            | _        | j        | _        d| _        d S d S )Nr6   r   r   T)r<   rW   rX   r9   r>   rC   r4   K_CUBIC_LOSS_REDUCTION_FACTORmaxr7   K_MINIMUM_WINDOWr?   rA   )r+   r`   rO   lost_largest_timerU   s        r   on_packets_lostz%QuicCongestionControl.on_packets_lost   s     	1 	1F  F$55   & 0 tCCC36D0 %33!*a2O.OPSTT  #4%(D*-JJKK'*::& &D" !2DM26D///! DCr   
latest_rttc                x    || _         | j        )| j                            ||          r| j        | _        d S d S d S rQ   )r:   r?   r8   is_rtt_increasingr>   )r+   rj   rO   s      r   on_rtt_measurementz(QuicCongestionControl.on_rtt_measurement   sL    	= T%6%H%H&
 &
  !2DMMM !   r   N)r3   r4   r   r   )rG   r   r   r4   r-   rO   r   r   r   )rU   r   r   r   )r`   ra   r   r   )r`   ra   rO   r   r   r   )rj   r   rO   r   r   r   )r.   r/   r0   __doc__r,   rL   rN   rT   r[   r_   rc   ri   rm   r   r   r   r2   r2   2   s         # # # #(> > > >
	 	 	 	B B B B/ / / /b   6 6 6 67 7 7 743 3 3 3 3 3r   r2   c                      e Zd ZdZ	 	 	 d,d-dZed.d            Zed.d            Zd/dZd0dZ	d0dZ
d1dZd2dZd3d"Zd2d#Zd4d$Zd5d&Zd6d7d(Zd8d+ZdS )9QuicPacketRecoveryz0
    Packet loss and congestion controller.
       Ninitial_rttr   !peer_completed_address_validationbool
send_probeCallable[[], None]r3   r4   loggerlogging.LoggerAdapter | Nonequic_loggerQuicLoggerTrace | Noner   r   c                .   d| _         || _        g | _        || _        || _        || _        d| _        || _        d| _        d| _	        t          j        | _        d| _        d| _        d| _        t!          |          | _        t%          |          | _        d S )Ng?r   Fr6   )max_ack_delayrt   spaces_logger_quic_logger_send_probe
_pto_count_rtt_initial_rtt_initialized_rtt_latestmathinf_rtt_min_rtt_smoothed_rtt_variance'_time_of_last_sent_ack_eliciting_packetr2   _ccr   _pacer)r+   rs   rt   rv   r3   rx   rz   s          r   r,   zQuicPacketRecovery.__init__   s     #1R.-/ '% ' %  7:4 )):;;%&788r   c                    | j         j        S rQ   )r   r<   r*   s    r   r<   z"QuicPacketRecovery.bytes_in_flight   s    x''r   c                    | j         j        S rQ   )r   r>   r*   s    r   r>   z$QuicPacketRecovery.congestion_window   s    x))r   spacer   c                @   || j         v sJ | j                            t          d |j                                                             |j                                         d |_        d|_        d |_	        d| _
        | j        |                                  d S d S )Nc                    | j         S rQ   )	in_flightr   s    r   <lambda>z2QuicPacketRecovery.discard_space.<locals>.<lambda>   s    Q[ r   r   )r~   r   rc   filterr)   valuesclearr    r&   r(   r   r   _log_metrics_updated)r+   r   s     r   discard_spacez QuicPacketRecovery.discard_space   s    ######((%*<*C*C*E*EFF	
 	
 	
 	  """()% (%%''''' )(r   c                    |                                  }||j        S | j        r"t          d | j        D                       dk    r)|                                 d| j        z  z  }| j        |z   S d S )Nc              3  $   K   | ]}|j         V  d S rQ   )r&   ).0r   s     r   	<genexpr>z=QuicPacketRecovery.get_loss_detection_time.<locals>.<genexpr>  s%      JJU50JJJJJJr   r   r   )_get_loss_spacer(   rt   sumr~   get_probe_timeoutr   r   )r+   
loss_spacetimeouts      r   get_loss_detection_timez*QuicPacketRecovery.get_loss_detection_time  s    ))++
!'' 6	JJJdkJJJJJQNN,,..!T_2DEG?'IItr   c                ~    | j         s
d| j        z  S | j        t          d| j        z  t
                    z   | j        z   S )Nr      )r   r   r   rf   r   K_GRANULARITYr}   r*   s    r   r   z$QuicPacketRecovery.get_probe_timeout  sK    $ 	)t(((!d((-889 !	
r   ack_rangesetr
   	ack_delayrO   c                   d}|                                 d         dz
  }d}d}||j        k    r||_        t          |j                                                  D ]}	|	|k    r n|	|v r}|j                            |	          }
|
j        rd}|xj        dz  c_        |
j        r| j	        
                    |
           |	}|
j        }|
j        D ]\  }} |t          j        g|R   |dS ||k    r$|r!||z
  }d}t          || j                  }t#          |d          | _        | j        | j        k     r| j        | _        | j        | j        |z   k    r| xj        |z  c_        | j        sd| _        |dz  | _        || _        nId| j        z  dt/          | j        | j        z
            z  z   | _        d	| j        z  d
| j        z  z   | _        | j	                            ||           | j                            | j	        j        | j                   nd}|                     ||           d| _        | j        |                     |           dS dS )zH
        Update metrics as the result of an ACK being received.
        Fr   NTr   r   g      ?g      ?g      ?g      ?rO   r>   smoothed_rttr   )log_rtt) boundsr'   sortedr)   keyspopis_ack_elicitingr&   r   r   r[   rX   delivery_handlersr   ACKEDminr}   rf   r   r   r   r   r   absrm   r   update_rater>   _detect_lossr   r   r   )r+   r   r   r   rO   r   largest_ackedlargest_newly_ackedlargest_sent_timepacket_numberrU   handlerargsrj   r   s                  r   on_ack_receivedz"QuicPacketRecovery.on_ack_received  s    !$++--a014" 5555)6E&#E$6$;$;$=$=>> 	< 	<M},,,,+//>>* 7'+$11Q611# 5H,,V444&3#$*$4! &,%= < <MGTG-3;d;;;;; &F///4D/00JG It'9::I  #:u55D$-// $ 0$-)";;;  I-  ( 
(,%%/!^"%/""%*T-?%?%#MD$44K K C &" D..9I1II "
 H''
'<<<K##"&("<!/ $     G%S))) (%%g%66666 )(r   c                    |                                  }||                     ||           d S | xj        dz  c_        |                     |           d S )Nr   r   )r   r   r   reschedule_data)r+   rO   r   s      r   on_loss_detection_timeoutz,QuicPacketRecovery.on_loss_detection_timeouto  se    ))++
!jc22222OOq OO  S )))))r   rU   r   c                    ||j         |j        <   |j        r|xj        dz  c_        |j        rJ|j        r|j        | _        | j                            |           | j	        | 
                                 d S d S d S )Nr   )r)   r   r   r&   r   rX   r   r   r_   r   r   )r+   rU   r   s      r   r_   z!QuicPacketRecovery.on_packet_sentw  s    396/0" 	/))Q.)) 	,& P?E?O< H##F+++ ,))+++++	, 	, -,r   c                .   d}| j         D ]S}t          t          d |j                                                            }|r|                     |||           d}T|r!| j        | j                            d           |                                  dS )z8
        Schedule some data for retransmission.
        Fc                    | j         S rQ   )is_crypto_packet)is    r   r   z4QuicPacketRecovery.reschedule_data.<locals>.<lambda>  s	    !3 r   r   rO   TNz(Scheduled CRYPTO data for retransmission)	r~   tupler   r)   r   _on_packets_lostr   debugr   )r+   rO   crypto_scheduledr   r`   s        r   r   z"QuicPacketRecovery.reschedule_data  s    
 ![ 	( 	(E33U5G5N5N5P5PQQ G  (%%gU%DDD#'  	K 8LIJJJ 	r   c                   t           | j        rt          | j        | j                  n| j        z  }|j        t          z
  }||z
  }g }d|_        |j	        
                                D ]\\  }}||j        k    r nK||k    s|j        |k    r|                    |           9|j        |z   }	|j        |j        |	k    r|	|_        ]|                     |||           dS )zD
        Check whether any packets should be declared lost.
        Nr   )K_TIME_THRESHOLDr   rf   r   r   r   r'   K_PACKET_THRESHOLDr(   r)   itemsrX   appendr   )
r+   r   rO   
loss_delaypacket_thresholdtime_thresholdlost_packetsr   rU   packet_loss_times
             r   r   zQuicPacketRecovery._detect_loss  s    &$#C $"4555"


 !58JJz)%*%7%=%=%?%? 		7 		7!M6u999 000F4D4V4V##F++++#)#3j#@ ?*eo@P.P.P&6EOl%SAAAAAr   QuicPacketSpace | Nonec                T    d }| j         D ]}|j        ||j        |j        k     r|}|S rQ   )r~   r(   )r+   r   r   s      r   r   z"QuicPacketRecovery._get_loss_space  sA    
[ 	# 	#E*"eo
8L&L&L"
r   Fc                   | j         j        | j         j        d}| j         j        | j         j        |d<   |r|                    | j                            | j                  | j                            | j                  | j                            | j	                  | j                            | j
                  d           | j                            dd|           d S )N)r<   cwndr?   )rj   min_rttr   rtt_variancerecoverymetrics_updatedcategoryeventdata)r   r<   r>   r?   updater   encode_timer   r   r   r   	log_event)r+   r   r   s      r   r   z'QuicPacketRecovery._log_metrics_updated  s    #x7H. 
  
 8(#x0D 	KK"&"3"?"?@P"Q"Q#0<<T]KK$($5$A$A$BT$U$U$($5$A$A$BT$U$U	    	##'8t 	$ 	
 	
 	
 	
 	
r   r`   ra   c                ^   g }|D ]}|j         |j        = |j        r|                    |           |j        r|xj        dz  c_        | j        V| j                            dd| j                            |j                  |j        d           | 	                                 |j
        D ]\  }} |t          j        g|R   |rd| j                            ||           | j                            | j        j        | j                   | j        | 	                                 d S d S d S )Nr   r   packet_lost)typer   r   r   r   )r)   r   r   r   r   r&   r   r   packet_typer   r   r   LOSTr   ri   r   r   r>   r   )r+   r`   r   rO   lost_packets_ccrU   r   r   s           r   r   z#QuicPacketRecovery._on_packets_lost  s     	7 	7F"6#78 /&&v...& 3--2-- ,!++'' $ 1 = =f>P Q Q)/)=  ,    ))+++ "(!9 7 7).6666667  	,H$$_#$>>>K##"&("<!/ $     ,))+++++	, 	, -,r   )rr   NN)rs   r   rt   ru   rv   rw   r3   r4   rx   ry   rz   r{   r   r   )r   r4   )r   r   r   r   )r   r   )
r   r   r   r
   r   r   rO   r   r   r   rn   )rU   r   r   r   r   r   )r   r   rO   r   r   r   )r   r   )Fr-   )r`   ra   r   r   rO   r   r   r   )r.   r/   r0   ro   r,   propertyr<   r>   r   r   r   r   r   r_   r   r   r   r   r   r   r   r   rq   rq      sm         "&/3.29 9 9 9 9@ ( ( ( X( * * * X*( ( ( ($    
 
 
 
R7 R7 R7 R7h* * * *, , , ,   &B B B B6   
 
 
 
 
,$, $, $, $, $, $,r   rq   )r   r   r   r   )
__future__r   loggingr   typingr   r   r   _hazmatr   r	   r
   rx   r   packet_builderr   r   r   r   r   K_MICRO_SECONDK_SECONDr=   rg   rI   re   r]   r   r   r2   rq   r   r   r   <module>r      sv   " " " " " "   * * * * * * * * * * ? ? ? ? ? ? ? ? ? ? # # # # # # = = = = = = = =       	 #     : : : : : : : : N3 N3 N3 N3 N3 N3 N3 N3bt, t, t, t, t, t, t, t, t, t,r   