
    ({])                        d Z ddlZddlZ	 ddlmZmZ 	 ddl	m
Z
 ej                  eefZd Z e       Z eej$                  ej&                  ej(                  g      Z eed      rej/                  ej0                         dZeZg d	Zd
ZdZdZdZ G d de       Z! e!       Z" G d de       Z#ejH                  dfdZ%y# eef$ r ddlmZmZ Y w xY w# eef$ r	 ddl	m	Z
 Y w xY w)zN Python implementation of the Happy Eyeballs Algorithm described in RFC 6555.     N)DefaultSelectorEVENT_WRITE)perf_counter)timec                     t        t        dd      rWt        t        d      rGd } 	 t        j                  t        j                  t        j                        } | j                  d       yy# t        $ r | r| j                          Y yw xY w)Nhas_ipv6FAF_INET6)z::1r   T)getattrsockethasattrr	   SOCK_STREAMbind_SOCKET_ERRORSclose)_socks    )/usr/lib/python3/dist-packages/rfc6555.py_detect_ipv6r   %   sp    vz5)gfj.I	MM&//63E3EFEJJz"   		s   AA* *BBWSAWOULDBLOCKiX  )RFC6555_ENABLEDcreate_connectioncachez1.0.0zSeth Michael Larsonz sethmichaellarson@protonmail.comz
Apache-2.0c                       e Zd Zd Zd Zd Zy)_RFC6555CacheManagerc                 6    t         | _        d| _        i | _        y )NT)_DEFAULT_CACHE_DURATIONvalidity_durationenabledentriesselfs    r   __init__z_RFC6555CacheManager.__init__L   s    !8    c                     | j                   rMt               }|| j                  vs| j                  |   d   |kD  r||| j                  z   f| j                  |<   y y y )N   )r   r   r   r   )r    addressfamilycurrent_times       r   	add_entryz_RFC6555CacheManager.add_entryQ   s\    <<'>L dll*dll7.CA.F.U)/@V@V1V(WW% /V	 r"   c                     | j                   r|| j                  vry | j                  |   \  }}t               |kD  r| j                  |= y |S N)r   r   r   )r    r%   r&   expirys       r   	get_entryz_RFC6555CacheManager.get_entryY   sG    ||wdll:g.>F"W%r"   N)__name__
__module____qualname__r!   r(   r,    r"   r   r   r   K   s    
X	r"   r   c                   ~    e Zd Zej                  dfdZd Zd Zd Zd Z	d Z
d Zd	 Zd
 Zed        Zd Zd Zd Zy)_RFC6555ConnectionManagerNc                 v    || _         || _        || _        d | _        t	               | _        g | _        d | _        y r*   )r%   timeoutsource_address_errorr   	_selector_sockets_start_time)r    r%   r4   r5   s       r   r!   z"_RFC6555ConnectionManager.__init__i   s8    ,(*r"   c                 J   t               | _        | j                  \  }}t        j                  ||t        j
                  t        j                        }| j                  |      }t        |t              r|}n,t        j                  | j                  |j                         |S |st        j                  d      | j                  |      }|r,t        j                  | j                  |j                         |S | j                  r| j                  t        j                          )N!getaddrinfo returns an empty list)r   r9   r%   r   getaddrinfo	AF_UNSPECr   _connect_with_cached_family
isinstancelistr   r(   r&   error_attempt_connect_with_addr_infor6   r4   )r    hostport	addr_inforetsocks         r   r   z+_RFC6555ConnectionManager.create_connections   s    '>\\
d&&tT63C3CVEWEWX	..y9 c4 IOODLL#**5J ,,BCC33I>OODLL$++6K[[++..""r"   c                     d }	 |D ]1  \  }}}}}| j                  ||||       | j                  d      }|s1 n || j                  d      }| j                          |S # | j                          w xY w)NFT)_create_socket_wait_for_connection_remove_all_sockets)r    rE   rG   r&   socktypeproto_sockaddrs           r   rB   z9_RFC6555ConnectionManager._attempt_connect_with_addr_info   s    		'8A 4%H##FHeXF007	
 |006$$& $$&s   2A A A1c                     t         j                  | j                        }||S g }g }|D ]-  }|d   |k(  r|j                  |       |j                  |       / | j	                  |      }||S |S )Nr   )r   r,   r%   appendrB   )r    rE   r&   	is_family
not_familyvaluerG   s          r   r>   z5_RFC6555ConnectionManager._connect_with_cached_family   s    .>	
 	)EQx6!  '!!%(		) 33I>Kr"   c                 4   d }	 t        j                   |||      }| j                  t         j                  u r|j                         | _        | j                  r|j                  | j                         |j                  d       | j                  |j                  |            r<| j                  j                  |t               | j                  j                  |       y y # t        $ r-}|| _        |t         j#                  |       Y d }~y Y d }~y d }~ww xY wNg        )r   r4   _GLOBAL_DEFAULT_TIMEOUT
