o
    ¯b»H  ã                   @   s`  d Z ddlZddlZddlZddlmZ ddlmZ ddlm	Z	 e	dkrWddl
mZ ddl
mZ dd	l
mZmZmZmZmZmZmZ eeeegZeeeegZeZeZeZeZndd
l
mZmZmZmZmZmZ eeegZegZddlmZmZmZm Z m!Z!m"Z" ddl#m$Z$m%Z% ee"j&e"j'e"j(ƒG dd„ dej)ƒƒZ*G dd„ dƒZ+ee"j,ƒG dd„ de+e*ƒƒZ-dS )a�  
Various asynchronous UDP classes.

Please do not use this module directly.

@var _sockErrReadIgnore: list of symbolic error constants (from the C{errno}
    module) representing socket errors where the error is temporary and can be
    ignored.

@var _sockErrReadRefuse: list of symbolic error constants (from the C{errno}
    module) representing socket errors that indicate connection refused.
é    N)ÚOptional)Úimplementer)ÚplatformTypeÚwin32)ÚWSAEINPROGRESS)ÚWSAEWOULDBLOCK)ÚWSAECONNREFUSEDÚWSAECONNRESETÚWSAEINTRÚWSAEMSGSIZEÚWSAENETRESETÚWSAENOPROTOOPTÚWSAETIMEDOUT)ÚEAGAINÚECONNREFUSEDÚEINTRÚEMSGSIZEÚENOPROTOOPTÚEWOULDBLOCK)ÚabstractÚaddressÚbaseÚdeferÚerrorÚ
interfaces)ÚfailureÚlogc                   @   sî   e Zd ZU dZejZejZdZ	dZ
ee ed< dZd2dd„Zed	d
„ ƒZdefdd„Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zd3dd„Zdd„ Zdd„ Zdd„ Zd d!„ Zd"d#„ Zd3d$d%„Zd&d'„ Z d(d)„ Z!d*d+„ Z"d,d-„ Z#d.d/„ Z$d0d1„ Z%dS )4ÚPorta©  
    UDP port, listening for packets.

    @ivar maxThroughput: Maximum number of bytes read in one event
        loop iteration.

    @ivar addressFamily: L{socket.AF_INET} or L{socket.AF_INET6}, depending on
        whether this port is listening on an IPv4 address or an IPv6 address.

    @ivar _realPortNumber: Actual port number being listened on. The
        value will be L{None} until this L{Port} is listening.

    @ivar _preexistingSocket: If not L{None}, a L{socket.socket} instance which
        was created and initialized outside of the reactor and will be used to
        listen for connections (instead of a new socket being created by this
        L{Port}).
    i   NÚ_realPortNumberÚ é    c                 C   s@   t j | |¡ || _|| _|| _|| _|  ¡  d| _|  	¡  dS )a  
        @param port: A port number on which to listen.
        @type port: L{int}

        @param proto: A C{DatagramProtocol} instance which will be
            connected to the given C{port}.
        @type proto: L{twisted.internet.protocol.DatagramProtocol}

        @param interface: The local IPv4 or IPv6 address to which to bind;
            defaults to '', ie all IPv4 addresses.
        @type interface: L{str}

        @param maxPacketSize: The maximum packet size to accept.
        @type maxPacketSize: L{int}

        @param reactor: A reactor which will notify this C{Port} when
            its socket is ready for reading or writing. Defaults to
            L{None}, ie the default global reactor.
        @type reactor: L{interfaces.IReactorFDSet}
        N)
r   ÚBasePortÚ__init__ÚportÚprotocolÚmaxPacketSizeÚ	interfaceÚ	setLogStrÚ_connectedAddrÚ_setAddressFamily)Úselfr#   Úprotor&   r%   Úreactor© r-   ú6/usr/lib/python3/dist-packages/twisted/internet/udp.pyr"   [   s   zPort.__init__c           	      C   s8   t  ||| j¡}| ¡ d }| d||||d�}||_|S )a�  
        Create a new L{Port} based on an existing listening
        I{SOCK_DGRAM} socket.

        @param reactor: A reactor which will notify this L{Port} when
            its socket is ready for reading or writing. Defaults to
            L{None}, ie the default global reactor.
        @type reactor: L{interfaces.IReactorFDSet}

        @param fd: An integer file descriptor associated with a listening
            socket.  The socket must be in non-blocking mode.  Any additional
            attributes desired, such as I{FD_CLOEXEC}, must also be set already.
        @type fd: L{int}

        @param addressFamily: The address family (sometimes called I{domain}) of
            the existing socket.  For example, L{socket.AF_INET}.
        @type addressFamily: L{int}

        @param protocol: A C{DatagramProtocol} instance which will be
            connected to the C{port}.
        @type protocol: L{twisted.internet.protocol.DatagramProtocol}

        @param maxPacketSize: The maximum packet size to accept.
        @type maxPacketSize: L{int}

        @return: A new instance of C{cls} wrapping the socket given by C{fd}.
        @rtype: L{Port}
        r   N)r&   r,   r%   )ÚsocketÚfromfdÚ
socketTypeÚgetsocknameÚ_preexistingSocket)	Úclsr,   ÚfdÚaddressFamilyr$   r%   r#   r&   r*   r-   r-   r.   Ú_fromListeningDescriptory   s    ûzPort._fromListeningDescriptorÚreturnc                 C   s2   | j d urd| jj› d| j › d�S d| jj› d�S )Nú<z on ú>z not connected>)r   r$   Ú	__class__©r*   r-   r-   r.   Ú__repr__¥   s   
zPort.__repr__c                 C   ó   | j S )z)
        Return a socket object.
        )r/   r<   r-   r-   r.   Ú	getHandle«   ó   zPort.getHandlec                 C   s   |   ¡  |  ¡  dS )zÐ
        Create and bind my socket, and begin listening on it.

        This is called on unserialization, and must be called after creating a
        server to begin listening on the specified port.
        N)Ú_bindSocketÚ_connectToProtocolr<   r-   r-   r.   ÚstartListening±   s   zPort.startListeningc              
   C   s¤   | j du r*z|  ¡ }| | j| jf¡ W n ty) } z	t | j| j|¡‚d}~ww | j }d| _ | ¡ d | _	t
 d|  | j¡| j	f ¡ d| _|| _| jj| _dS )aJ  
        Prepare and assign a L{socket.socket} instance to
        C{self.socket}.

        Either creates a new SOCK_DGRAM L{socket.socket} bound to
        C{self.interface} and C{self.port} or takes an existing
        L{socket.socket} provided via the
        L{interfaces.IReactorSocket.adoptDatagramPort} interface.
        Né   z%s starting on %s)r3   ÚcreateInternetSocketÚbindr&   r#   ÚOSErrorr   ÚCannotListenErrorr2   r   r   ÚmsgÚ_getLogPrefixr$   Ú	connectedr/   Úfileno©r*   ÚsktÚler-   r-   r.   rA   »   s&   

€ÿÿÿzPort._bindSocketc                 C   s   | j  | ¡ |  ¡  d S ©N)r$   ÚmakeConnectionÚstartReadingr<   r-   r-   r.   rB   Þ   s   zPort._connectToProtocolc              
   C   sê   d}|| j k rsz| j | j¡\}}W n0 tyB } z$|jd }|tv r*W Y d}~dS |tv r=| jr6| j	 
¡  W Y d}~dS ‚ d}~ww |t|ƒ7 }| jtjkrU|dd… }z	| j	 ||¡ W n tyk   t ¡  Y nw || j k sdS dS )z=
        Called when my socket is ready for reading.
        r   Né   )ÚmaxThroughputr/   Úrecvfromr%   rG   ÚargsÚ_sockErrReadIgnoreÚ_sockErrReadRefuser(   r$   ÚconnectionRefusedÚlenr6   ÚAF_INET6ÚdatagramReceivedÚBaseExceptionr   Úerr)r*   ÚreadÚdataÚaddrÚseÚnor-   r-   r.   ÚdoReadâ   s0   


€ø
ÿèzPort.doReadc              
   C   sÀ  | j rO|d| j fv sJ ‚z| j |¡W S  tyN } z/|jd }|tkr/|  |¡W  Y d}~S |tkr8t 	d¡‚|t
krB| j ¡  n‚ W Y d}~dS d}~ww |dksUJ ‚t |d ¡sqt |d ¡sq|d dkrqt |d d¡‚t |d ¡s~|d dkrŒ| jtjkrŒt |d d¡‚t |d ¡r¡| jtjkr¡t |d d¡‚z| j ||¡W S  tyß } z*|jd }|tkrÆ|  ||¡W  Y d}~S |tkrÏt 	d¡‚|t
krÚW Y d}~dS ‚ d}~ww )az  
        Write a datagram.

        @type datagram: L{bytes}
        @param datagram: The datagram to be sent.

        @type addr: L{tuple} containing L{str} as first element and L{int} as
            second element, or L{None}
        @param addr: A tuple of (I{stringified IPv4 or IPv6 address},
            I{integer port number}); can be L{None} in connected mode.
        Nr   zmessage too longz<broadcast>z0write() only accepts IP addresses, not hostnamesz7IPv6 port write() called with IPv4 or broadcast addressz*IPv4 port write() called with IPv6 address)r(   r/   ÚsendrG   rV   r   Úwriter   r   ÚMessageLengthErrorr   r$   rY   r   ÚisIPAddressÚisIPv6AddressÚInvalidAddressErrorr6   r[   ÚAF_INETÚsendto)r*   Údatagramra   rb   rc   r-   r-   r.   rf     sb   

þ€ùÿþÿÿÿÿ

€ôz
Port.writec                 C   s   |   d |¡|¡ dS )aÛ  
        Write a datagram constructed from an iterable of L{bytes}.

        @param seq: The data that will make up the complete datagram to be
            written.
        @type seq: an iterable of L{bytes}

        @type addr: L{tuple} containing L{str} as first element and L{int} as
            second element, or L{None}
        @param addr: A tuple of (I{stringified IPv4 or IPv6 address},
            I{integer port number}); can be L{None} in connected mode.
        ó    N)rf   Újoin)r*   Úseqra   r-   r-   r.   ÚwriteSequence@  s   zPort.writeSequencec                 C   sL   | j rtdƒ‚t |¡st |¡st |d¡‚||f| _ | j ||f¡ dS )z-
        'Connect' to remote server.
        z:already connected, reconnecting is not currently supportedúnot an IPv4 or IPv6 address.N)	r(   ÚRuntimeErrorr   rh   ri   r   rj   r/   Úconnect)r*   Úhostr#   r-   r-   r.   rt   O  s   ÿ
zPort.connectc                 C   s&   |   ¡  | jr| j d| j¡ d S d S )Nr   )ÚstopReadingrK   r,   Ú	callLaterÚconnectionLostr<   r-   r-   r.   Ú_loseConnection\  s   ÿzPort._loseConnectionc                 C   s&   | j rt ¡  }| _nd }|  ¡  |S rP   )rK   r   ÚDeferredÚdry   )r*   Úresultr-   r-   r.   ÚstopListeninga  s
   zPort.stopListeningc                 C   s   t jdtdd� |  ¡  d S )Nz-Please use stopListening() to disconnect portrS   )Ú
stacklevel)ÚwarningsÚwarnÚDeprecationWarningr}   r<   r-   r-   r.   ÚloseConnectioni  s   ýzPort.loseConnectionc                 C   sh   t  d| j ¡ d| _d| _tj | |¡ | j ¡  | j	 
¡  | `	| `t| dƒr2| j d¡ | `dS dS )z&
        Cleans up my socket.
        z(UDP Port %s Closed)Néÿÿÿÿr{   )r   rI   r   rT   r   r!   rx   r$   ÚdoStopr/   ÚcloserL   Úhasattrr{   Úcallback)r*   Úreasonr-   r-   r.   rx   q  s   


