
    Vh1                       d Z ddlmZ ddlZddlZddlZddlZddlmZm	Z	 ddl
mZ ddl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mZ dd
lmZmZmZ ddlmZ ddl m!Z! ddl"m#Z# erddl$m%Z%  eeejL                  ejN                  ejP                         G d dejR                               Z* eejV                         G d dee*             Z,y)z
UDP support for IOCP reactor
    )annotationsN)TYPE_CHECKINGOptional)implementer)addressdefererror
interfaces)MulticastMixin)isIPAddressisIPv6Address)abstractiocpsupport)ERROR_CONNECTION_REFUSEDERROR_IO_PENDINGERROR_PORT_UNREACHABLE)IReadWriteHandle)AbstractDatagramProtocol)log)IOCPReactorc                     e Zd ZU dZded<   ej                  Zej                  Z	dZ
dZded<   	 	 	 d	 	 	 	 	 	 	 	 	 	 	 d dZd	 Zd!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#dZd Zd Zd Z d Z!d Z"y)$Portz
    UDP port, listening for packets.

    @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.
    r   reactorFNzOptional[int]_realPortNumberc                   || _         || _        || _        || _        | j	                          d| _        | j                          t        j                  j                  | |       t        j                  | j                  | j                        }t        j                  |j                               }t!        |      | _        t!        t%        j&                  d            | _        y)z>
        Initialize with a numeric port to listen on.
        Ni)portprotocolreadBufferSize	interface	setLogStr_connectedAddr_setAddressFamilyr   
