
    ϪfH                        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"jL                  e"jN                  e"jP                         G d dejR                               Z* G d d      Z+ ee"jX                         G d de+e*             Z-y)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%y)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_realPortNumberc                     t         j                  j                  | |       || _        || _        || _        || _        | j                          d| _        | j                          y)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         6/usr/lib/python3/dist-packages/twisted/internet/udp.pyr#   zPort.__init__[   sS    * 	tW-	*""     c                     t        j                  ||| 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	            r.   _fromListeningDescriptorzPort._fromListeningDescriptory   sV    @ }}R?$$&q)	'
 #'r/   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    r.   __repr__zPort.__repr__   sO    +t}}../tD4H4H3IKKt}}../??r/   c                     | j                   S )z)
        Return a socket object.
        )r1   r?   s    r.   	getHandlezPort.getHandle        {{r/   c                 D    | j                          | j                          y)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?   s    r.   startListeningzPort.startListening   s     	!r/   c                 (   | j                   9	 | j                         }|j                  | j                  | j                  f       n| j                   }d| _         |j                         d   | _	        t        j                  | j                  | j                        d| j                         d| _        || _        | j                  j                   | _        y# t
        $ r0}t        j                  | j                  | j                  |      d}~ww xY w)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 )r5   createInternetSocketbindr'   r$   OSErrorr   CannotListenErrorr4   r    r   msg_getLogPrefixr%   	connectedr1   filenor+   sktles      r.   rE   zPort._bindSocket   s     ""*M//1$..$))45
 ))C&*D#  #03!!$--0$2F2FH	

 kk((%  M--dnndiiLLMs   7C 	D!+DDc                 Z    | j                   j                  |        | j                          y N)r%   makeConnectionstartReadingr?   s    r.   rF   zPort._connectToProtocol   s     $$T*r/   c                 <   d}|| j                   k  r	 | j                  j                  | j                        \  }}|t	        |      z  }| j
                  t        j                  k(  r|dd }	 | j                  j                  ||       || j                   k  ryy# t        $ r t        j                          Y 1w xY w# t        $ rU}|j                  d   }|t        v rY d}~y|t        v r+| j                   r| j                  j#                          Y d}~y d}~ww xY w)z=
        Called when my socket is ready for reading.
        r   N   )maxThroughputr1   recvfromr&   lenr8   AF_INET6r%   datagramReceivedBaseExceptionr   errrL   args_sockErrReadIgnore_sockErrReadRefuser)   connectionRefused)r+   readdataaddrsenos         r.   doReadzPort.doRead   s     T'''![[11$2D2DE
d D	!%%8  8DMM224>/ T'''0 % GGI+  WWQZ++++**779s5   (B= ,B B:9B:=	DD".DDDc                    | j                   r.|d| j                   fv sJ 	 | j                  j                  |      S |dk7  sJ t        j                  |d         s9t        j                  |d         s!|d   dk7  rt        j                   |d   d      t        j                  |d         s|d   dk(  r6| j"                  t        j$                  k(  rt        j                   |d   d      t        j                  |d         r6| j"                  t        j&                  k(  rt        j                   |d   d      	 | j                  j)                  ||      S # t        $ r{}|j                  d   }|t
        k(  r| j                  |      cY d}~S |t        k(  rt        j                  d      |t        k(  r| j                  j                          n Y d}~yd}~ww xY w# t        $ ra}|j                  d   }|t
        k(  r| j                  ||      cY d}~S |t        k(  rt        j                  d      |t        k(  rY d}~y 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)   r1   sendrL   rb   r   writer   r   MessageLengthErrorr   r%   re   r   isIPAddressisIPv6AddressInvalidAddressErrorr8   r^   AF_INETsendto)r+   datagramrh   ri   rj   s        r.   rn   z
Port.write  s    D$"5"56666{{''11 4<<((a1 ..tAw7G},//GO  $$T!W-aM1I$$7//GV  %%d1g.43E3E3W//GI {{))(D99?  	WWQZ;::h//8^223EFF<'MM335 6	@  WWQZ;::h558^223EFF<' sN   E 8G 	G(GGAGG	I$)I I'I ?I  Ic                 F    | j                  dj                  |      |       y)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.
        r/   N)rn   join)r+   seqrh   s      r.   writeSequencezPort.writeSequence@  s     	

388C=$'r/   c                     | j                   rt        d      t        j                  |      s+t        j                  |      st        j                  |d      ||f| _         | j                  j                  ||f       y)z-
        'Connect' to remote server.
        z:already connected, reconnecting is not currently supportednot an IPv4 or IPv6 address.N)	r)   RuntimeErrorr   rp   rq   r   rr   r1   connect)r+   hostr$   s      r.   r}   zPort.connectO  sp     L  ##D)(2H2H2N++D2PQQ#TlT4L)r/   c                     | j                          | j                  r'| j                  j                  d| j                         y y )Nr   )stopReadingrP   r-   	callLaterconnectionLostr?   s    r.   _loseConnectionzPort._loseConnection\  s4    >>LL""1d&9&9: r/   c                 z    | j                   rt        j                         x}| _        nd }| j	                          |S rV   )rP   r   Deferreddr   )r+   results     r.   stopListeningzPort.stopListeninga  s2    >>#nn..FTVFr/   c                 \    t        j                  dt        d       | j                          y )Nz-Please use stopListening() to disconnect portrZ   )
