U
    �Acj‘B  ã                   @  sv  d Z ddlmZ ddlZddlZddlmZ ddlmZ ddl	m
Z
 ddlmZ ddlmZ dd	lmZ ed
krÖd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!n0d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+ ee)j,e)j-e)j.ƒG dd„ de&j/ƒƒZ0ee)j1ƒG dd„ de
e0ƒƒZ2d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.
é    )ÚannotationsN)ÚOptional)Úimplementer)ÚMulticastMixin)ÚIReactorMulticast)ÚAbstractDatagramProtocol)ÚplatformTypeÚwin32)ÚWSAEINPROGRESS)ÚWSAEWOULDBLOCK)ÚWSAECONNREFUSEDÚWSAECONNRESETÚWSAEINTRÚWSAEMSGSIZEÚWSAENETRESETÚWSAENOPROTOOPTÚWSAETIMEDOUT)ÚEAGAINÚECONNREFUSEDÚEINTRÚEMSGSIZEÚENOPROTOOPTÚEWOULDBLOCK)ÚabstractÚaddressÚbaseÚdeferÚerrorÚ
interfaces)Úlogc                   @  sú   e Zd ZU dZejZded< ejZ	ded< dZ
dZded	< dZd8dd„Zedd„ ƒZddœdd„Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zd9d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d0d1„ Zd2d3„ Z d4d5„ Z!d6d7„ Z"dS );Ú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}).
    zsocket.AddressFamilyÚaddressFamilyzsocket.SocketKindÚ
socketTypei   NzOptional[int]Ú_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© r2   ú8/tmp/pip-unpacked-wheel-nrvc_22y/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+   r1   r*   )ÚsocketÚfromfdr"   ÚgetsocknameÚ_preexistingSocket)	Úclsr1   Úfdr!   r)   r*   r(   r+   r/   r2   r2   r3   Ú_fromListeningDescriptor{   s     ûzPort._fromListeningDescriptorÚstr©Úreturnc                 C  s6   | j d k	r"d| jj› d| j › d�S d| jj› d�S d S )Nú<z on ú>z not connected>)r#   r)   Ú	__class__©r/   r2   r2   r3   Ú__repr__§   s    
zPort.__repr__c                 C  s   | j S )z)
        Return a socket object.
        )r4   rA   r2   r2   r3   Ú	getHandle­   s    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Ú_connectToProtocolrA   r2   r2   r3   ÚstartListening³   s    zPort.startListeningc              
   C  s°   | j dkr`z|  ¡ }| | j| jf¡ W ql tk
r\ } zt | j| j|¡‚W 5 d}~X Y qlX n| 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)r7   ÚcreateInternetSocketÚbindr+   r(   ÚOSErrorr   ZCannotListenErrorr6   r#   r   ÚmsgÚ_getLogPrefixr)   Ú	connectedr4   Úfileno©r/   ZsktÚler2   r2   r3   rD   ½   s"    

&ÿÿzPort._bindSocketc                 C  s   | j  | ¡ |  ¡  d S ©N)r)   ZmakeConnectionZstartReadingrA   r2   r2   r3   rE   à   s    zPort._connectToProtocolc              
   C  sâ   d}|| j k rÞz| j | j¡\}}W nb tk
r† } zD|jd }|tkrRW Y ¢,dS |tkrt| jrj| j	 
¡  W Y ¢
dS ‚ W 5 d}~X Y qX |t|ƒ7 }| jtjkr¬|dd… }z| j	 ||¡ W q tk
rÚ   t ¡  Y qX qdS )z=
        Called when my socket is ready for reading.
        r   Né   )ÚmaxThroughputr4   Úrecvfromr*   rJ   ÚargsÚ_sockErrReadIgnoreÚ_sockErrReadRefuser-   r)   ÚconnectionRefusedÚlenr!   ÚAF_INET6ZdatagramReceivedÚBaseExceptionr   Úerr)r/   ÚreadÚdataÚaddrÚseÚnor2   r2   r3   ÚdoReadä   s(    




zPort.doReadc              
   C  sØ  | j rœ|d| j fkst‚z| j |¡W S  tk
r– } zR|jd }|tkr\|  |¡ W Y ¢0S |tkrpt	 
d¡‚n|tkr„| j ¡  n‚ W 5 d}~X Y nX �n8|dks¨t‚t |d ¡sàt |d ¡sà|d dkràt	 |d d¡‚t |d ¡� sþ|d dk�r| jtjk�rt	 |d d¡‚t |d ¡�rJ| jtjk�rJt	 |d d¡‚z| j ||¡W S  tk
�rÒ } zX|jd }|tk�r–|  ||¡ W Y ¢2S |tk�r¬t	 
d¡‚n|tk�rÀW Y ¢
dS ‚ W 5 d}~X Y nX dS )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-   ÚAssertionErrorr4   ÚsendrJ   rU   r   Úwriter   r   ZMessageLengthErrorr   r)   rX   r   ÚisIPAddressÚisIPv6AddressÚInvalidAddressErrorr!   rZ   ÚAF_INETÚsendto)r/   Zdatagramr_   r`   ra   r2   r2   r3   re     sd    
ÿþ
ý ÿÿ
ÿ
þ ÿ ÿ




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)re   Újoin)r/   Úseqr_   r2   r2   r3   ÚwriteSequenceB  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   rf   rg   r   rh   r4   Úconnect)r/   Úhostr(   r2   r2   r3   rq   Q  s    ÿ
zPort.connectc                 C  s"   |   ¡  | jr| j d| j¡ d S )Nr   )ZstopReadingrM   r1   Z	callLaterÚconnectionLostrA   r2   r2   r3   Ú_loseConnection^  s    zPort._loseConnectionc                 C  s&   | j rt ¡  }| _nd }|  ¡  |S rQ   )rM   r   ZDeferredÚdrt   )r/   Úresultr2   r2   r3   ÚstopListeningc  s
    zPort.stopListeningc                 C  s   t jdtdd� |  ¡  d S )Nz-Please use stopListening() to disconnect portrR   )Ú
