
    Vh}w                       d Z ddlmZ ddlZddlmZmZmZmZm	Z	m
Z
mZmZmZmZmZ ddlmZ ddlmZmZmZmZ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"m#Z#m$Z$ ddl%m&Z& ddl'm(Z( ddl)m*Z* ddl+m,Z,m-Z-  G d d      Z. G d de.ej^                        Z0 G d de.ejb                        Z2 G d de0      Z3 G d de4      Z5 G d dej^                        Z6 e ejn                  ed       d       G d de-             Z8 e ejn                  ed       d       G d de-             Z9	 	 	 	 	 	 	 	 	 	 	 	 d,d Z: e ejF                  ed       d!       e e:eeed"d#       d$       G d% d&e-                    Z; e ejF                  ed       d!      e* e e:ee	e
d'd(       d)       G d* d+e;                           Z<y)-zG
Tests for implementations of L{IReactorUDP} and L{IReactorMulticast}.
    )annotationsN)AF_INETAF_INET6IP_ADD_MEMBERSHIP
IPPROTO_IPIPPROTO_IPV6IPV6_JOIN_GROUP
SOCK_DGRAMAddressFamilyif_nameindex	inet_ptonsocket)skipIf)defererror
interfacesprotocolreactorudp)IPv4AddressIPv6Address)DeferredgatherResultsmaybeDeferred)MulticastJoinError)IMulticastTransportIReactorMulticastIReactorTime)
deferLater)runtime)skipWithoutIPv6)SkipTestTestCasec                  *    e Zd ZdZdZdZd Zd Zd Zy)Mixinr   Nc                    g | _         y N)packetsselfs    E/home/dcms/DCMS/lib/python3.12/site-packages/twisted/test/test_udp.py__init__zMixin.__init__0   s	        c                v    d| _         | j                  &| j                  d c}| _        |j                  d        y y N   )startedstartedDeferredcallbackr*   ds     r+   startProtocolzMixin.startProtocol3   s;    +&*&:&:D#At#JJt ,r-   c                    d| _         y r/   )stoppedr)   s    r+   stopProtocolzMixin.stopProtocol9   s	    r-   )	__name__
__module____qualname__r1   r8   r2   r,   r6   r9    r-   r+   r%   r%   *   s     GGOr-   r%   c                  0    e Zd ZU dZded<   dZded<   d Zy)ServerNzDeferred[None] | NonepacketReceivedr   r   	transportc                    | j                   j                  ||f       | j                  &| j                  d c}| _        |j                  d        y y r'   r(   appendr@   r3   )r*   dataaddrr5   s       r+   datagramReceivedzServer.datagramReceivedB   sJ    T4L)*%)%8%8$"At"JJt +r-   )r:   r;   r<   r@   __annotations__refusedrG   r=   r-   r+   r?   r?   =   s    ,0N)0G""r-   r?   c                  &    e Zd ZdZdZd Zd Zd Zy)ClientNr   c                    | j                   j                  |       | j                  &| j                  d c}| _        |j                  d        y y r'   rC   )r*   rE   r5   s      r+   rG   zClient.datagramReceivedM   sF    D!*%)%8%8$"At"JJt +r-   c                t    | j                   %| j                   d c}| _         |j                  |       || _        y r'   )r2   errbackfailure)r*   rO   r5   s      r+   connectionFailedzClient.connectionFailedS   s6    +&*&:&:D#At#IIgr-   c                    | j                   8| j                   d c}| _         |j                  t        j                  d             d| _        y Nyupr0   r2   rN   r   ConnectionRefusedErrorrI   r4   s     r+   connectionRefusedzClient.connectionRefusedY   A    +&*&:&:D#At#IIe2259:r-   )r:   r;   r<   r@   rI   rG   rP   rV   r=   r-   r+   rK   rK   I   s    NGr-   rK   c                      e Zd Zd Zy)
GoodClientc                    | j                   8| j                   d c}| _         |j                  t        j                  d             d| _        y rR   rT   r4   s     r+   rV   zGoodClient.connectionRefuseda   rW   r-   N)r:   r;   r<   rV   r=   r-   r+   rY   rY   `   s    r-   rY   c                      e Zd ZdZy)BadClientErrorzf
    Raised by BadClient at the end of every datagramReceived call to try and
    screw stuff up.
    N)r:   r;   r<   __doc__r=   r-   r+   r\   r\   h   s    r-   r\   c                       e Zd ZdZdZd Zd Zy)	BadClientz
    A DatagramProtocol which always raises an exception from datagramReceived.
    Used to test error handling behavior in the reactor for that method.
    Nc                    || _         y)ze
        Set the Deferred which will be called back when datagramReceived is
        called.
        N)r5   r4   s     r+   setDeferredzBadClient.setDeferredw   s    
 r-   c                z    | j                   %| j                   d c}| _         |j                  |       t        d      )NzApplication code is very buggy!)r5   r3   r\   )r*   bytesrF   r5   s       r+   rG   zBadClient.datagramReceived~   s5    66IAtvJJu>??r-   )r:   r;   r<   r]   r5   ra   rG   r=   r-   r+   r_   r_   o   s    
 	A@r-   r_   !This reactor does not support UDPc                      e Zd Zd Zd Zd Zd Zd Z ee	j                  j                  d      dk(  d      d	        Zd
 Zd Zd Zd Zy)UDPTestsc                     t               }t        j                         x}|_        t	        j
                  d|d       fd}|j                  |      S )zu
        The C{type} of the host address of a listening L{DatagramProtocol}'s
        transport is C{"UDP"}.
        r   	127.0.0.1	interfacec                |    j                         }j                  |j                  d       j                         S )NUDP)getHostassertEqualtypestopListening)ignoredrF   pr*   s     r+   	cbStartedz+UDPTests.test_oldAddress.<locals>.cbStarted   s/    99;DTYY.??$$r-   r?   r   r   r2   r   	listenUDPaddCallback)r*   serverr5   rs   rr   s   `   @r+   test_oldAddresszUDPTests.test_oldAddress   sJ    
 %*^^%55F"a;?	%
 }}Y''r-   c                     t               t        j                         x}_        t	        j
                  dd       fd} fd}|j                  |      j                  |      S )z
        The L{DatagramProtocol}'s C{startProtocol} and C{stopProtocol}
        methods are called when its transports starts and stops listening,
        respectively.
        r   rh   ri   c                    j                  j                  d       j                  j                  d       j                         S )Nr0   r   )rn   r1   r8   rp   )rq   port1r*   rw   s    r+   rs   z*UDPTests.test_startStop.<locals>.cbStarted   s:    V^^Q/V^^Q/&&((r-   c                >    j                  j                  d       y r/   )rn   r8   )rq   r*   rw   s    r+   	cbStoppedz*UDPTests.test_startStop.<locals>.cbStopped   s    V^^Q/r-   rt   )r*   r5   rs   r}   r{   rw   s   `   @@r+   test_startStopzUDPTests.test_startStop   sZ     %*^^%55F"!!!V{C	)
	0 }}Y'33I>>r-   c                    t               t        j                         x}_        t	        j
                  dd      }d fd}|j                  |      S )zr
        Re-listening with the same L{DatagramProtocol} re-invokes the
        C{startProtocol} callback.
        r   rh   ri   c                "    |j                         S r'   rp   rq   ports     r+   rs   z'UDPTests.test_rebind.<locals>.cbStarted   s    %%''r-   c                    t        j                         x}_        t        j                  dd      }|j                  |      S Nr   rh   ri   )r   r   r2   r   ru   rv   )rq   r5   rr   rs   rw   s      r+   r}   z'UDPTests.test_rebind.<locals>.cbStopped   s<    ).)99A&!!!V{CA==A..r-   rt   )r*   r5   rr   r}   rs   rw   s       @@r+   test_rebindzUDPTests.test_rebind   sQ    
 %*^^%55F"a;?	(	/
 }}Y**r-   c                     t               t        j                         x}_        t	        j
                  dd       fd}|j                  |       fd}|j                  |       |S )z
        A L{CannotListenError} exception is raised when attempting to bind a
        second protocol instance to an already bound port
        r   rh   ri   c                   j                  j                         j                  j                                t               }j	                  t
        j                  t        j                  j                         j                  |d       y )Nrh   ri   )
rn   rm   rA   r?   assertRaisesr   CannotListenErrorr   ru   r   )rq   server2r   r*   rw   s     r+   rs   z*UDPTests.test_bindError.<locals>.cbStarted   si    T\\^V-=-=-E-E-GHhG''!!##%  r-   c                $    j                         S r'   r   r   s    r+   
cbFinishedz+UDPTests.test_bindError.<locals>.cbFinished   s    %%''r-   rt   )r*   r5   rs   r   r   rw   s   `   @@r+   test_bindErrorzUDPTests.test_bindError   s_    
 %*^^%55F"  FkB		 	
i 	( 	
j!r-   c                   	
 t               
t        j                         x}
_        t	        j
                  d
d      	t               t        j                         x_         fd}|j                  |      }
fd}|j                  |        
fd}|j                  |       	 fd}|j                  |       |S )z
        Datagrams can be sent with the transport's C{write} method and
        received via the C{datagramReceived} callback method.
        r   rh   ri   c                B    t        j                  dd      _        S r   )r   ru   port2)rq   clientclientStartedr*   s    r+   cbServerStartedz2UDPTests.test_sendPackets.<locals>.cbServerStarted   s     **1fLDJ  r-   c                   j                   j                  dj                   j                         j                         j                   j                         }j                   j                         }t	        j
                         x}_        j                   j                  d|j                  |j                  f       ddd|j                  |j                  ffgfdt	        j                   d       |gd      S )	Nrh      hello)   a)   bN   cc                    rVt        j                         x}_        |j                          j                  j
                  j                  d        |S y Nr   )r   r   r@   rv   rA   writepop)rq   nextClientWritecbClientSendr   clientWritesrw   s     r+   r   zHUDPTests.test_sendPackets.<locals>.cbClientStarted.<locals>.cbClientSend   sT    >Cnn>NNOf&;#//=*F$$**L,<,<Q,?@**	  r-   TfireOnOneErrback)
