o
    >h1                     @  s  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rlddl$m%Z% eeej&ej'ej(G dd dej)Z*eej+G dd dee*Z,dS )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                   @  s   e Zd ZU dZded< ejZejZ	dZ
dZded< 				dCdDddZdd ZdEddZdd Zdd ZdFdd Zd!d" Zd#d$ Zd%d& Zd'd( Zd)d* ZdGd+d,Zd-d. Zd/d0 Zd1d2 Zd3d4 Zd5d6 ZdGd7d8Zd9d: Zd;d< Zd=d> Z d?d@ Z!dAdB Z"dS )H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]_realPortNumber     portintprotor   	interfacestrmaxPacketSizeIOCPReactor | NonereturnNonec                 C  sx   || _ || _|| _|| _|   d| _|   tj	| | t

| j| j}t| }t|| _ttd| _dS )z>
        Initialize with a numeric port to listen on.
        Ni)r   protocolreadBufferSizer   	setLogStr_connectedAddr_setAddressFamilyr   
FileHandle__init__socketaddressFamily
socketType_iocp
maxAddrLenfileno	bytearrayaddressBufferstructcalcsizeaddressLengthBuffer)selfr   r   r   r    r   sktaddrLen r:   /var/www/vedio/testing/chatpythonscript.ninositsolution.com/env/lib/python3.10/site-packages/twisted/internet/iocpreactor/udp.pyr+   :   s   
zPort.__init__c                 C  sD   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.
        znot an IPv4 or IPv6 addressN)	r   r   r,   AF_INET6r-   r   AF_INETr   InvalidAddressErrorr7   r:   r:   r;   r)   U   s   

zPort._setAddressFamilyc                 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__b   s   
zPort.__repr__c                 C     | j S )z)
        Return a socket object.
        )r,   r?   r:   r:   r;   	getHandleh      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;   startListeningn   s   zPort.startListeningsocket.socketc                 C  s   | j | j| jS N)r   createSocketr-   r.   r?   r:   r:   r;   rL   x   s   zPort.createSocketc              
   C  s   z|   }|| j| jf W n ty$ } z	t| j| j|d }~ww | d | _t	
d| | j| jf  d| _|| _| jj| _d S )N   z%s starting on %sT)rL   bindr   r   OSErrorr   CannotListenErrorgetsocknamer   r   msg_getLogPrefixr%   	connectedr,   r1   getFileHandle)r7   r8   ler:   r:   r;   rG   {   s    zPort._bindSocketc                 C  s$   | j |  |   | j|  d S rK   )r%   makeConnectionstartReadingr   addActiveHandler?   r:   r:   r;   rH      s   zPort._connectToProtocolc                 C  s$   | j r| ||| |   d S d S rK   )reading
handleReaddoReadr7   rcdataevtr:   r:   r;   cbRead   s   zPort.cbReadc                 C  s   |t jt jttfv r| jr| j  d S d S |r(t	dt j
|d|f  d S z| jt|jd | t|j W d S  tyK   t  Y d S w )Nzerror in recvfrom -- %s (%s)zunknown error)errnoWSAECONNREFUSEDWSAECONNRESETr   r   r(   r%   connectionRefusedr   rR   	errorcodegetdatagramReceivedbytesbuffr/   makesockaddr	addr_buffBaseExceptionerrr]   r:   r:   r;   r[      s,   
zPort.handleReadc                 C  s~   t | j| }| jd  |_}| j |_}| j |_}t 	| 
 ||||\}}|r;|tkr=| jd| j||| d S d S d S Nr   )r/   Eventra   _readBuffersrj   r3   rl   r6   addr_len_buffrecvfromrU   r   r   	callLater)r7   r`   rj   rl   rr   r^   r_   r:   r:   r;   r\      s   zPort.doReadc              
   C  s  | j rW|d| j fv sJ z| j|W S  tyV } z7|jd }|tjkr0| |W  Y d}~S |tjkr:t	
d|tjtjttfv rJ| j  n W Y d}~dS d}~ww |dks]J t|d swt|d sw|d dkrwt	|d dt|d r| jtjkrt	|d dt|d r| jtjkrt	|d dz| j||W S  ty } z2|jd }|tjkr| ||W  Y d}~S |tjkrt	
d|tjtjttfv rW Y d}~dS  d}~w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   argsrb   WSAEINTRwriteWSAEMSGSIZEr   MessageLengthErrorrc   rd   r   r   r%   re   r   r   r>   r-   r<   r=   sendto)r7   datagramaddrsenor:   r:   r;   rx      sp   









	z
Port.writec                 C  s   |  d|| d S )N    )rx   join)r7   seqr}   r:   r:   r;   writeSequence  s   zPort.writeSequencec                 C  sH   | 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 (talk to itamar if you want this)znot an IPv4 or IPv6 address.N)r(   RuntimeErrorr   r   r   r>   r,   connect)r7   hostr   r:   r:   r;   r     s   
zPort.connectc                 C  s2   |    | j|  | jr| jd| j d S d S ro   )stopReadingr   removeActiveHandlerT   rt   connectionLostr?   r:   r:   r;   _loseConnection  s
   zPort._loseConnectionc                 C  s&   | j rt  }| _nd }|   |S rK   )rT   r   Deferreddr   )r7   resultr:   r:   r;   stopListening  s
   zPort.stopListeningc                 C  s   t jdtdd |   d S )Nz-Please use stopListening() to disconnect port   )
stacklevel)warningswarnDeprecationWarningr   r?   r:   r:   r;   loseConnection!  s   zPort.loseConnectionc                 C  sb   t d| j  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   rR   r   r   r*   r   r%   doStopr,   closerU   hasattrr   callback)r7   reasonr:   r:   r;   r   )  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)rS   r%   logstr)r7   	logPrefixr:   r:   r;   r'   8  s   zPort.setLogStrc                 C  rD   )zK
        Returns the name of my class, to prefix log entries with.
        )r   r?   r:   r:   r;   r   ?  rF   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}
        UDPNr   )r,   rQ   r-   r=   r   IPv4Addressr<   IPv6Address)r7   r}   r:   r:   r;   getHostE  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)r7   enabledr:   r:   r;   setBroadcastAllowedR  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   N)r   r   r   r   r   r   r    r   r   r!   r"   r#   )r"   r   r"   rJ   rK   )#__name__
__module____qualname____doc____annotations__r,   r=   r-   
SOCK_DGRAMr.   dynamicReadBuffersr   r+   r)   rC   rE   rI   rL   rG   rH   ra   r[   r\   rx   r   r   r   r   r   r   r'   r   r   r   r   r:   r:   r:   r;   r   #   sB   
 



A
	r   c                   @  s.   e Zd ZdZ				ddddZdddZdS )MulticastPortz.
    UDP Port that supports multicasting.
    r   r   NFr   r   r   r   r   r   r    r   r!   listenMultipler   r"   r#   c                 C  s   t | ||||| || _d S rK   )r   r+   r   )r7   r   r   r   r    r   r   r:   r:   r;   r+   k  s   	
zMulticastPort.__init__rJ   c                 C  sB   t | }| jr|tjtjd ttdr|tjtjd |S )NrM   SO_REUSEPORT)	r   rL   r   r   r,   r   SO_REUSEADDRr   r   )r7   r8   r:   r:   r;   rL   w  s   

zMulticastPort.createSocket)r   r   NF)r   r   r   r   r   r   r    r   r   r!   r   r   r"   r#   r   )r   r   r   r   r+   rL   r:   r:   r:   r;   r   e  s    r   )-r   
__future__r   rb   r,   r4   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:   r:   r:   r;   <module>   s:     >