stacklevel)ÚwarningsÚwarnÚDeprecationWarningrw   rA   r2   r2   r3   ÚloseConnectionk  s    ýzPort.loseConnectionc                 C  sd   t  d| j ¡ d| _d| _tj | |¡ | j ¡  | j	 
¡  | `	| `t| dƒr`| j d¡ | `dS )z&
        Cleans up my socket.
        z(UDP Port %s Closed)Néÿÿÿÿru   )r   rK   r#   rS   r   r&   rs   r)   ZdoStopr4   ÚcloserN   Úhasattrru   Úcallback)r/   Úreasonr2   r2   r3   rs   s  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)rL   r)   Úlogstr)r/   Ú	logPrefixr2   r2   r3   r,   ƒ  s    zPort.setLogStrc                 C  sD   t  | j¡rtj| _n*t  | j¡r,tj| _n| jr@t 	| jd¡‚dS )z8
        Resolve address family for the socket.
        ro   N)
r   rg   r+   r4   rZ   r!   rf   ri   r   rh   rA   r2   r2   r3   r.   Š  s    

 ÿzPort._setAddressFamilyc                 C  s   | j S )z0
        Return the prefix to log with.
        )r‚   rA   r2   r2   r3   rƒ   —  s    zPort.logPrefixc                 C  sJ   | j  ¡ }| jt jkr$tjd|žŽ S | jt jkrFtjd|dd… žŽ 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}
        ÚUDPNrR   )r„   )r„   )r4   r6   r!   ri   r   ÚIPv4AddressrZ   ÚIPv6Address)r/   r_   r2   r2   r3   Ú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)r4   Ú
setsockoptÚ
SOL_SOCKETÚSO_BROADCAST)r/   Zenabledr2   r2   r3   Ú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}
        )Úboolr4   Ú
getsockoptr‰   rŠ   rA   r2   r2   r3   ÚgetBroadcastAllowed³  s    zPort.getBroadcastAllowed)r$   r%   N)N)N)#Ú__name__Ú
__module__Ú__qualname__Ú__doc__r4   ri   r!   Ú__annotations__Ú
SOCK_DGRAMr"   rS   r#   r7   r'   Úclassmethodr:   rB   rC   rF   rD   rE   rb   re   rn   rq   rt   rw   r|   rs   r,   r.   rƒ   r‡   r‹   rŽ   r2   r2   r2   r3   r    @   s8   


+
# 
>
	r    c                	   @  s:   e Zd ZdZdddddd	d
ddœdd„Zddœdd„ZdS )ÚMulticastPortz.
    UDP Port that supports multicasting.
    r$   r%   NFÚintr   r;   zIReactorMulticast | NonerŒ   ÚNone)r(   r0   r+   r*   r1   ÚlistenMultipler=   c                 C  s   t  | |||||¡ || _dS )zX
        @see: L{twisted.internet.interfaces.IReactorMulticast.listenMulticast}
        N)r    r'   r™   )r/   r(   r0   r+   r*   r1   r™   r2   r2   r3   r'   Ã  s    zMulticastPort.__init__zsocket.socketr<   c              
   C  sx   t  | ¡}| jrt| tjtjd¡ ttdƒrtz| tjtjd¡ W n0 t	k
rr } z|j
tkr`n‚ W 5 d}~X Y nX |S )z§
        Override L{Port.createInternetSocket} to configure the socket to honor
        the C{listenMultiple} argument to L{IReactorMulticast.listenMultiple}.
        rG   ÚSO_REUSEPORTN)r    rH   r™   rˆ   r4   r‰   ÚSO_REUSEADDRr   rš   rJ   Úerrnor   rO   r2   r2   r3   rH   Ò  s    


z"MulticastPort.createInternetSocket)r$   r%   NF)r�   r�   r‘   r’   r'   rH   r2   r2   r2   r3   r–   ½  s       ùr–   )3r’   Ú
__future__r   r4   ry   Útypingr   Zzope.interfacer   Ztwisted.internet._multicastr   Ztwisted.internet.interfacesr   Ztwisted.internet.protocolr   Ztwisted.python.runtimer   rœ   r
   r   r   r   r   r   r   r   r   r   rV   rW   r   r   r   r   r   Ztwisted.internetr   r   r   r   r   r   Ztwisted.pythonr   ZIListeningPortZIUDPTransportZISystemHandler&   r    ZIMulticastTransportr–   r2   r2   r2   r3   Ú<module>   sD   $ 
   ÿ  |