rA   connectrm   r   r   r   r@   r   hostDeferredList)rq   cAddrsAddr
serverSendr   r   r   rw   s       @@r+   cbClientStartedz2UDPTests.test_sendPackets.<locals>.cbClientStarted   s    $$[&2B2B2J2J2L2Q2QR$$,,.E$$,,.E161AAJ.""8ejj%**-EF#\D5::uzz:R3STL+ %%d#Z04 r-   c                R   j                   j                         }j                   j                         }j                  j                  d|j                  |j
                  ffg       |j                  |j
                  f}j                  j                  d|fd|fd|fg       y )Nr   r   r   r   )rA   rm   rn   r(   r   r   )rq   r   r   
clientAddrr   r*   rw   s       r+   cbSendsFinishedz2UDPTests.test_sendPackets.<locals>.cbSendsFinished  s    $$,,.E$$,,.EV^^x%**ejj9Q.R-ST**ejj1J
#dJ%7$
9KLr-   c                    t        j                  t        j                  j                        t        j                  j                  j                        gd      S NTr   )r   r   r   rp   r   )rq   r{   r*   s    r+   r   z-UDPTests.test_sendPackets.<locals>.cbFinished  sL    %%''(;(;<''

(@(@A "& r-   )r?   r   r   r2   r   ru   rY   rv   )r*   serverStartedr   r5   r   r   r   r   r   r{   rw   s   `      @@@@r+   test_sendPacketszUDPTests.test_sendPackets   s    
 161AA.!!!V{C161AA.	! %%o6	0 	
o&	 	
o&	 	
j!r-   INFRASTRUCTUREAZUREPIPELINESz"Hangs on Pipelines due to firewallc                   	 t               t        j                         x}_        t	        j
                  dd      t               	t        j                         x}	_        t	        j
                  d	d      t        j                  ||gd      } 	fd}|j                  |       fd}|j                  |       |S )z
        A L{ConnectionRefusedError} exception is raised when a connection
        attempt is actively refused by the other end.

        Note: This test assumes no one is listening on port 80 UDP.
        r   rh   ri   Tr   c                P   t        j                         x}_        j                  j	                  dd       t        d      D ]A  }j                  j                  d|fz         j                  j                  d|fz  d       C j                  |t        j                        S )Nrh   P   
      %drh   r   )