þzPort.connectionLostc                 C   s   |   | j¡}d| | _dS )zP
        Initialize the C{logstr} attribute to be used by C{logPrefix}.
        z%s (UDP)N)rJ   r$   Úlogstr)r*   Ú	logPrefixr-   r-   r.   r'   �  s   zPort.setLogStrc                 C   sH   t  | j¡rtj| _dS t  | j¡rtj| _dS | jr"t 	| jd¡‚dS )z8
        Resolve address family for the socket.
        rr   N)
r   ri   r&   r/   r[   r6   rh   rk   r   rj   r<   r-   r-   r.   r)   ˆ  s   ÿÿzPort._setAddressFamilyc                 C   r>   )z0
        Return the prefix to log with.
        )r‰   r<   r-   r-   r.   rŠ   •  r@   zPort.logPrefixc                 C   sR   | j  ¡ }| jt jkrtjdg|¢R Ž S | jt jkr'tjdg|dd… ¢R Ž S dS )z¬
        Return the local address of the UDP connection

        @returns: the local address of the UDP connection
        @rtype: L{IPv4Address} or L{IPv6Address}
        ÚUDPNrS   )r/   r2   r6   rk   r   ÚIPv4Addressr[   ÚIPv6Address©r*   ra   r-   r-   r.   ÚgetHost›  s   
ÿzPort.getHostc                 C   s   | j  t jt j|¡ dS )z«
        Set whether this port may broadcast. This is disabled by default.

        @param enabled: Whether the port may broadcast.
        @type enabled: L{bool}
        N)r/   Ú