FileHandle__init__socketaddressFamily
socketType_iocp
maxAddrLenfileno	bytearrayaddressBufferstructcalcsizeaddressLengthBuffer)selfr   protor    maxPacketSizer   sktaddrLens           P/home/dcms/DCMS/lib/python3.12/site-packages/twisted/internet/iocpreactor/udp.pyr%   zPort.__init__:   s     	+"" $$T73mmD..@""3::<0&w/#,V__S-A#B     c                   t        | j                        rt        j                  | _        yt        | j                        rt        j                  | _        y| j                  r t        j                  | j                  d      y)z8
        Resolve address family for the socket.
        znot an IPv4 or IPv6 addressN)	r   r    r&   AF_INET6r'   r   AF_INETr	   InvalidAddressErrorr1   s    r6   r#   zPort._setAddressFamilyU   s]     (!'D(!'D^^++ =  r7   c                    | j                   'd| j                  j                   d| j                    dS d| j                  j                   dS )N<z on >z not connected>)r   r   	__class__r<   s    r6   __repr__zPort.__repr__b   sO    +t}}../tD4H4H3IKKt}}../??r7   c                    | j                   S )z)
        Return a socket object.
        )r&   r<   s    r6   	getHandlezPort.getHandleh        {{r7   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    r6   startListeningzPort.startListeningn   s     	!r7   c                b    | j                   j                  | j                  | j                        S N)r   createSocketr'   r(   r<   s    r6   rK   zPort.createSocketx   s#    ||((););T__MMr7   c                   	 | j                         }|j                  | j                  | j                  f       |j                         d   | _        t        j                  | j                  | j                        d| j                         d| _        || _        | j                  j                  | _        y # t        $ r0}t        j                  | j                  | j                  |      d }~ww xY w)N   z starting on T)rK   bindr    r   OSErrorr	   CannotListenErrorgetsocknamer   r   msg_getLogPrefixr   	connectedr&   r+   getFileHandle)r1   r4   les      r6   rF   zPort._bindSocket{   s    	I##%CHHdnndii01  #03!!$--0$2F2FH	

 ![[//  	I))$..$))RHH	Is   7B8 8	C1+C,,C1c                    | j                   j                  |        | j                          | j                  j	                  |        y rJ   )r   makeConnectionstartReadingr   addActiveHandler<   s    r6   rG   zPort._connectToProtocol   s2    $$T*$$T*r7   c                d    | j                   r$| j                  |||       | j                          y y rJ   )reading
handleReaddoReadr1   rcdataevts       r6   cbReadzPort.cbRead   s'    <<OOBc*KKM r7   c                   |t         j                  t         j                  t        t        fv r(| j
                  r| j                  j                          y y |r;t        j                  dt         j                  j                  |d      d|d       y 	 | j                  j                  t        |j                  d |       t        j                   |j"                               y # t$        $ r t        j&                          Y y w xY w)Nzerror in recvfrom -- zunknown errorz ())errnoWSAECONNREFUSEDWSAECONNRESETr   r   r"   r   connectionRefusedr   rR   	errorcodegetdatagramReceivedbytesbuffr)   makesockaddr	addr_buffBaseExceptionerrr_   s       r6   r]   zPort.handleRead   s    !!$"	
 
 ""//1 #GG??&&r?;RA
..#((5D/*E,>,>s}},M ! 	s   AC# #DDc                |   t        j                  | j                  |       }| j                  d   x|_        }| j
                  x|_        }| j                  x|_        }t        j                  | j                         ||||      \  }}|r4|t        k7  r*| j                  j                  d| j                  |||       y y y Nr   )r)   Eventrc   _readBuffersrn   r-   rp   r0   addr_len_buffrecvfromrU   r   r   	callLater)r1   rb   rn   rp   rw   r`   ra   s          r6   r^   zPort.doRead   s    kk$++t,++A..4$($6$66	,0,D,DDM>> $	=#
D "(( LL""1dkk2tSA )2r7   c                   | j                   r.|d| j                   fv sJ 	 | j                  j                  |      S |dk7  sJ t#        |d         s/t%        |d         s!|d   dk7  rt        j&                  |d   d      t#        |d         r6| j(                  t        j*                  k(  rt        j&                  |d   d      t%        |d         r6| j(                  t        j,                  k(  rt        j&                  |d   d      	 | j                  j/                  ||      S # t        $ r}|j                  d   }|t
        j                  k(  r| j                  |      cY d}~S |t
        j                  k(  rt        j                  d      |t
        j                  t
        j                  t        t        fv r| j                  j!                          n Y d}~yd}~ww xY w# t        $ r}|j                  d   }|t
        j                  k(  r| j                  ||      cY d}~S |t
        j                  k(  rt        j                  d      |t
        j                  t
        j                  t        t        fv rY d}~y d}~ww xY w)z~
        Write a datagram.

        @param addr: should be a tuple (ip, port), can be None in connected
        mode.
        Nr   zmessage too longz<broadcast>z0write() only accepts IP addresses, not hostnamesz*IPv6 port write() called with IPv4 addressz*IPv4 port write() called with IPv6 address)r"   r&   sendrO   argsrf   WSAEINTRwriteWSAEMSGSIZEr	   MessageLengthErrorrg   rh   r   r   r   ri   r   r   r;   r'   r9   r:   sendto)r1   datagramaddrsenos        r6   r~   z
Port.write   sF    D$"5"56666{{''11" 4<<Q(%d1g.G},//GO  47#(:(:foo(M//GI  T!W%$*<*<*N//GI {{))(D99E  WWQZ'::h//5,,,223EFF))'',*	  MM335 6F  WWQZ'::h555,,,223EFF))'',*	  #sO   D$ G" $	G-2GG%A0GG"	J+3I>J$AI>=I>>Jc                F    | j                  dj                  |      |       y )Nr7   )r~   join)r1   seqr   s      r6   writeSequencezPort.writeSequence  s    

388C=$'r7   c                    | j                   rt        d      t        |      s!t        |      st	        j
                  |d      ||f| _         | j                  j                  ||f       y)z-
        'Connect' to remote server.
        z\already connected, reconnecting is not currently supported (talk to itamar if you want this)znot an IPv4 or IPv6 address.N)r"   RuntimeErrorr   r   r	   r;   r&   connect)r1   hostr   s      r6   r   zPort.connect  sf     4  4 t)<++D2PQQ#TlT4L)r7   c                    | j                          | j                  j                  |        | j                  r'| j                  j	                  d| j
                         y y rt   )stopReadingr   removeActiveHandlerT   ry   connectionLostr<   s    r6   _loseConnectionzPort._loseConnection  sF    ''->>LL""1d&9&9: r7   c                z    | j                   rt        j                         x}| _        nd }| j	                          |S rJ   )rT   r   Deferreddr   )r1   results     r6   stopListeningzPort.stopListening  s2    >>#nn..FTVFr7   c                \    t        j                  dt        d       | j                          y )Nz-Please use stopListening() to disconnect port   )
stacklevel)warningswarnDeprecationWarningr   r<   s    r6   loseConnectionzPort.loseConnection!  s%    ;	

 	r7   c                Z   t        j                  d| j                  z         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   rR   r   r   r$   r   r   doStopr&   closerU   hasattrr   callback)r1   reasons     r6   r   zPort.connectionLost)  s     	&)=)==>#**48K4FFOOD! r7   c                N    | j                  | j                        }d|z  | _        y)zP
        Initialize the C{logstr} attribute to be used by C{logPrefix}.
        z%s (UDP)N)rS   r   logstr)r1   	logPrefixs     r6   r!   zPort.setLogStr8  s$     &&t}}5	 9,r7   c                    | j                   S )zK
        Returns the name of my class, to prefix log entries with.
        )r   r<   s    r6   r   zPort.logPrefix?  rD   r7   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}
        UDPNr   )r&   rQ   r'   r:   r   IPv4Addressr9   IPv6Address)r1   r   s     r6   getHostzPort.getHostE  sq     {{&&(/&&u4t446??2&&u:Ra:: 3r7   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)r&   
setsockopt
SOL_SOCKETSO_BROADCAST)r1   enableds     r6   setBroadcastAllowedzPort.setBroadcastAllowedR  s&     	v00&2E2EwOr7   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}
        )boolr&   
getsockoptr   r   r<   s    r6   getBroadcastAllowedzPort.getBroadcastAllowed[  s,     DKK**6+<+<f>Q>QRSSr7   )     N)r   intr2   r   r    strr3   r   r   IOCPReactor | NonereturnNone)r   r   r   zsocket.socketrJ   )#__name__
__module____qualname____doc____annotations__r&   r:   r'   
SOCK_DGRAMr(   dynamicReadBuffersr   r%   r#   rA   rC   rH   rK   rF   rG   rc   r]   r^   r~   r   r   r   r   r   r   r!   r   r   r   r    r7   r6   r   r   #   s     NNM""J &*O]) !&*CC (C 	C
 C $C 
C6@"N0(+

,B$?B(*;-;PTr7   r   c                  D    e Zd ZdZ	 	 	 	 d	 	 	 	 	 	 	 	 	 	 	 	 	 ddZddZy)MulticastPortz.
    UDP Port that supports multicasting.
    Nc                F    t         j                  | |||||       || _        y rJ   )r   r%   listenMultiple)r1   r   r2   r    r3   r   r   s          r6   r%   zMulticastPort.__init__k  s"     	dD%M7K,r7   c                $   t         j                  |       }| j                  rn|j                  t        j
                  t        j                  d       t        t        d      r/|j                  t        j
                  t        j                  d       |S )NrM   SO_REUSEPORT)	r   rK   r   r   r&   r   SO_REUSEADDRr   r   )r1   r4   s     r6   rK   zMulticastPort.createSocketw  sb    %NN6,,f.A.A1Ev~.v00&2E2EqI
r7   )r   r   NF)r   r   r2   r   r    r   r3   r   r   r   r   r   r   r   r   )r   r   r   r   r%   rK   r   r7   r6   r   r   e  sc     !&*$
-
- (
- 	
-
 
- $
- 
- 

-r7   r   )-r   
__future__r   rf   r&   r.   r   typingr   r   zope.interfacer   twisted.internetr   r   r	   r
   twisted.internet._multicastr   twisted.internet.abstractr   r   twisted.internet.iocpreactorr   r   r)   "twisted.internet.iocpreactor.constr   r   r   'twisted.internet.iocpreactor.interfacesr   twisted.internet.protocolr   twisted.pythonr   $twisted.internet.iocpreactor.reactorr   IListeningPortIUDPTransportISystemHandler$   r   IMulticastTransportr   r   r7   r6   <module>r      s    #     * & > > 6 @ G 
 E > @ 	yT8 yTyTx	 Z++,ND  -r7   