r   r   r2   rA   r   ranger   assertFailurer   rU   )rq   rV   ir   r*   rw   s      r+   rs   z2UDPTests.test_connectionRefused.<locals>.cbStarted3  s    9>9II 6$$["52Y H  &&ut|4  &&ut|5FGH %%&79U9UVVr-   c                    t        j                  t        j                  j                        t        j                  j                        gd      S r   r   r   r   rp   )rq   r   r   s    r+   r   z3UDPTests.test_connectionRefused.<locals>.cbFinished?  sH    %%''(:(:;''(;(;< "& r-   )	rY   r   r   r2   r   ru   r?   r   rv   )
r*   r   r   r5   rs   r   r   r   r   rw   s
   `     @@@@r+   test_connectionRefusedzUDPTests.test_connectionRefused  s     161AA.  FkB161AA.!!!V{C}=PTU	W 	
i 	 	
j!r-   c                4   	
 t               	t        j                         x}	_        t	        j
                  d	d      
dt               t        j                         x}_        t        j                         x}_        t	        j
                  dd      t        j                  ||gd      }	fd}|j                  |       t        j                  ||gd      } fd}|j                  |       
fd	}|j                  |       |S )
as  
        When a server fails to successfully read a packet the server should
        still be able to process future packets.
        The IOCP reactor had a historical problem where a failure to read caused
        the reactor to ignore any future reads. This test should prevent a regression.

        Note: This test assumes no one is listening on port 80 UDP.
        r   rh   ri   s   Sending test packet to serverTr   c                    j                   j                  dd       j                   j                  dj                  f       y )Ns$   write to port no one is listening tor   rh   )rA   r   _realPortNumber)rq   r   rw   
serverPorttest_data_to_sends    r+   cbClientAndServerStartedzAUDPTests.test_serverReadFailure.<locals>.cbClientAndServerStartedb  sE     ""79J ""!K1K1K#Lr-   c                J    j                  j                  d   d          y r   )rn   r(   )rq   r*   rw   r   s    r+   verify_server_got_dataz?UDPTests.test_serverReadFailure.<locals>.verify_server_got_datau  s"    V^^A.q13DEr-   c                    t        j                  t        j                  j                        t        j                  j                        gd      S r   r   )rq   
clientPortr   s    r+   cleanupz0UDPTests.test_serverReadFailure.<locals>.cleanupz  sH    %%''
(@(@A''
(@(@A "& r-   )
rY   r   r   r2   r   ru   r?   r@   r   rv   )r*   r   r   serverGotDataserver_client_started_dr   all_data_sentr   r   r   r   rw   r   r   s   `        @@@@@r+   test_serverReadFailurezUDPTests.test_serverReadFailureK  s     161AA.&&q&KH
<161AA.050@@-&&q&KH
"'"4"4M*T#
	 	 ++,DE**$m4t
	F 	!!"89	 	!!'*r-   c                b   t               }t        j                  d|d      }| j                  t        j
                  |j                  j                  dd       |j                  j                  dd       | j                  t        |j                  j                  dd       |j                         S )a   
        A call to the transport's connect method fails with an
        L{InvalidAddressError} when a non-IP address is passed as the host
        value.

        A call to a transport's connect method fails with a L{RuntimeError}
        when the transport is already connected.
        r   rh   ri   	localhostr   )
