
    \dH                        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    r3d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ej)                              Z* G d d          Z+ ee"j,                   G 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                       e Zd ZU dZej        Zej        ZdZ	dZ
ee         ed<   dZddZed             Zd	efd
Zd Zd Zd Zd Zd ZddZd Zd Zd Zd Zd ZddZd Z d Z!d Z"d Z#d Z$d 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}).
    i   N_realPortNumber     c                     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(   reactors         4lib/python3.11/site-packages/twisted/internet/udp.pyr%   zPort.__init__[   si    * 	tW---	*""         c                     t          j        ||| j                  }|                                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-   s	            r0   _fromListeningDescriptorzPort._fromListeningDescriptory   sd    @ }R??$$&&q)	s'
 
 
 #'r1   returnc                 `    | j         d| j        j         d| j          dS d| j        j         dS )N<z on >z not connected>)r    r'   	__class__r-   s    r0   __repr__zPort.__repr__   sB    +Kt}.KKD4HKKKK?t}.????r1   c                     | j         S )z)
        Return a socket object.
        )r3   rA   s    r0   	getHandlezPort.getHandle        {r1   c                 V    |                                   |                                  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   s    r0   startListeningzPort.startListening   s.     	!!!!!r1   c                    | j         i	 |                                 }|                    | j        | j        f           n@# t
          $ r%}t          j        | j        | j        |          d}~ww xY w| j         }d| _         |                                d         | _	        t          j        |                     | j                  d| j	                   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 starting on )r7   createInternetSocketbindr)   r&   OSErrorr   CannotListenErrorr6   r    r   msg_getLogPrefixr'   	connectedr3   filenor-   sktles      r0   rG   zPort._bindSocket   s    "*M//11$.$)45555 M M M-dndiLLLM )C&*D#  #003!!$-0000$2F2FH	
 	
 	

 k(s   5? 
A.	 A))A.c                 b    | j                             |            |                                  d S N)r'   makeConnectionstartReadingrA   s    r0   rH   zPort._connectToProtocol   s0    $$T***r1   c                    d}|| j         k     r	 | j                            | j                  \  }}|t	          |          z  }| j        t          j        k    r
|dd         }	 | j                            ||           n# t          $ r t          j                     Y nbw xY w# t          $ rQ}|j        d         }|t          v rY d}~dS |t          v r&| j        r| j                                         Y d}~dS  d}~ww xY w|| j         k     dS dS )z=
        Called when my socket is ready for reading.
        r   N   )maxThroughputr3   recvfromr(   lenr:   AF_INET6r'   datagramReceivedBaseExceptionr   errrN   args_sockErrReadIgnore_sockErrReadRefuser+   connectionRefused)r-   readdataaddrsenos         r0   doReadzPort.doRead   sO    T'''![11$2DEE
d D		!%88  8DM224>>>>$   GIIIII+    WQZ+++FFFFF+++* :77999FFFFF T'''''''s5   "B" #A? ?BB"
C=,C8)C87C88C=c                    | j         r|d| j         fv sJ 	 | j                            |          S # t          $ r}|j        d         }|t
          k    r|                     |          cY d}~S |t          k    rt          j	        d          |t          k    r| j                                         n Y d}~dS d}~ww xY w|dk    sJ t          j        |d                   sAt          j        |d                   s'|d         dk    rt          j        |d         d          t          j        |d                   s|d         dk    r0| j        t          j        k    rt          j        |d         d          t          j        |d                   r0| j        t          j        k    rt          j        |d         d          	 | j                            ||          S # t          $ ri}|j        d         }|t
          k    r|                     ||          cY d}~S |t          k    rt          j	        d          |t          k    rY d}~dS  d}~ww xY 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+   r3   sendrN   rd   r   writer   r   MessageLengthErrorr   r'   rg   r   isIPAddressisIPv6AddressInvalidAddressErrorr:   r`   AF_INETsendto)r-   datagramrj   rk   rl   s        r0   rp   z