gettimeoutr5   r   
settimeout_is_acceptable_errno
connect_exr7   registerr   r8   rQ   r   r6   r2   _close_socket)r    r&   rL   rM   rO   rG   es          r   rI   z(_RFC6555ConnectionManager._create_socket   s    	>==59D ||v===#0""		$--. OOC (()BC''k:$$T* D  	>DK)77==  	>s   CC! !	D*DDc                    | j                          | j                  sy |r | j                  d }n!| j                         }n| j	                         }| j
                  j                  |      D ]w  \  }}|j                  }| j                  |      r$|j                  | j                         | j                  j                  |       | j
                  j                  |       |c S  y r*   )_remove_all_errored_socketsr8   r4   _get_remaining_time_get_select_timer7   selectfileobj_is_socket_erroredrY   remove
unregister)r    	last_waitselect_timeoutkeyrN   rG   s         r   rJ   z._RFC6555ConnectionManager._wait_for_connection   s    ((*
 }} ||#!%!%!9!9!;!224N nn++N; 	FC;;D**40 - $$T*))$/	 r"   c                 x    | j                   y t        | j                   t               | j                  z
  z
  d      S rV   )r4   maxr   r9   r   s    r   ra   z-_RFC6555ConnectionManager._get_remaining_time   s2    <<4<<<>D4D4D#DEsKKr"   c                 P    | j                   yt        d| j                               S )Ng?)r4   minra   r   s    r   rb   z*_RFC6555ConnectionManager._get_select_time   s%    <<300233r"   c                    g }| j                   D ]%  }| j                  |      s|j                  |       ' |D ]M  }| j                  j	                  |       | j                   j                  |       t        j                  |       O y r*   )r8   re   rQ   r7   rg   rf   r2   r]   )r    socksrG   s      r   r`   z5_RFC6555ConnectionManager._remove_all_errored_sockets   sw    MM 	#D&&t,T"	#  	:DNN%%d+MM  &%33D9	:r"   c                 D    	 | j                          y # t        $ r Y y w xY wr*   )r   r   )rG   s    r   r]   z'_RFC6555ConnectionManager._close_socket  s"    	JJL 		s    	c                 t    |dk(  s|t         v ryt        j                         | _        || j                  _        y)Nr   TF)_ASYNC_ERRNOSr   rA   r6   errno)r    rt   s     r   rZ   z._RFC6555ConnectionManager._is_acceptable_errno  s/    A:-/lln!r"   c                     |j                  t        j                  t        j                        }| j	                  |       S r*   )
getsockoptr   
SOL_SOCKETSO_ERRORrZ   )r    rG   rt   s      r   re   z,_RFC6555ConnectionManager._is_socket_errored  s0     1 16??C,,U333r"   c                     | j                   D ]2  }| j                  j                  |       t        j	                  |       4 g | _         y r*   )r8   r7   rg   r2   r]   )r    rG   s     r   rK   z-_RFC6555ConnectionManager._remove_all_sockets  s>    MM 	:DNN%%d+%33D9	: r"   )r-   r.   r/   r   rW   r!   r   rB   r>   rI   rJ   ra   rb   r`   staticmethodr]   rZ   re   rK   r0   r"   r   r2   r2   h   s`    (.(F(FW[  #8(>6#JL
4
:  4r"   r2   c                 *   t         r#t        rt        | ||      }|j                         S | \  }}d }t	        j
                  ||dt        j                        D ]n  }|\  }}	}
}}d }	 t	        j                  ||	|
      }|t        j                  ur|j                  |       |r|j                  |       |j                  |       |c S  ||t	        j                  d      # t        j                  $ r}|}||j                          Y d }~d }~ww xY w)Nr   r;   )r   	_HAS_IPV6r2   r   r   r<   r   rW   rY   r   connectrA   r   )r%   r4   r5   managerrC   rD   errresafrL   rM   	canonnamesarG   rN   s                  r   r   r     s   9+GWnM((** 
d%%dD!V5G5GH 	!C14.B%BD!}}R59&"@"@@OOG,!IIn-R 	!" ?I,,BCC << !#JJL!s   %AC!!D4DD)&__doc__rt   r   	selectorsr   r   ImportErrorAttributeError
selectors2r   r   rA   OSErrorIOErrorr   r   r|   setEINPROGRESSEAGAINEWOULDBLOCKrs   r   addr   r   r   __all____version__
__author__	__email____license__objectr   r   r2   rW   r   r0   r"   r   <module>r      s!   T   87
*! ,,1
 N	 U&&\\&&( ) 5/"e))*!   "
.	6 4 	s sl (.'E'EVZ  DS 	^$ 8778 	^$ *)*s"   B? C ?CCC$#C$