rY   r   ru   r   r   InvalidAddressErrorrA   r   RuntimeErrorrp   )r*   r   r   s      r+   test_badConnectzUDPTests.test_badConnect  s       FkB%%v'7'7'?'?b	
 	  b1,(8(8(@(@+rR!!##r-   c                J   	 t        j                          fd}j                  |       t               t	        j
                  dd      fd}j                  |       j                         t        t        d            g 	 	fd         S )zr
        When datagramReceived raises an exception it is logged but the port
        is not disconnected.
        c                    j                  t              }j                  t        |      ddt        |      fz         y)z
            Flush the exceptions which the reactor should have logged and make
            sure they're actually there.
               z'Incorrectly found %d errors, expected 2N)flushLoggedErrorsr\   rn   len)ignerrsr*   s     r+   cbCompletedz8UDPTests.test_datagramReceivedError.<locals>.cbCompleted  s:    
 )).9DD	1G3t9,Vr-   r   rh   ri   c                h     t        j                  j                        j                   fd      S )z
            Disconnect the port we started and pass on whatever was given to us
            in case it was a Failure.
            c                    S r'   r=   )r   results    r+   <lambda>zHUDPTests.test_datagramReceivedError.<locals>.cbCleanup.<locals>.<lambda>  s    v r-   )r   r   rp   addBoth)r   r   s   `r+   	cbCleanupz6UDPTests.test_datagramReceivedError.<locals>.cbCleanup  s(    
 &&t'9'9:BBCUVVr-   <   c                 ^   s	 