Port.write  s     0	D$"566666{''111 	 	 	WQZ;;::h////////8^^23EFFF<''M335555 655555	 4<<<<(a11 .tAw77 G},,/GO   $T!W--15aM1I1I$77/GV   %d1g.. 43E3W3W/GI  {))(D999   WQZ;;::h555555558^^23EFFF<'' FFFFFsK   0 
B<,B7&B<,AB77B<G 
I(-II*IIIc                 X    |                      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.
        r1   N)rp   join)r-   seqrj   s      r0   writeSequencezPort.writeSequence@  s(     	

388C==$'''''r1   c                     | j         rt          d          t          j        |          s)t          j        |          st          j        |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   rr   rs   r   rt   r3   connect)r-   hostr&   s      r0   r   zPort.connectO  s      	L   #D)) 	R(2H2N2N 	R+D2PQQQ#TlT4L)))))r1   c                     |                                   | j        r"| j                            d| j                   d S d S )Nr   )stopReadingrR   r/   	callLaterconnectionLostrA   s    r0   _loseConnectionzPort._loseConnection\  sI    > 	;L""1d&9:::::	; 	;r1   c                 v    | j         rt          j                    x}| _        nd }|                                  |S rX   )rR   r   Deferreddr   )r-   results     r0   stopListeningzPort.stopListeninga  s>    > 	#n...FTVVFr1   c                 f    t          j        dt          d           |                                  d S )Nz-Please use stopListening() to disconnect portr\   )
stacklevel)warningswarnDeprecationWarningr   rA   s    r0   loseConnectionzPort.loseConnectioni  s>    ;	
 	
 	
 	

 	r1   c                 b   t          j        d| j        z             d| _        d| _        t          j                            | |           | j                                         | j	        
                                 | `	| `t          | d          r| j                            d           | `dS dS )z&
        Cleans up my socket.
        z(UDP Port %s Closed)Nr   )r   rP   r    r]   r   r$   r   r'   doStopr3   closerS   hasattrr   callback)r-   reasons     r0   r   zPort.connectionLostq  s     	&)==>>>#$$T6222KK4 	FOOD!!!	 	r1   c                 N    |                      | j                  }d|z  | _        dS )zP
        Initialize the C{logstr} attribute to be used by C{logPrefix}.
        z%s (UDP)N)rQ   r'   logstr)r-   	logPrefixs     r0   r*   zPort.setLogStr  s)     &&t}55	 9,r1   c                     t          j        | j                  rt          j        | _        dS t          j        | j                  rt          j        | _        dS | j        rt          j	        | j        d          dS )z8
        Resolve address family for the socket.
        r}   N)
r   rs   r)   r3   r`   r:   rr   ru   r   rt   rA   s    r0   r,   zPort._setAddressFamily  s     !$.11 	!'D!$.11 	!'D^ 	+ >  	 	r1   c                     | j         S )z0
        Return the prefix to log with.
        )r   rA   s    r0   r   zPort.logPrefix  rE   r1   c                     | 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}
        UDPNr\   )r3   r6   r:   ru   r   IPv4Addressr`   IPv6Addressr-   rj   s     r0   getHostzPort.getHost  sy     {&&((//&u4t44446?22&u:RaR:::: 32r1   c                 f    | 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)r3   
setsockopt
SOL_SOCKETSO_BROADCAST)r-   enableds     r0   setBroadcastAllowedzPort.setBroadcastAllowed  s*     	v0&2EwOOOOOr1   c                 z    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}
        )boolr3   
getsockoptr   r   rA   s    r0   getBroadcastAllowedzPort.getBroadcastAllowed  s*     DK**6+<f>QRRSSSr1   )r!   r"   NrX   )&__name__
__module____qualname____doc__r3   ru   r:   
SOCK_DGRAMr5   r]   r    r   int__annotations__r7   r%   classmethodr;   strrB   rD   rI   rG   rH   rm   rp   r{   r   r   r   r   r   r*   r,   r   r   r   r    r1   r0   r   r   >   s         $ NM"JM%)OXc])))! ! ! !< ) ) [)V@# @ @ @ @  " " "!) !) !)F    @< < < <|( ( (* * *; ; ;
        - - -    ; ; ;P P PT T T T Tr1   r   c                   X    e Zd ZdZd Zd Zd Zd Zd Zd Z	d Z
dd
Zd Zd ZddZdS )MulticastMixinz,
    Implement multicast functionality.
    c                     | j                             t           j        t           j                  }t          j        t          j        d|                    S )Nz@i)r3   r   
IPPROTO_IPIP_MULTICAST_IF	inet_ntoastructpack)r-   is     r0   getOutgoingInterfacez#MulticastMixin.getOutgoingInterface  s<    K""6#4f6LMMD! 4 4555r1   c                 f    | j                             |                              | j                  S )zReturns Deferred of success.)r/   resolveaddCallback_setInterfacer   s     r0   setOutgoingInterfacez#MulticastMixin.setOutgoingInterface  s)    |##D))55d6HIIIr1   c                     t          j        |          }| j                             t           j        t           j        |           dS )NrK   )r3   	inet_atonr   r   r   )r-   rj   r   s      r0   r   zMulticastMixin._setInterface  s7    T""v0&2H!LLLqr1   c                 `    | j                             t           j        t           j                  S rX   )r3   r   r   IP_MULTICAST_LOOPrA   s    r0   getLoopbackModezMulticastMixin.getLoopbackMode  s     {%%f&79QRRRr1   c                     t          j        dt          |                    }| j                            t          j        t          j        |           d S )Nb)r   r   r   r3   r   r   r   )r-   modes     r0   setLoopbackModezMulticastMixin.setLoopbackMode  s?    {3T

++v0&2JDQQQQQr1   c                 `    | j                             t           j        t           j                  S rX   )r3   r   r   IP_MULTICAST_TTLrA   s    r0   getTTLzMulticastMixin.getTTL  s     {%%f&79PQQQr1   c                     t          j        d|          }| j                            t          j        t          j        |           d S )NB)r   r   r3   r   r   r   )r-   ttls     r0   setTTLzMulticastMixin.setTTL  s9    k#s##v0&2I3OOOOOr1   r!   c                 j    | j                             |                              | j        |d          S )z4Join a multicast group. Returns Deferred of success.rK   r/   r   r   
_joinAddr1r-   rj   r)   s      r0   	joinGroupzMulticastMixin.joinGroup  -    |##D))55doyRSTTTr1   c                 j    | j                             |                              | j        ||          S rX   )r/   r   r   
_joinAddr2)r-   rj   r)   ry   s       r0   r   zMulticastMixin._joinAddr1  s-    |##I..::4?DRVWWWr1   c                 b   t          j        |          }t          j        |          }|rt           j        }nt           j        }	 | j                             t           j        |||z              d S # t          $ r4}t          j        t          j
        ||g|j        R            cY d }~S d }~ww xY wrX   )r3   r   IP_ADD_MEMBERSHIPIP_DROP_MEMBERSHIPr   r   rN   r   Failurer   MulticastJoinErrorrd   )r-   r)   rj   ry   cmdes         r0   r   zMulticastMixin._joinAddr2  s    %%$Y//	 	,*CC+C	WK""6#4c4);KLLLLL 	W 	W 	W?5#;D)#Uaf#U#U#UVVVVVVVV	Ws   )A0 0
B.:)B)#B.)B.c                 j    | j                             |                              | j        |d          S )z2Leave multicast group, return Deferred of success.r   r   r   s      r0   
leaveGroupzMulticastMixin.leaveGroup  r   r1   N)r!   )r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r1   r0   r   r     s         6 6 6J J J  
S S SR R RR R RP P PU U U UX X X
W 
W 
WU U U U U Ur1   r   c                   (    e Zd ZdZ	 	 	 	 ddZd ZdS )	MulticastPortz.
    UDP Port that supports multicasting.
    r!   r"   NFc                 R    t                               | |||||           || _        dS )zX
        @see: L{twisted.internet.interfaces.IReactorMulticast.listenMulticast}
        N)r   r%   listenMultiple)r-   r&   r.   r)   r(   r/   r   s          r0   r%   zMulticastPort.__init__  s.     	dD%M7KKK,r1   c                 t   t                               |           }| j        r|                    t          j        t          j        d           t          t          d          rV	 |                    t          j        t          j        d           n)# t          $ r}|j
        t          k    rn Y d }~nd }~ww xY w|S )NrK   SO_REUSEPORT)r   rL   r   r   r3   r   SO_REUSEADDRr   r   rN   errnor   rT   s      r0   rL   z"MulticastPort.createInternetSocket  s    ''-- 
	NN6,f.A1EEEv~.. NN6#4f6I1MMMM   x;..  
s   #+B 
B5B00B5)r!   r"   NF)r   r   r   r   r%   rL   r   r1   r0   r   r     sO          - - - -    r1   r   ).r   r3   r   r   typingr   zope.interfacer   twisted.python.runtimer   r   r   r   r	   r
   r   r   r   r   r   r   re   rf   r   r   r   r   r   twisted.internetr   r   r   r   r   r   twisted.pythonr   r   IListeningPortIUDPTransportISystemHandler$   r   r   IMulticastTransportr   r   r1   r0   <module>r      s  
           & & & & & & / / / / / /7$$$$$$$$$$$$                  #NKP)=,U H"LFEEUUUUUUUUUUUUUUUU %5& O N N N N N N N N N N N N N N N ' ' ' ' ' ' ' ' z79Q wT wT wT wT wT4= wT wT wTt5U 5U 5U 5U 5U 5U 5U 5Up Z+,,! ! ! ! !ND ! ! -,! ! !r1   