setsockoptÚ
SOL_SOCKETÚSO_BROADCAST)r*   Úenabledr-   r-   r.   ÚsetBroadcastAllowed¨  s   zPort.setBroadcastAllowedc                 C   s   t | j tjtj¡ƒS )z“
        Checks if broadcast is currently allowed on this port.

        @return: Whether this port may broadcast.
        @rtype: L{bool}
        )Úboolr/   Ú
getsockoptr‘   r’   r<   r-   r-   r.   ÚgetBroadcastAllowed±  s   zPort.getBroadcastAllowed)r   r    NrP   )&Ú__name__Ú
__module__Ú__qualname__Ú__doc__r/   rk   r6   Ú
SOCK_DGRAMr1   rT   r   r   ÚintÚ__annotations__r3   r"   Úclassmethodr7   Ústrr=   r?   rC   rA   rB   rd   rf   rq   rt   ry   r}   r‚   rx   r'   r)   rŠ   r�   r”   r—   r-   r-   r-   r.   r   >   s:   
 

+
#
 >
	r   c                   @   sl   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d„Zdd„ Zdd„ Zddd„ZdS )ÚMulticastMixinz,
    Implement multicast functionality.
    c                 C   s$   | j  t jt j¡}t  t d|¡¡S )Nz@i)r/   r–   Ú