j                  d       
j                  j                  dd       dj                  d      fz  } t        j                         }j                  |       j                  j                  | j                  j                  f       	fd}	fd}|j                  ||       |j                  j                         t        j                  d|j                  t!        j"                  d	            y# t        $ r j                          Y w xY w)
a6  
            Send one packet to the listening BadClient.  Set up a 0.1 second
            timeout to do re-transmits in case the packet is dropped.  When two
            packets have been received by the BadClient, stop sending and let
            the finalDeferred's callbacks do some assertions.
            zNot enough packets receivedNzUDP Protocol lost its transportr   r   c                    j                          j                  |        t              dk(  r"t        j                  dj
                  d       y         y)z
                A packet arrived.  Cancel the timeout for it, record it, and
                maybe finish the test.
                r   r   N)cancelrD   r   r   	callLaterr3   )packetfinalDeferredmakeAttemptsucceededAttemptstimeoutCalls    r+   cbPacketReceivedzRUDPTests.test_datagramReceivedError.<locals>.makeAttempt.<locals>.cbPacketReceived  sL    
 ""$!((0()Q.
 %%a)?)?FMr-   c                             y)a  
                The packet wasn't received quickly enough.  Try sending another
                one.  It doesn't matter if the packet for which this was the
                timeout eventually arrives: makeAttempt throws away the
                Deferred on which this function is the errback, so when
                datagramReceived callbacks, so it won't be on this Deferred, so
                it won't raise an AlreadyCalledError.
                Nr=   )errr   s    r+   ebPacketTimeoutzQUDPTests.test_datagramReceivedError.<locals>.makeAttempt.<locals>.ebPacketTimeout  s
     r-   g?z&Timed out in testDatagramReceivedError)fail	ExceptionrN   failIfIdenticalrA   r   r   r   ra   r   r   r   addCallbacks
addErrbackr   r   r   TimeoutError)r   packetDeferredr   r   r   rF   attemptsr   r   r   r*   r   s       @r+   r   z8UDPTests.test_datagramReceivedError.<locals>.makeAttempt  s    ,II;<     $(I hll1o//F"^^-N~.""6DIItyy+AB" 	 ''(8/J%%m&;&;<!++&&""#KLKU ! ,!))+,s   D D,+D,)
r   r   rv   r_   r   ru   r   rm   listr   )
r*   r   r   rF   r   r   r   r   r   r   s
   `  @@@@@@@r+   test_datagramReceivedErrorz#UDPTests.test_datagramReceivedError  s    
 (	 	!!+.  FkB	W 	i(||~ b	?8	 8	t 	r-   c                     G d d      }t        j                  dt                     } |       |_        |j	                  dd       | j                  | j                  g      }| j                  t        |      d       y)ai  
        C{'<broadcast>'} is an alternative way to say C{'255.255.255.255'}
        ({socket.gethostbyname("<broadcast>")} returns C{'255.255.255.255'}),
        so because it becomes a valid IP address, no deprecation warning about
        passing hostnames to L{twisted.internet.udp.Port.write} needs to be
        emitted by C{write()} in this case.
        c                      e Zd Zd Zy)6UDPTests.test_NoWarningOnBroadcast.<locals>.fakeSocketc                     y r'   r=   )r*   foobars      r+   sendtoz=UDPTests.test_NoWarningOnBroadcast.<locals>.fakeSocket.sendto  s    r-   N)r:   r;   r<   r   r=   r-   r+   
fakeSocketr     s    r-   r   r   s   test)z<broadcast>i  N)	r   Portr?   r   r   flushWarningstest_NoWarningOnBroadcastrn   r   )r*   r   rr   warningss       r+   r  z"UDPTests.test_NoWarningOnBroadcast  se    	 	 HHQ!<	./%%t'E'E&FGX*r-   N)r:   r;   r<   rx   r~   r   r   r   r   osenvirongetr   r   r   r   r  r=   r-   r+   rf   rf      sh    ( ?(+&8BH 


'(,<<,'	'R:x$$gR+r-   rf   c                  L    e Zd ZdZ ej
                  ed      sdZd Zd Z	d Z
y)ReactorShutdownInteractionTestsz!Test reactor shutdown interactionNrd   c                p    t               | _        t        j                  d| j                  d      | _        y)zStart a UDP portr   rh   ri   N)r?   rw   r   ru   r   r)   s    r+   setUpz%ReactorShutdownInteractionTests.setUp  s%    h%%aL	r-   c                6    | j                   j                         S )zStop the UDP port)r   rp   r)   s    r+   tearDownz(ReactorShutdownInteractionTests.tearDown#  s    yy&&((r-   c                ~    t        j                         t        j                         x} j                  _         fd}|j	                  |        fd}j	                  |        j                  j
                  j                  dd j                  j
                  j                         j                  f       S )z0Test reactor shutdown while in a recvfrom() loopc                    j                   j                  j                          t        j                  dj
                  d        y r   )rw   rA   connectionLostr   r   r3   )rq   finishedr*   s    r+   pktRecezQReactorShutdownInteractionTests.testShutdownFromDatagramReceived.<locals>.pktRece6  s3    KK!!002 a!2!2D9r-   c                &    j                          y r'   )r   rq   r*   s    r+   flushErrorszUReactorShutdownInteractionTests.testShutdownFromDatagramReceived.<locals>.flushErrors@  s    
 ""$r-   s@                                                                   rh   )	r   r   rw   r@   rv   rA   r   rm   r   )r*   prr  r  r  s   `   @r+    testShutdownFromDatagramReceivedz@ReactorShutdownInteractionTests.testShutdownFromDatagramReceived'  s     >>#*/..*::T[['	: 	w	% 	[)##dkk&;&;&C&C&E&J&JK	
 r-   )r:   r;   r<   r]   r   IReactorUDPr   skipr  r  r  r=   r-   r+   r	  r	    s,    +!:!!'402M
)$r-   r	  c                2   t        | t              }|j                  |df       t        | |      }t        | |      }	 |j	                  ||||z          	 |j                          y# t        $ r Y |j                          yw xY w# |j                          w xY w)a	  
    Bind a socket to the given network interface and attempt to join a
    multicast group with the given address family.  This is used to determine
    whether the local networking stack configuration allows for multicast
    within the given address family.
    r   TF)r   r
   bindr   
