o
    Òó·iˆ1  ã                   @  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   ÚprotocolZreadBufferSizer   Ú	setLogStrÚ_connectedAddrÚ_setAddressFamilyr   Ú
FileHandleÚ__init__ÚsocketÚaddressFamilyÚ
socketTypeÚ_iocpZ
maxAddrLenÚfilenoÚ	bytearrayÚaddressBufferÚstructÚcalcsizeÚaddressLengthBuffer)Úselfr   r   r   r    r   ÚsktZaddrLen© r7   úfC:\Users\psant\Downloads\PAF backend\school\venv\Lib\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©r5   r7   r7   r8   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<   r7   r7   r8   Ú__repr__b   s   
zPort.__repr__c                 C  ó   | j S )z)
        Return a socket object.
        N)r+   r<   r7   r7   r8   Ú	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<   r7   r7   r8   ÚstartListeningn   s   zPort.startListeningúsocket.socketc                 C  s   | j  | j| j¡S ©N)r   ÚcreateSocketr,   r-   r<   r7   r7   r8   rI   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)rI   Úbindr   r   ÚOSErrorr   ZCannotListenErrorÚgetsocknamer   r   ÚmsgÚ_getLogPrefixr%   Ú	connectedr+   r/   ÚgetFileHandle)r5   r6   Úler7   r7   r8   rD   {   s    €ÿÿÿzPort._bindSocketc                 C  s$   | j  | ¡ |  ¡  | j | ¡ d S rH   )r%   ZmakeConnectionZstartReadingr   ZaddActiveHandler<   r7   r7   r8   rE   �   s   zPort._connectToProtocolc                 C  s$   | j r|  |||¡ |  ¡  d S d S rH   )ÚreadingÚ
handleReadÚdoRead©r5   ÚrcÚdataÚevtr7   r7   r8   Ú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   rN   Ú	errorcodeÚgetZdatagramReceivedÚbytesÚbuffr.   ZmakesockaddrÚ	addr_buffÚBaseExceptionÚerrrV   r7   r7   r8   rT   ™   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.   ÚEventrZ   Z_readBuffersrb   r1   rc   r4   Úaddr_len_buffÚrecvfromrQ   r   r   Ú	callLater)r5   rY   rb   rc   rh   rW   rX   r7   r7   r8   rU   ¯   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r‹t	 |d d¡‚t|d ƒrŸ| jtjkrŸt	 |d d¡‚z| j ||¡W S  tyå } z2|jd }|tjkrÅ|  ||¡W  Y d}~S |tjkrÏt	 
d¡‚|tjtjttfv ràW 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+   ÚsendrL   Úargsr[   ZWSAEINTRÚwriteZWSAEMSGSIZEr   ZMessageLengthErrorr\   r]   r   r   r%   r^   r   r   r;   r,   r9   r:   Úsendto)r5   ZdatagramÚaddrÚseÚnor7   r7   r8   rm   Á   sr   



üþ€ô
ÿ
þ
ýÿÿÿ



ü	€ïz
Port.writec                 C  s   |   d |¡|¡ d S )Nó    )rm   Újoin)r5   Úseqro   r7   r7   r8   Ú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)r5   Úhostr   r7   r7   r8   rw     s   ÿ
zPort.connectc                 C  s2   |   ¡  | j | ¡ | jr| j d| j¡ d S d S rf   )ZstopReadingr   ZremoveActiveHandlerP   rj   ÚconnectionLostr<   r7   r7   r8   Ú_loseConnection  s
   ÿzPort._loseConnectionc                 C  s&   | j rt ¡  }| _nd }|  ¡  |S rH   )rP   r   ZDeferredÚdrz   )r5   Úresultr7   r7   r8   Ú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<   r7   r7   r8   Ú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   rN   r   r   r)   ry   r%   ZdoStopr+   ÚcloserQ   Úhasattrr{   Úcallback)r5   Úreasonr7   r7   r8   ry   )  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)rO   r%   Úlogstr)r5   Ú	logPrefixr7   r7   r8   r&   8  s   zPort.setLogStrc                 C  rA   )zK
        Returns the name of my class, to prefix log entries with.
        N)rˆ   r<   r7   r7   r8   r‰   ?  rC   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}
        ZUDPNr~   )r+   rM   r,   r:   r   ÚIPv4Addressr9   ÚIPv6Address)r5   ro   r7   r7   r8   Ú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)r5   Úenabledr7   r7   r8   Ú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}
        N)Úboolr+   Ú
getsockoptrŽ   r�   r<   r7   r7   r8   ÚgetBroadcastAllowed[  s   zPort.getBroadcastAllowed)r   r   N)r   r   r   r   r   r   r    r   r   r!   r"   r#   )r"   r   ©r"   rG   rH   )#Ú__name__Ú
__module__Ú__qualname__Ú__doc__Ú__annotations__r+   r:   r,   Ú
SOCK_DGRAMr-   ZdynamicReadBuffersr   r*   r(   r@   rB   rF   rI   rD   rE   rZ   rT   rU   rm   ru   rw   rz   r}   rƒ   ry   r&   r‰   rŒ   r‘   r”   r7   r7   r7   r8   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 rH   )r   r*   r�   )r5   r   r   r   r    r   r�   r7   r7   r8   r*   k  s   	
zMulticastPort.__init__rG   c                 C  sB   t  | ¡}| jr| tjtjd¡ ttdƒr| tjtjd¡ |S )NrJ   ÚSO_REUSEPORT)	r   rI   r�   r�   r+   rŽ   ÚSO_REUSEADDRr…   rž   )r5   r6   r7   r7   r8   rI   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*   rI   r7   r7   r7   r8   rœ   e  s    ùrœ   )-r™   Ú
__future__r   r[   r+   r2   r€   Útypingr   r   Zzope.interfacer   Ztwisted.internetr   r   r   r	   Ztwisted.internet._multicastr
   Ztwisted.internet.abstractr   r   Ztwisted.internet.iocpreactorr   r   r.   Z"twisted.internet.iocpreactor.constr   r   r   Z'twisted.internet.iocpreactor.interfacesr   Ztwisted.internet.protocolr   Ztwisted.pythonr   Z$twisted.internet.iocpreactor.reactorr   ZIListeningPortZIUDPTransportZISystemHandler)   r   ZIMulticastTransportrœ   r7   r7   r7   r8   Ú<module>   s:   ü  >