IPPROTO_IPÚIP_MULTICAST_IFÚ	inet_ntoaÚstructÚpack)r*   Úir-   r-   r.   ÚgetOutgoingInterfaceÀ  s   z#MulticastMixin.getOutgoingInterfacec                 C   s   | j  |¡ | j¡S )zReturns Deferred of success.)r,   ÚresolveÚaddCallbackÚ_setInterfacerŽ   r-   r-   r.   ÚsetOutgoingInterfaceÄ  s   z#MulticastMixin.setOutgoingInterfacec                 C   s"   t  |¡}| j  t jt j|¡ dS )NrD   )r/   Ú	inet_atonr�   r¢   r£   )r*   ra   r§   r-   r-   r.   r«   È  s   
zMulticastMixin._setInterfacec                 C   ó   | j  t jt j¡S rP   )r/   r–   r¢   ÚIP_MULTICAST_LOOPr<   r-   r-   r.   ÚgetLoopbackModeÍ  ó   zMulticastMixin.getLoopbackModec                 C   s(   t  dt|ƒ¡}| j tjtj|¡ d S )NÚb)r¥   r¦   r•   r/   r�   r¢   r¯   )r*   Úmoder-   r-   r.   ÚsetLoopbackModeÐ  s   zMulticastMixin.setLoopbackModec                 C   r®   rP   )r/   r–   r¢   ÚIP_MULTICAST_TTLr<   r-   r-   r.   ÚgetTTLÔ  r±   zMulticastMixin.getTTLc                 C   s$   t  d|¡}| j tjtj|¡ d S )NÚB)r¥   r¦   r/   r�   r¢   rµ   )r*   Úttlr-   r-   r.   ÚsetTTL×  s   zMulticastMixin.setTTLr   c                 C   ó   | j  |¡ | j|d¡S )z4Join a multicast group. Returns Deferred of success.rD   ©r,   r©   rª   Ú
_joinAddr1©r*   ra   r&   r-   r-   r.   Ú	joinGroupÛ  ó   zMulticastMixin.joinGroupc                 C   s   | j  |¡ | j||¡S rP   )r,   r©   rª   Ú
_joinAddr2)r*   ra   r&   ro   r-   r-   r.   r¼   ß  s   zMulticastMixin._joinAddr1c              
   C   s„   t  |¡}t  |¡}|rt j}nt j}z| j  t j||| ¡ W d S  tyA } zt t	j