setsockoptcloseOSError)afipprotojoingroupbindtos	packgrouppackifs           r+   checkMulticastAvailabilityr'  N  s     	r:AFFFA;"e$Ir6"F	WdI$67 		   	
	
 	
	s#   A% %	B.B  BB Bz'This reactor does not support multicast225.0.0.2500.0.0.0z:The local networking stack does not enable IPv4 multicast.c                     e Zd ZU dZdZded<   dZded<   dZded<   d	Zded
<   dZ	ded<   dZ
ded<   dZded<   dZded<   d Zd ZddZddZddZddZddZ eej,                  j/                         xr ej,                  j1                          d      d        Zd Z eej,                  j/                         d      dd       Zy)MulticastTestszs
    Tests for sending and receiving multicast datagrams.  (This suite supports
    IPv4, see below for IPv6.)
    r)  strrj   	str | intexpectedInterfacerh   clientAddressr(  multicastGroupalternateInterfacer   interfaceSynonyminvalidGroup::1wrongAddressFamilyc                   t               | _        t               | _        t	        j
                  d| j                  | j                        | _        t	        j
                  d| j                  | j                        | _        | j                  j                  j                  | j                  | j                  j                  j                         j                         y r   )r?   rw   rK   r   r   listenMulticastrj   r{   r   rA   r   r/  rm   r   r)   s    r+   r  zMulticastTests.setUp  s    hh,,QT^^L
,,QT^^L
%%KK!!))+00	
r-   c                    t        t        | j                  j                        t        | j                  j                        g      S r'   )r   r   r{   rp   r   r)   s    r+   r  zMulticastTests.tearDown  s8    djj667djj667
 	
r-   c                      j                   j                  j                  t        k7  rt	        d      d fd} | j
                          | j                          y )Nz+only IPv4 multicast has TTLs, IPv6 has hopsc                &   t        j                  | j                        sJ j                  | j                  j	                         d       | j                  j                  d       j                  | j                  j	                         d       y )Nr0   r   )r   
