o
    pjì  ã                   @   sØ   d Z ddlZddlZddlmZmZmZmZmZ ddl	m
Z
 ddlmZmZ ddlmZ ddlmZ dd	lmZmZ dd
lmZmZmZmZ G dd„ deƒZG dd„ deƒZdZdZdZdZe
ej ƒG dd„ dƒƒZ!dS )zD
IProxyParser implementation for version two of the PROXY protocol.
é    N)ÚCallableÚLiteralÚTupleÚTypeÚUnion)Úimplementer)ÚValueConstantÚValues)Úaddress)Úcompaté   )Ú_infoÚ_interfaces)ÚInvalidNetworkProtocolÚInvalidProxyHeaderÚMissingAddressDataÚconvertErrorc                   @   s0   e Zd ZdZedƒZedƒZedƒZedƒZdS )Ú	NetFamilyz(
    Values for the 'family' field.
    r   é   é    é0   N)	Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   ÚUNSPECÚINETÚINET6ÚUNIX© r   r   úE/usr/lib/python3/dist-packages/twisted/protocols/haproxy/_v2parser.pyr      s    r   c                   @   s(   e Zd ZdZedƒZedƒZedƒZdS )ÚNetProtocolz&
    Values for 'protocol' field.
    r   r   é   N)r   r   r   r   r   r   ÚSTREAMÚDGRAMr   r   r   r    r!   (   s
    r!   éð   é   ÚLOCALÚPROXYc                   @   s¬   e Zd ZdZdZdgZeedœZdddddddœZ	ddd„Z
ded	eeejef ed f fdd„Zeded	efdd„ƒZeded	efdd„ƒZeded	ejfdd„ƒZd
S )ÚV2Parserzn
    PROXY protocol version two header parser.

    Version two of the PROXY protocol is a binary format.
    s   

 
QUIT
r   )r   r   z!4s4s2Hz	!16s16s2Hz	!108s108s)é   é   é!   é"   é1   é2   ÚreturnNc                 C   s
   d| _ d S )Nó    )Úbuffer)Úselfr   r   r    Ú__init__O   s   
zV2Parser.__init__Údata©NNc                 C   sˆ   |  j |7  _ t| j ƒdk rtƒ ‚t d| j dd… ¡d d }t| j ƒ|k r)dS | j d|… | j |d… }}d| _ |  |¡}||fS )aë  
        Consume a chunk of data and attempt to parse it.

        @param data: A bytestring.
        @type data: bytes

        @return: A two-tuple containing, in order, a L{_interfaces.IProxyInfo}
            and any bytes fed to the parser that followed the end of the
            header.  Both of these values are None until a complete header is
            parsed.

        @raises InvalidProxyHeader: If the bytes fed to the parser create an
            invalid PROXY header.
        r   z!Hé   r   r6   Nr1   )r2   Úlenr   ÚstructÚunpackÚparse)r3   r5   ÚsizeÚheaderÚ	remainingÚinfor   r   r    ÚfeedR   s   
zV2Parser.feedÚ
bytestringc                 C   s   d  dd„ t | ¡D ƒ¡S )a7  
        Convert packed 32-bit IPv4 address bytes into a dotted-quad ASCII bytes
        representation of that address.

        @param bytestring: 4 octets representing an IPv4 address.
        @type bytestring: L{bytes}

        @return: a dotted-quad notation IPv4 address.
        @rtype: L{bytes}
        ó   .c                 s   s$   � | ]}d t |ƒf  d¡V  qdS )z%iÚasciiN)ÚordÚencode©Ú.0Úbr   r   r    Ú	<genexpr>|   s   € 
ÿz(V2Parser._bytesToIPv4.<locals>.<genexpr>)Újoinr   Ú	iterbytes©rA   r   r   r    Ú_bytesToIPv4p   s   
ÿzV2Parser._bytesToIPv4c                    s*   t  | ¡‰ d ‡ fdd„tdddƒD ƒ¡S )a=  
        Convert packed 128-bit IPv6 address bytes into a colon-separated ASCII
        bytes representation of that address.

        @param bytestring: 16 octets representing an IPv6 address.
        @type bytestring: L{bytes}

        @return: a dotted-quad notation IPv6 address.
        @rtype: L{bytes}
        ó   :c                 3   s0   � | ]}t ˆ ||d  … dƒd› d¡V  qdS )é   r   ÚxrC   N)ÚintrE   rF   ©Ú	hexStringr   r    rI   �   s
   € ÿ
ÿz(V2Parser._bytesToIPv6.<locals>.<genexpr>r   r   rO   )ÚbinasciiÚb2a_hexrJ   ÚrangerL   r   rR   r    Ú_bytesToIPv6€   s   

þzV2Parser._bytesToIPv6Úlinec              	   C   sX  |dd… }d}t ttƒ� t|dd… ƒ}t|dd… ƒ}W d  ƒ n1 s(w   Y  || jkr5tƒ ‚|t@ |t@ }}|| jvsH|| jvrKtƒ ‚| j| t	krYt
 |dd¡S |t@ |t@ }}	t ttƒ� t |¡}t |	¡}	W d  ƒ n1 s|w   Y  |tju s‹|	tju r’t
 |dd¡S | j| }
|ddt |
¡ … }|tju rØt tjtƒ� t |
|¡\}}W d  ƒ n1 sÀw   Y  t
 |t | d¡¡t | d¡¡¡S d}|	tju rád}tj}| j}|tju ròtj }| j!}t tjtƒ� t |
|¡}|\}}}}W d  ƒ n	1 �sw   Y  t
 |||||ƒ "¡ |ƒ||||ƒ "¡ |ƒ¡S )	a‘  
        Parse a bytestring as a full PROXY protocol header.

        @param line: A bytestring that represents a valid HAProxy PROXY
            protocol version 2 header.
        @type line: bytes

        @return: A L{_interfaces.IProxyInfo} containing the
            parsed data.

        @raises InvalidProxyHeader: If the bytestring does not represent a
            valid PROXY header.
        Né   é   r7   r   ó    ÚTCPÚUDP)#r   Ú
IndexErrorr   rD   ÚPREFIXÚ_HIGHÚ_LOWÚVERSIONSÚCOMMANDSÚ_LOCALCOMMANDr   Ú	ProxyInfoÚ
ValueErrorr   r   ÚlookupByValuer!   r   ÚADDRESSFORMATSr9   Úcalcsizer   Úerrorr   r:   r
   ÚUNIXAddressÚrstripr$   ÚIPv4AddressrM   r   ÚIPv6AddressrW   Údecode)ÚclsrX   ÚprefixÚaddrInfoÚversionCommandÚfamilyProtoÚversionÚcommandÚfamilyÚnetprotoÚaddressFormatÚsourceÚdestÚaddrTypeÚaddrClsÚ
addrParserr?   ÚsPortÚdPortr   r   r    r;   ’   sb   ü

þ

ÿý
þ
þýzV2Parser.parse)r0   N)r   r   r   r   r_   rb   rd   Ú_PROXYCOMMANDrc   rh   r4   Úbytesr   r   r   re   r@   ÚstaticmethodrM   rW   Úclassmethodr;   r   r   r   r    r)   8   s0    
÷
ÿ
þr)   )"r   rT   r9   Útypingr   r   r   r   r   Úzope.interfacer   Ú
constantlyr   r	   Útwisted.internetr
   Útwisted.pythonr   Ú r   r   Ú_exceptionsr   r   r   r   r   r!   r`   ra   rd   r�   ÚIProxyParserr)   r   r   r   r    Ú<module>   s$   