||g|j¢R Ž ¡W  Y d }~S d }~ww rP   )r/   r­   ÚIP_ADD_MEMBERSHIPÚIP_DROP_MEMBERSHIPr�   r¢   rG   r   ÚFailurer   ÚMulticastJoinErrorrV   )r*   r&   ra   ro   ÚcmdÚer-   r-   r.   rÀ   â  s   

(€ÿzMulticastMixin._joinAddr2c                 C   rº   )z2Leave multicast group, return Deferred of success.r   r»   r½   r-   r-   r.   Ú
leaveGroupî  r¿   zMulticastMixin.leaveGroupN)r   )r˜   r™   rš   r›   r¨   r¬   r«   r°   r´   r¶   r¹   r¾   r¼   rÀ   rÇ   r-   r-   r-   r.   r¡   »  s    
r¡   c                   @   s*   e Zd ZdZ				d
dd„Zdd	„ ZdS )ÚMulticastPortz.
    UDP Port that supports multicasting.
    r   r    NFc                 C   s   t  | |||||¡ || _dS )zX
        @see: L{twisted.internet.interfaces.IReactorMulticast.listenMulticast}
        N)r   r"   ÚlistenMultiple)r*   r#   r+   r&   r%   r,   rÉ   r-   r-   r.   r"   ù  s   
zMulticastPort.__init__c              
   C   s~   t  | ¡}| jr=| tjtjd¡ ttdƒr=z| tjtjd¡ W |S  t	y< } z|j
tkr0n‚ W Y d }~|S d }~ww |S )NrD   ÚSO_REUSEPORT)r   rE   rÉ   r�   r/   r‘   ÚSO_REUSEADDRr†   rÊ   rG   Úerrnor   rM   r-   r-   r.   rE     s    

ú

þ€úz"MulticastPort.createInternetSocket)r   r    NF)r˜   r™   rš   r›   r"   rE   r-   r-   r-   r.   rÈ   ó  s    
ùrÈ   ).r›   r/   r¥   r   Útypingr   Úzope.interfacer   Útwisted.python.runtimer   rÌ   r   r   r   r	   r
   r   r   r   r   r   rW   rX   r   r   r   r   r   Útwisted.internetr   r   r   r   r   r   Útwisted.pythonr   r   ÚIListeningPortÚIUDPTransportÚISystemHandler!   r   r¡   ÚIMulticastTransportrÈ   r-   r-   r-   r.   Ú<module>   s>   $ 
 ÿ  |8