providedByrA   rn   getTTLsetTTL)or*   s    r+   checkttlz(MulticastTests.testTTL.<locals>.checkttl  sg    &11!++>>>Q[[//115KKq!Q[[//115r-   )r>  zServer | ClientreturnNone)rw   rA   addressFamilyr   r"   r   )r*   r?  s   ` r+   testTTLzMulticastTests.testTTL  sF    ;;  ..'9HII	6 	r-   c                $  K   | j                   }| j                  | j                  j                  j	                         d       | j                  j                  j                         }| j                  j                  j                  |       d{    t               | j                  _        | j                  j                  j                  d||j                  f       | j                  j                   d{    | j                  t        | j                  j                        d       | j                  j                  j                  d       | j                  | j                  j                  j	                         d       | j                  j                  j                  d||j                  f       t        t        t               d       d{    | j                  t        | j                  j                        d       y7 y7 7 :w)zv
        Test that after loopback mode has been set, multicast packets are
        delivered to their sender.
        r0   Nr   r   )r0  rn   rw   rA   getLoopbackModerm   	joinGroupr   r@   r   r   r   r(   setLoopbackModer   r   r   )r*   r"  rF   s      r+   test_loopbackzMulticastTests.test_loopback  st    
 ##..>>@!D{{$$,,.kk##--e444%-Z"##Hudii.@Akk((((T[[00115--a0..>>@!D##Hudii.@A g.222T[[00115 	5 	) 	3s8   BHHA(H8H9CHH5HHHc                   K   | j                  t              5  | j                  j                  j	                  | j
                  | j                         d{    ddd       y7 # 1 sw Y   yxY ww)z
        A sensible error will be reported when using the wrong address family
        literal for the 'interface' argument to 'joinGroup'.
        ri   N)r   r   rw   rA   rF  r0  r5  r)   s    r+   test_wrongFamilyInterfaceJoinz,MulticastTests.test_wrongFamilyInterfaceJoin  sn     
 12 	++''11##t/F/F 2   	 		 	s.   A3?A'A%A'	A3%A''A0,A3c                  K   | j                  | j                  j                  j                         | j                         | j                  | j
                  j                  j                         | j                         | j
                  j                  j                  | j                         d{    | j                  j                  j                  | j                         d{    | j                  | j                  j                  j                         | j                         | j                  | j
                  j                  j                         | j                         y7 7 w)zK
        Test C{getOutgoingInterface} and C{setOutgoingInterface}.
        N)	rn   r   rA   getOutgoingInterfacer.  rw   setOutgoingInterfacer1  r2  r)   s    r+   test_interfacezMulticastTests.test_interface  s     	KK!!668$:P:P	
 	KK!!668$:P:P	
 kk##889P9PQQQkk##889N9NOOOKK!!668##	
 	KK!!668##	
 	ROs%   B/E.1E*26E.(E,)BE.,E.c                  K   | j                   j                  j                  | j                         d{    | j                   j                  j	                  | j                         d{    | j
                  j                  j                  | j                         d{    | j
                  j                  j	                  | j                         d{    y7 7 u7 @7 w)zE
        Test that multicast a group can be joined and left.
        N)r   rA   rF  r0  
leaveGrouprw   r)   s    r+   test_joinLeavezMulticastTests.test_joinLeave  s      kk##--d.A.ABBBkk##..t/B/BCCCkk##--d.A.ABBBkk##..t/B/BCCC 	CCBCsE   3C(C 6C(,C"-6C(#C$$6C(C&C("C($C(&C(z2Windows' UDP multicast is not yet fully supported.c                    | j                  | j                  j                  j                  | j                        t
        j                        S )z
        Test that an attempt to join an address which is not a multicast
        address fails with L{error.MulticastJoinError}.
        )r   r   rA   rF  r3  r   r   r)   s    r+   test_joinFailurezMulticastTests.test_joinFailure  s=     !!KK!!++D,=,=>@X@X
 	