stacklevel)warningswarnDeprecationWarningr   r?   s    r.   loseConnectionzPort.loseConnectioni  s%    ;	

 	r/   c                 h   t        j                  d| j                  z         d| _        d| _        t        j
                  j                  | |       | j                  j                          | j                  j                          | `	| `t        | d      r| j                  j                  d       | `yy)z&
        Cleans up my socket.
        z(UDP Port %s Closed)Nr   )r   rN   r    r[   r   r"   r   r%   doStopr1   closerQ   hasattrr   callback)r+   reasons     r.   r   zPort.connectionLostq  s     	&)=)==>#$$T62KK4FFOOD! r/   c                 N    | j                  | j                        }d|z  | _        y)zP
        Initialize the C{logstr} attribute to be used by C{logPrefix}.
        z%s (UDP)N)rO   r%   logstr)r+   	logPrefixs     r.   r(   zPort.setLogStr  s$     &&t}}5	 9,r/   c                 0   t        j                  | j                        rt        j                  | _        yt        j                  | j                        rt        j                  | _        y| j                  r t        j                  | j                  d      y)z8
        Resolve address family for the socket.
        r{   N)
r   rq   r'   r1   r^   r8   rp   rs   r   rr   r?   s    r.   r*   zPort._setAddressFamily  si     !!$..1!'D!!$..1!'D^^++ >  r/   c                     | j                   S )z0
        Return the prefix to log with.
        )r   r?   s    r.   r   zPort.logPrefix  rC   r/   c                 
   | j                   j                         }| j                  t         j                  k(  rt	        j
                  dg| S | j                  t         j                  k(  rt	        j                  dg|dd  S y)z
        Return the local address of the UDP connection

        @returns: the local address of the UDP connection
        @rtype: L{IPv4Address} or L{IPv6Address}
        UDPNrZ   )r1   r4   r8   rs   r   IPv4Addressr^   IPv6Addressr+   rh   s     r.   getHostzPort.getHost  sq     {{&&(/&&u4t446??2&&u:Ra:: 3r/   c                 v    | j                   j                  t         j                  t         j                  |       y)z
        Set whether this port may broadcast. This is disabled by default.

        @param enabled: Whether the port may broadcast.
        @type enabled: L{bool}
        N)r1   
setsockopt
SOL_SOCKETSO_BROADCAST)r+   enableds     r.   setBroadcastAllowedzPort.setBroadcastAllowed  s&     	v00&2E2EwOr/   c                     t        | j                  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}
        )boolr1   
getsockoptr   r   r?   s    r.   getBroadcastAllowedzPort.getBroadcastAllowed  s,     DKK**6+<+<f>Q>QRSSr/   )     NrV   )&__name__
__module____qualname____doc__r1   rs   r8   
SOCK_DGRAMr3   r[   r    r   int__annotations__r5   r#   classmethodr9   strr@   rB   rG   rE   rF   rk   rn   ry   r}   r   r   r   r   r(   r*   r   r   r   r    r/   r.   r   r   >   s    $ NNM""JM%)OXc])!< ) )V@# @"!)F@<|(*;
 -;PTr/   r   c                   V    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y)MulticastMixinz,
    Implement multicast functionality.
    c                     | j                   j                  t         j                  t         j                        }t        j                  t        j                  d|            S )Nz@i)r1   r   
IPPROTO_IPIP_MULTICAST_IF	inet_ntoastructpack)r+   is     r.   getOutgoingInterfacez#MulticastMixin.getOutgoingInterface  s@    KK""6#4#4f6L6LMD! 455r/   c                 j    | j                   j                  |      j                  | j                        S )zReturns Deferred of success.)r-   resolveaddCallback_setInterfacer   s     r.   setOutgoingInterfacez#MulticastMixin.setOutgoingInterface  s(    ||##D)55d6H6HIIr/   c                     t        j                  |      }| j                   j                  t         j                  t         j                  |       y)NrI   )r1   	inet_atonr   r   r   )r+   rh   r   s      r.   r   zMulticastMixin._setInterface  s7    T"v00&2H2H!Lr/   c                 r    | j                   j                  t         j                  t         j                        S rV   )r1   r   r   IP_MULTICAST_LOOPr?   s    r.   getLoopbackModezMulticastMixin.getLoopbackMode  s%    {{%%f&7&79Q9QRRr/   c                     t        j                  dt        |            }| j                  j	                  t        j
                  t        j                  |       y )Nb)r   r   r   r1   r   r   r   )r+   modes     r.   setLoopbackModezMulticastMixin.setLoopbackMode  s8    {{3T
+v00&2J2JDQr/   c                 r    | j                   j                  t         j                  t         j                        S rV   )r1   r   r   IP_MULTICAST_TTLr?   s    r.   getTTLzMulticastMixin.getTTL  s%    {{%%f&7&79P9PQQr/   c                     t        j                  d|      }| j                  j                  t        j                  t        j
                  |       y )NB)r   r   r1   r   r   r   )r+   ttls     r.   setTTLzMulticastMixin.setTTL  s4    kk#s#v00&2I2I3Or/   c                 n    | j                   j                  |      j                  | j                  |d      S )z4Join a multicast group. Returns Deferred of success.rI   r-   r   r   
_joinAddr1r+   rh   r'   s      r.   	joinGroupzMulticastMixin.joinGroup  +    ||##D)55dooyRSTTr/   c                 n    | j                   j                  |      j                  | j                  ||      S rV   )r-   r   r   
_joinAddr2)r+   rh   r'   rw   s       r.   r   zMulticastMixin._joinAddr1  s+    ||##I.::4??DRVWWr/   c                    t        j                  |      }t        j                  |      }|rt         j                  }nt         j                  }	 | j                   j	                  t         j
                  |||z          y # t        $ r>}t        j                  t        j                  ||g|j                         cY d }~S d }~ww xY wrV   )r1   r   IP_ADD_MEMBERSHIPIP_DROP_MEMBERSHIPr   r   rL   r   Failurer   MulticastJoinErrorrb   )r+   r'   rh   rw   cmdes         r.   r   zMulticastMixin._joinAddr2  s    %$$Y/	**C++C	WKK""6#4#4c4);KL 	W??5#;#;D)#Uaff#UVV	Ws   .A> >	C3C :C Cc                 n    | j                   j                  |      j                  | j                  |d      S )z2Leave multicast group, return Deferred of success.r   r   r   s      r.   
leaveGroupzMulticastMixin.leaveGroup  r   r/   N)r   )r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r/   r.   r   r     sG    6J
SRRPUX
WUr/   r   c                   &    e Zd ZdZ	 	 	 	 ddZd Zy)MulticastPortz.
    UDP Port that supports multicasting.
    Nc                 F    t         j                  | |||||       || _        y)zX
        @see: L{twisted.internet.interfaces.IReactorMulticast.listenMulticast}
        N)r   r#   listenMultiple)r+   r$   r,   r'   r&   r-   r   s          r.   r#   zMulticastPort.__init__  s"     	dD%M7K,r/   c                    t         j                  |       }| j                  rq|j                  t        j
                  t        j                  d       t        t        d      r2	 |j                  t        j
                  t        j                  d       |S |S # t        $ r }|j                  t        k(  rn Y d }~|S d }~ww xY w)NrI   SO_REUSEPORT)r   rJ   r   r   r1   r   SO_REUSEADDRr   r   rL   errnor   rR   s      r.   rJ   z"MulticastPort.createInternetSocket  s    ''-NN6,,f.A.A1Ev~.NN6#4#4f6I6I1M 
s
  xx;.  
s   "/B 	B>B99B>)r   r   NF)r   r   r   r   r#   rJ   r   r/   r.   r   r     s     -r/   r   ).r   r1   r   r   typingr   zope.interfacer   twisted.python.runtimer   r   r   r   r	   r
   r   r   r   r   r   r   rc   rd   r   r   r   r   r   twisted.internetr   r   r   r   r   r   twisted.pythonr   r   IListeningPortIUDPTransportISystemHandler"   r   r   IMulticastTransportr   r   r/   r.   <module>r      s  
     & /7$$   #NKP)=,U H"LFEUU %5& O N ' z779Q9QwT4== wTwTt5U 5Up Z++,!ND ! -!r/   