r-   c                    t               t        j                  d j                         j                  j
                  j                          j                  j
                  j                   j                        } fd}|j                  |        fd}|j                  |       fd}|j                  |       |S )zn
        Test that a multicast group can be joined and messages sent to and
        received from it.
        r   c                    t               x}j                  _        j                  j	                  dj
                  j                  f       |S )N   hello world)r   rw   r@   rA   r   r0  r   )rq   r5   rF   cr*   s     r+   cbJoinedz/MulticastTests.test_multicast.<locals>.cbJoined  s>    -5Z7A*KKnt/B/BDII.NOHr-   c                ^    j                  j                  j                  d   d   d       y )Nr   rV  )rn   rw   r(   r  s    r+   cbPacketz/MulticastTests.test_multicast.<locals>.cbPacket  s'    T[[003A6Gr-   c                \     t        j                        }|j                   fd       |S )Nc                    S r'   r=   )r   passthroughs    r+   r   z@MulticastTests.test_multicast.<locals>.cleanup.<locals>.<lambda>
  s    ; r-   )r   rp   rv   )r]  r   rr   s   ` r+   r   z.MulticastTests.test_multicast.<locals>.cleanup  s%    "1??3F67Mr-   )
r?   r   r7  rj   rw   rA   rm   rF  r0  rv   )r*   joinedrX  rZ  r   rF   rW  rr   s   `    @@@r+   test_multicastzMulticastTests.test_multicast  s    
 H##Aq$..9{{$$,,.&&001D1DE	
 	8$	H 	8$	
 	7#r-   zjon non-linux platforms it appears multiple processes can listen, but not multiple sockets in same process?c                  K   t               }t        t              }|j                  d|d| j                        }|j                         }t        |t        t        f      sJ |j                  }t               }|j                  ||d| j                        }t        | j                  j                  j                  | j                        |j                  | j                        |j                  | j                        g       d{    t               x}|_        t               x}	|_        |j                  j#                  d| j                  |f       t        ||	g       d{    | j%                  |j&                  d   d   d       | j%                  |j&                  d   d   d       t        t)        |j*                        t)        |j*                        g       d{    y7 7 7 	w)z
        Test that multiple sockets can listen on the same multicast port and
        that they both receive multicast messages directed to that address.
        r   T)listenMultiplerj   NrV  )r?   r   r   r7  rj   rm   
isinstancer   r   r   r   rw   rA   rF  r0  r   r@   r   rn   r(   r   rp   )
r*   firstClientmreactor	firstPortfpAddrportnosecondClient
secondPortd1d2s
             r+   test_multiListenzMulticastTests.test_multiListen  s     h$W-,,{44>> - 
	 ""$&;"<===x--nn	 . 

 %%//0C0CD##D$7$78$$T%8%89
 	
 	
 +3*4['+3:5\(##NT5H5H&4QRRH%%%,,Q/2NC--a03^Di556j667
 	
 	
'	
 	&
	
s8   DG2G,	AG2'G.(A>G2&G0'G2.G20G2N)r@  rA  )r:   r;   r<   r]   rj   rH   r.  r/  r0  r1  r2  r3  r5  r  r  rC  rH  rJ  rN  rQ  r   r    platform	isWindowsisVistarS  r_  rl  r=   r-   r+   r+  r+  e  s     Is#,y,$M3$'NC'$/	/"-i-#L####	

60
.D ""$GW-=-=-E-E-G)G<
	
@ ""$	.
.
r-   r+  ff03::1::z/The local stack does not enable IPv6 multicast.c                      e Zd ZU dZdZded<   dZded<   dZded<    ed	  e	       D              Z
d
ed<   e
Zd
ed<   dZded<   dZd
ed<   dZded<   y)MulticastTestsIPv6zC
    Tests for sending and receiving IPv6 multicast datagrams.
    rq  r,  rj   r4  r/  rp  r0  c              #  P   K   | ]  }|d    j                  d      s|d      yw)r0   lor   N)
startswith).0idxnms     r+   	<genexpr>zMulticastTestsIPv6.<genexpr>^  s%     Keq1D1DT1JqKs   &
&r-  r1  r2  r3  r   r.  rh   r5  N)r:   r;   r<   r]   rj   rH   r/  r0  nextr   r1  r2  r3  r.  r5  r=   r-   r+   rs  rs  H  sp     IsM3#NC#$(K|~K%	  #5i4L##$y$))r-   rs  )r  r   r   intr!  r{  r"  r,  r#  r,  r@  bool)=r]   
__future__r   r  r   r   r   r   r   r   r	   r
   r   r   r   unittestr   twisted.internetr   r   r   r   r   r   twisted.internet.addressr   r   twisted.internet.deferr   r   r   twisted.internet.errorr   twisted.internet.interfacesr   r   r   twisted.internet.taskr   twisted.pythonr    twisted.test.testutilsr!   twisted.trial.unittestr"   r#   r%   DatagramProtocolr?   ConnectedDatagramProtocolrK   rY   r   r\   r_   r  rf   r	  r'  r+  rs  r=   r-   r+   <module>r     s1  
 # 	     M M = I I 5 
 - " 2 5 &	UH-- 	UH66 . Y @)) @, "J""7D113VWN+x N+ XN+b "J""7D113VW3h 3 X3l #+.7:DG	. $
$$Wd33- ".y	  A	V
X V
	V
r $
$$Wd33- ",D	  6	* * 	*r-   