Ϫf zUdZddlZddlZddlZddlmZddlmZmZm Z m Z m Z m Z m Z ddlmZddlmZddlmZddlmZdd lmZmZeeed < ed dZdd lmZmZddl m!Z!ddl"m#Z#ddl$m%Z%m&Z&m'Z'ddl(m)Z)m*Z*m+Z+ddl,m-Z-ddl.m/Z/ddl0m1Z1ddl2m3Z3ddl4m5Z5ddl6m7Z7ddl8m9Z9m:Z:m;Z;ddlmZ>m?Z?e@ZAeZBes'ddlCmDZDmEZEmFZFmGZGmHZHmIZImJZJmKZKddlLmMZMmNZNmOZOmPZPmQZQmBZBmAZAneZRee'GddZSe!e'eSGdd e-eSZTGd!d"ZUGd#d$ZVGd%d&e?ZWGd'd(ZXGd)d*ZYGd+d,eYeXe?ZZe[eZd-eVeZjeZjd./Gd0d1eYeXe?Z^e[e^d-eVeZjeZjd2/Gd3d4eYeXe?Z_e[e_d-eUe_je_jeeBGd5d6eAZ`Gd7d8ZaGd9d:eaeXe?ZbGd;de?ZdGd?d@ZeGdAdBe?ZfGdCdDe?Zgee3GdEdFe)ZhGdGdHeee?ZiGdIdJe/ZjGdKdLeee?ZkGdMdNZlGdOdPele?eYZmGdQdRele?eaZny#eef$rd ZY^wxYw)Sz# Tests for L{twisted.pair.tuntap}. N)deque)EAGAINEBADFEINVALENODEVENOENTEPERM EWOULDBLOCK)cycle) randrange)SIGINT)Optional)ObjectNotFoundnamedAny platformSkipz fcntl.ioctlz'Platform is missing fcntl/ioctl support) Interface implementer) verifyObject)CannotListenError)IAddressIListeningPort IReactorFDSet)AbstractDatagramProtocolDatagramProtocolFactory)Clock)EthernetProtocol) IPProtocol)IRawPacketProtocol)RawUDPProtocol) iterbytes) addObserverremoveObservertextFromEventDict)fullyQualifiedName)SkipTestSynchronousTestCase)_H_PI_SIZEMemoryIOSystemTunnel _ethernet_ip_IPv4_udp) _IFNAMSIZ _TUNSETIFF TunnelAddress TunnelFlags TuntapPort_IInputOutputSystem _RealSystemc4eZdZdZdZdZdZdZdZdZ y) ReactorFDSeta6 An implementation of L{IReactorFDSet} which only keeps track of which descriptors have been registered for reading and writing. This implementation isn't actually capable of determining readability or writeability and generates no events for the descriptors registered with it. @ivar _readers: A L{set} of L{IReadDescriptor} providers which the reactor is supposedly monitoring for read events. @ivar _writers: A L{set} of L{IWriteDescriptor} providers which the reactor is supposedly monitoring for write events. ct|_t|_|jj|_|jj|_yN)set_readers_writersadd addReader addWriterselfs ?/usr/lib/python3/dist-packages/twisted/pair/test/test_tuntap.py__init__zReactorFDSet.__init__cs6  ****c:|jj|yr:)r<discard)rBreaders rC removeReaderzReactorFDSet.removeReaderi f%rEc:|jj|yr:)r=rG)rBwriters rC removeWriterzReactorFDSet.removeWriterlrJrEc,t|jSr:)iterr<rAs rC getReaderszReactorFDSet.getReadersoDMM""rEc,t|jSr:)rOr=rAs rC getWriterszReactorFDSet.getWritersrrQrEc t|j|jzt|_t|_S#t|_t|_wxYwr:)listr<r=r;rAs rC removeAllzReactorFDSet.removeAllusD "  56EDMEDM EDMEDMs !A A"N) __name__ __module__ __qualname____doc__rDrIrMrPrSrVrErCr8r8Rs% + &&##"rEr8ceZdZdZdZy) FSSetClockzI An L{FSSetClock} is a L{IReactorFDSet} and an L{IReactorClock}. cXtj|tj|yr:)rrDr8rAs rCrDzFSSetClock.__init__s td#rEN)rWrXrYrZrDr[rErCr]r]s $rEr]c2eZdZdZedZdZdZdZy) TunHelperzM A helper for tests of tun-related functionality (ip-level tunnels). cDtjtjzSr:)r3IFF_TUN IFF_NO_PIrAs rC TUNNEL_TYPEzTunHelper.TUNNEL_TYPEs""[%:%:::rEc ||_||_y)aw @param tunnelRemote: The source address for UDP datagrams originated from this helper. This is an IPv4 dotted-quad string. @type tunnelRemote: L{bytes} @param tunnelLocal: The destination address for UDP datagrams originated from this helper. This is an IPv4 dotted-quad string. @type tunnelLocal: L{bytes} N) tunnelRemote tunnelLocal)rBrfrgs rCrDzTunHelper.__init__s)&rEc ^t|j|jt|||S)a Construct an ip datagram containing a udp datagram containing the given application-level payload. @param source: The source port for the UDP datagram being encapsulated. @type source: L{int} @param destination: The destination port for the UDP datagram being encapsulated. @type destination: L{int} @param payload: The application data to include in the udp datagram. @type payload: L{bytes} @return: An ethernet frame. @rtype: L{bytes} )srcdstpayload)r-rfrgr/)rBsource destinationrks rC encapsulatezTunHelper.encapsulates/$!!  VgF  rEcgt}fd}||_t}|jd|t jd|fd}|S)a Get a function for parsing a datagram read from a I{tun} device. @return: A function which accepts a datagram exactly as might be read from a I{tun} device. The datagram is expected to ultimately carry a UDP datagram. When called, it returns a L{list} of L{tuple}s. Each tuple has the UDP application data as the first element and the sender address as the second element. c(j|yr:appendargs datagramss rCcapturez!TunHelper.parser..capture   T "rE90c2j|ddddS)NF)datagramReceived)dataruips rCparsezTunHelper.parser..parses!   eT4 > rE)rr{r addProtor)rBreceiverrvudpr~rur}s @@rCparserzTunHelper.parsersX #% #%,! UH% \ B   rEN rWrXrYrZpropertyrdrDrnrr[rErCr`r`s*;; ' 0rEr`c2eZdZdZedZdZdZdZy) TapHelperzS A helper for tests of tap-related functionality (ethernet-level tunnels). cdtj}|js|tjz}|Sr:)r3IFF_TAPpirc)rBflags rCrdzTapHelper.TUNNEL_TYPEs)""ww K)) )D rEc.||_||_||_y)a @param tunnelRemote: The source address for UDP datagrams originated from this helper. This is an IPv4 dotted-quad string. @type tunnelRemote: L{bytes} @param tunnelLocal: The destination address for UDP datagrams originated from this helper. This is an IPv4 dotted-quad string. @type tunnelLocal: L{bytes} @param pi: A flag indicating whether this helper will generate and consume a protocol information (PI) header. @type pi: L{bool} N)rfrgr)rBrfrgrs rCrDzTapHelper.__init__s)&rEct|j|j}|j|||}t ddt |}|j r"t }d}t|t|z|z}|S)a< Construct an ethernet frame containing an ip datagram containing a udp datagram containing the given application-level payload. @param source: The source port for the UDP datagram being encapsulated. @type source: L{int} @param destination: The destination port for the UDP datagram being encapsulated. @type destination: L{int} @param payload: The application data to include in the udp datagram. @type payload: L{bytes} @return: An ethernet frame. @rtype: L{bytes} ss)rirjprotocolrkr)r`rfrgrnr,r.rr() rBrlrmrktunr}framerflagss rCrnzTapHelper.encapsulatess$))4+;+;< __V[' :++   77HEuI8 ,u4E rEcgt}fd}||_t}|jd|t }|jd|t jd|fd}|S)a Get a function for parsing a datagram read from a I{tap} device. @return: A function which accepts a datagram exactly as might be read from a I{tap} device. The datagram is expected to ultimately carry a UDP datagram. When called, it returns a L{list} of L{tuple}s. Each tuple has the UDP application data as the first element and the sender address as the second element. c(j|yr:rqrss rCrvz!TapHelper.parser..capture'rwrErxryicTjr |td}j|Sr:)rr)r{)datagramruetherrBs rCrz TapHelper.parser..parser5s.ww#HI.  " "8 , rE)rr{r rrr)rBrrvrr}rrurs` @@rCrzTapHelper.parsersn #% #%,! UH% \ B " ub!  rENrr[rErCrrs+ $ D&rErceZdZdZdZy) TunnelTestszs L{Tunnel} is mostly tested by other test cases but some tests don't fit there. Those tests are here. ctttjd}|j t |j dy)z Blocking reads are not implemented by L{Tunnel.read}. Attempting one results in L{NotImplementedError} being raised. N)r+r*osO_RDONLY assertRaisesNotImplementedErrorreadrBtunnels rCtest_blockingReadzTunnelTests.test_blockingReadIs0 ("++t< -v{{DArEN)rWrXrYrZrr[rErCrrCs  BrErcLeZdZdZdZdZdZdZdZdZ dZ d Z d Z d Z y ) TunnelDeviceTestsMixinzZ A mixin defining tests that apply to L{_IInputOutputSystem} implementations. c|j|_|jjdtjtj z|_|j|jj|j |jj}tjdtfz|j|j}|jj!|j t"|y)zk Create the L{_IInputOutputSystem} provider under test and open a tunnel using it. /dev/net/tunz%dsHN) createSystemsystemopenrO_RDWR O_NONBLOCKfileno addCleanupclosehelperrdstructpackr0_TUNNEL_DEVICEvalueioctlr1)rBmodeconfigs rCsetUpzTunnelDeviceTestsMixin.setUpXs '') kk&& BMM8QR   ))4;;7{{&&Vyl2D4G4GT $++z6:rEcV|jtt|jy)zH The object under test provides L{_IInputOutputSystem}. N) assertTruerr5rrAs rCtest_interfacez%TunnelDeviceTestsMixin.test_interfacees  %8$++FGrEc|jjdtj}|jj ||S)a@ Get an invalid file descriptor. @return: An integer which is not a valid file descriptor at the time of this call. After any future system call which allocates a new file descriptor, there is no guarantee the returned file descriptor will still be invalid. r)rrrrr)rBfds rC_invalidFileDescriptorz-TunnelDeviceTestsMixin._invalidFileDescriptorks5[[  oryy 9 " rEc|j}|jt|jj|d}|j t |jy)z The device's C{read} implementation raises L{OSError} with an errno of C{EBADF} when called on a file descriptor which is not valid (ie, which has no associated file description). rN)rrOSErrorrr assertEqualrerrnorBrexcs rCtest_readEBADFz%TunnelDeviceTestsMixin.test_readEBADFxsF  ( ( *)9)92tD  *rEc|j}|jt|jj|d}|j t |jy)z The device's C{write} implementation raises L{OSError} with an errno of C{EBADF} when called on a file descriptor which is not valid (ie, which has no associated file description). sbytesN)rrrrwriterrrrs rCtest_writeEBADFz&TunnelDeviceTestsMixin.test_writeEBADFsF  ( ( *):):BI  *rEc|j}|jt|jj|}|j t |jy)z The device's C{close} implementation raises L{OSError} with an errno of C{EBADF} when called on a file descriptor which is not valid (ie, which has no associated file description). N)rrrrrrrrrs rCtest_closeEBADFz&TunnelDeviceTestsMixin.test_closeEBADFsD  ( ( *):):B?  *rEc|j}|jt|jj|t d}|j t|jy)z The device's C{ioctl} implementation raises L{OSError} with an errno of C{EBADF} when called on a file descriptor which is not valid (ie, which has no associated file description). stap0N) rrIOErrorrrr1rrrrs rCtest_ioctlEBADFz&TunnelDeviceTestsMixin.test_ioctlEBADFsH  ( ( *):):B GT  *rEcd}|jt|jj|j|d}|j t |jy)z The device's C{ioctl} implementation raises L{IOError} with an errno of C{EINVAL} when called with a request (second argument) which is not a supported operation. l>[=sgarbageN)rrrrrrrr)rBrequestrs rCtest_ioctlEINVALz'TunnelDeviceTestsMixin.test_ioctlEINVALsH T[[&& Wj  +rEc|jj}d}tdD]}td}d|fz}|jj ||j df}tdD]@} |jj|jd}||} ||f| vrd}n| dd=B|sn|s|jd yy#t$r$} | jttfvrYd} ~ Bd} ~ wwxYw) z If a UDP datagram is sent to an address reachable by the tunnel device then it can be read out of the tunnel device. Fdhello world:%drxrTNz$Never saw probe UDP packet on tunnel)rrranger rsendUDP_TUNNEL_REMOTErrrrrr fail) rBr~foundikeymessagerljpacketrues rC test_receivez#TunnelDeviceTestsMixin.test_receives   ""$s AE"C'3&0G[[((43F3F2NOF 3Z % %![[--dkk4@F !&f I(I5 $!!  %- 0 II< =ww6;"77s3&C  C:C54C55C:ctd}d|fz}|jtjtjtjd|j j |j|jd}|jjdd|}|j j|j||jd}|j||y)z If a UDP datagram is written the tunnel device then it is received by the network to which it is addressed. rrxrxiPrN)r rsocketsetdefaulttimeoutgetdefaulttimeoutr receiveUDPr _TUNNEL_LOCALrrnrrecvr)rBrrportrs rC test_sendz TunnelDeviceTestsMixin.test_sends#sf, 00&2J2J2LM  %{{%%dkk43E3EuM((w? $++v.4 &)rEN)rWrXrYrZrrrrrrrrrrr[rErCrrRs; ;H ++++ ,$>L$*rErc"eZdZdZdZdZdZdZy)FakeDeviceTestsMixinz Define a mixin for use with test cases that require an L{_IInputOutputSystem} provider. This mixin hands out L{MemoryIOSystem} instances as the provider of that interface. stap-twistedtests 172.16.2.1s 172.16.2.2cbt}|jtjt|S)z Create and return a brand new L{MemoryIOSystem}. The L{MemoryIOSystem} knows how to open new tunnel devices. @return: The newly created I/O system object. @rtype: L{MemoryIOSystem} )r*registerSpecialDevicer+ _DEVICE_NAMErBrs rCrz!FakeDeviceTestsMixin.createSystems' !$$V%8%8&A rEN)rWrXrYrZrrrrr[rErCrrs (N!M"N rErceZdZdZy)FakeTapDeviceTestszQ Run various tap-type tunnel unit tests against an in-memory I/O system. NrWrXrYrZr[rErCrrrErrFrceZdZdZy)FakeTapDeviceWithPITestszp Run various tap-type tunnel unit tests against an in-memory I/O system with the PI header enabled. Nrr[rErCrr%srErTceZdZdZy)FakeTunDeviceTestszQ Run various tun-type tunnel unit tests against an in-memory I/O system. Nrr[rErCrr7rrErc8eZdZdZfdZfdZdZdZxZS)TestRealSystemz Add extra skipping logic so tests that try to create real tunnel devices on platforms where those are not supported automatically get skipped. c t||g|i|S#t$r.}|jtt fvr|dk(r t dd}~wwxYw)z Attempt an open, but if the file is /dev/net/tun and it does not exist, translate the error into L{SkipTest} so that tests that require platform support for tuntap devices are skipped instead of failed. rzPlatform lacks /dev/net/tunN)superrrrrrr&)rBfilenamertkwargsr __class__s rCrzTestRealSystem.openMsZ  7<:4:6: : ww66**x?/J<==   s A )AA c t||i|S#t$r$}t|jk(r t dd}~wwxYw)z Attempt an ioctl, but translate permission denied errors into L{SkipTest} so that tests that require elevated system privileges and do not have them are skipped instead of failed. z%Permission to configure device deniedN)rrrr rr&)rBrtrrrs rCrzTestRealSystem.ioctl\sG  7=$1&1 1 FGG  s ?:?ctjtjtj}|jd|j |||j S)a Use the platform network stack to send a datagram to the given address. @param datagram: A UDP datagram payload to send. @type datagram: L{bytes} @param address: The destination to which to send the datagram. @type address: L{tuple} of (L{bytes}, L{int}) @return: The address from which the UDP datagram was sent. @rtype: L{tuple} of (L{bytes}, L{int}) )z 172.16.0.1r)rAF_INET SOCK_DGRAMbindsendto getsockname)rBraddressss rCrzTestRealSystem.sendUDPisE MM&..&*;*; <  ! 7#}}rEctjtjtj}|j||f|S)a Use the platform network stack to receive a datagram sent to the given address. @param fileno: The file descriptor of the tunnel used to send the datagram. This is ignored because a real socket is used to receive the datagram. @type fileno: L{int} @param host: The IPv4 address at which the datagram will be received. @type host: L{bytes} @param port: The UDP port number at which the datagram will be received. @type port: L{int} @return: A L{socket.socket} which can be used to receive the specified datagram. )rrrr)rBrhostrrs rCrzTestRealSystem.receiveUDP{s3( MM&..&*;*; < d|rE) rWrXrYrZrrrr __classcell__)rs@rCrrFs  $rErceZdZdZeZdZy)RealDeviceTestsMixinz Define a mixin for use with test cases that require an L{_IInputOutputSystem} provider. This mixin hands out L{TestRealSystem} instances as the provider of that interface. ctS)z Create a real I/O system that can be used to open real tunnel device provided by the underlying system and previously configured. @return: The newly created I/O system object. @rtype: L{TestRealSystem} )rrAs rCrz!RealDeviceTestsMixin.createSystems rEN)rWrXrYrZrskiprr[rErCr r s D rEr c2eZdZdZdZdZdZeeedZy)&RealDeviceWithProtocolInformationTestsz| Run various tap-type tunnel unit tests, with "protocol information" (PI) turned on, against a real I/O system. s tap-twtest-pis 172.16.1.1s 172.16.1.2TrN rWrXrYrZrrrrrr[rErCrrs( &N!M"N ~} >FrErc2eZdZdZdZdZdZeeedZy))RealDeviceWithoutProtocolInformationTestsz} Run various tap-type tunnel unit tests, with "protocol information" (PI) turned off, against a real I/O system. s tap-twtests 172.16.0.1s 172.16.0.2FrNrr[rErCrrs& #N!M"N ~} ?FrErceZdZdZdZdZy)TuntapPortTestszR Tests for L{TuntapPort} behavior that is independent of the tunnel type. cjtdt}|jtt|y)zF A L{TuntapPort} instance provides L{IListeningPort}. deviceN)r4rrrrrBrs rCrzTuntapPortTests.test_interfaces')%5%78  ^T:;rEcltdt}|j|jty)zg When not initialized with an I/O system, L{TuntapPort} uses a L{_RealSystem}. rN)r4rassertIsInstance_systemr6rs rCtest_realSystemzTuntapPortTests.test_realSystems( )%5%78 dllK8rEN)rWrXrYrZrrr[rErCrrs<9rErceZdZdZdZdZdZdZdZdZ dZ d Z d Z d Z d Zd ZdZdZdZdZdZdZdZdZdZdZdZdZdZdZdZdZdZ dZ!d Z"d!Z#d"Z$d#Z%d$Z&y%)&TunnelTestsMixinz A mixin defining tests for L{TuntapPort}. These tests run against L{MemoryIOSystem} (proven equivalent to the real thing by the tests above) to avoid performing any real I/O. cd|_t|_|jjtj t|j jt|jj|j|_ t|_ t|j|j|j|j|_y)zW Create an in-memory I/O system and set up a L{TuntapPort} against it. tun0)reactorrN)namer*rrr+rfactory buildProtocolr2rrdrr]r!r4rrAs rCrzTunnelTestsMixin.setUps $&  ))&*=*=vF 22 $++11499 =  "|  IIt}}dll4;;  rEcJ|tjtjzzS)a/ Mask off any flags except for L{TunnelType.IFF_TUN} and L{TunnelType.IFF_TAP}. @param flags: Flags from L{TunnelType} to mask. @type flags: L{FlagConstant} @return: The flags given by C{flags} except the two type flags. @rtype: L{FlagConstant} )r3rbr)rBrs rC_tunnelTypeOnlyz TunnelTestsMixin._tunnelTypeOnlys  ++k.A.AABBrEc|j}|jj|jj|j}|j|j z|j zddttdz zz|jjddf}|j|j|j|j|jf}|j||y)z L{TuntapPort.startListening} opens the tunnel factory character special device C{"/dev/net/tun"} and configures it as a I{tun} tunnel. r FTN)rrstartListening getTunnelr O_CLOEXECrr0len interface openFlags requestedNamer"blocking closeOnExecr)rBrrexpectedactuals rCtest_startListeningOpensDevicez/TunnelTestsMixin.test_startListeningOpensDevices    "&&tyy1 MMF,, ,v/@/@ @ gS\!9: : II           KK OO      6*rEc|jj|j|jjy)zg L{TuntapPort.startListening} sets C{connected} on the port object to C{True}. N)rr)r connectedrAs rC test_startListeningSetsConnectedz1TunnelTestsMixin.test_startListeningSetsConnecteds*   "  ++,rEc|jj|j|j|jjy)z L{TuntapPort.startListening} calls C{makeConnection} on the protocol the port was initialized with, passing the port as an argument. N)rr)assertIsr transportrAs rC#test_startListeningConnectsProtocolz4TunnelTestsMixin.test_startListeningConnectsProtocol%s0   " dii!8!89rEc|jj|j|j|jj y)z L{TuntapPort.startListening} passes the port instance to the reactor's C{addReader} method to begin watching the port's file descriptor for data to read. N)rr)assertInr!rPrAs rC test_startListeningStartsReadingz1TunnelTestsMixin.test_startListeningStartsReading-s3   " dii!8!8!:;rEc|jjjd|jt|j j y)z L{TuntapPort.startListening} raises L{CannotListenError} if opening the tunnel factory character special device fails. rNr permissionsremoverrrr)rAs rC%test_startListeningHandlesOpenFailurez6TunnelTestsMixin.test_startListeningHandlesOpenFailure6s7 &&v. +TYY-E-EFrEc|jjjd|jt|j j y)z L{TuntapPort.startListening} raises L{CannotListenError} if the C{ioctl} call to configure the tunnel device fails. rNr@rAs rC*test_startListeningHandlesConfigureFailurez;TunnelTestsMixin.test_startListeningHandlesConfigureFailure>s7 &&w/ +TYY-E-EFrEc|j}|j||jj|jj d|j |j |y)a< Verify that the C{stopListening} method of an L{IListeningPort} removes that port from the reactor's "readers" set and also that the L{Deferred} returned by that method fires with L{None}. @param port: The port object to stop. @type port: L{IListeningPort} provider rN) stopListening assertNotInr!rPadvance assertIsNonesuccessResultOf)rBrstoppeds rC _stopPortzTunnelTestsMixin._stopPortFsZ$$& t||6689 Q $..w78rEc|jj|jj}|j|j|j ||j j y)z L{TuntapPort.stopListening} returns a L{Deferred} which fires after the port has been removed from the reactor's reader list by passing it to the reactor's C{removeReader} method. N)rr)rrMrHr _openFiles)rBrs rCtest_stopListeningStopsReadingz/TunnelTestsMixin.test_stopListeningStopsReadingUsP   "!!# tyy! !7!78rEc|jj|j|j|j|jjy)z After the L{Deferred} returned by L{TuntapPort.stopListening} fires, the C{connected} attribute of the port object is set to C{False}. N)rr)rM assertFalser6rAs rC!test_stopListeningUnsetsConnectedz2TunnelTestsMixin.test_stopListeningUnsetsConnectedas<   " tyy! ,,-rEc|jj|j|j|j|jj y)zt L{TuntapPort.stopListening} calls C{doStop} on the protocol the port was initialized with. N)rr)rMrJrr:rAs rCtest_stopListeningStopsProtocolz0TunnelTestsMixin.test_stopListeningStopsProtocoljs<   " tyy! $--112rEcx|jj}|j|j|y)z L{TuntapPort.stopListening} returns a L{Deferred} which succeeds immediately if it is called when the port is not listening. N)rrGrJrK)rBrLs rCtest_stopListeningWhenStoppedz.TunnelTestsMixin.test_stopListeningWhenStoppedss/ ))))+ $..w78rEc|jj|jj|jj}|jj d|j |j |y)z It is safe and a no-op to call L{TuntapPort.stopListening} more than once with no intervening L{TuntapPort.startListening} call. rN)rr)rGr!rIrJrK)rBseconds rCtest_multipleStopListeningz+TunnelTestsMixin.test_multipleStopListening{sa   " !((* Q $..v67rEc|jj|jj|jj d|j |jj |j|jg}|jt|dd|jd|dd|jdt|y)zP L{TuntapPort.loseConnection} stops the port and is deprecated. rcategoryztwisted.pair.tuntap.TuntapPort.loseConnection was deprecated in Twisted 14.0.0; please use twisted.pair.tuntap.TuntapPort.stopListening insteadrN) rr)loseConnectionr!rIrRr6 flushWarningstest_loseConnectionrDeprecationWarningr,)rBwarningss rCr`z$TunnelTestsMixin.test_loseConnections   "   " Q ,,-%%t'?'?&@A +Xa[-DE  $ QK "  CM*rEc|jj|jj|j}||_|jj |j g|jjy)ah Test that L{TuntapPort.doRead} has no side-effects under a certain exception condition. @param style: An exception instance to arrange for the (python wrapper around the) underlying platform I{read} call to fail with. @raise C{self.failureException}: If there are any observable side-effects. N) rr)rr*nonBlockingExceptionStyledoReadrrreceived)rBstylers rC_stopsReadingTestz"TunnelTestsMixin._stopsReadingTests^   "&&tyy1+0(  T]]334rEcB|jtjy)zr Once L{TuntapPort.doRead} encounters an I{EAGAIN} errno from a C{read} call, it returns. N)rhr+ EAGAIN_STYLErAs rCtest_eagainStopsReadingz(TunnelTestsMixin.test_eagainStopsReadings v223rEcB|jtjy)zw Once L{TuntapPort.doRead} encounters an I{EWOULDBLOCK} errno from a C{read} call, it returns. N)rhr+EWOULDBLOCK_STYLErAs rCtest_ewouldblockStopsReadingz-TunnelTestsMixin.test_ewouldblockStopsReadings v778rEcB|jtjy)zq Once L{TuntapPort.doRead} encounters an I{EINTR} errno from a C{read} call, it returns. N)rhr+ EINTR_STYLErAs rCtest_eintrblockStopsReadingz,TunnelTestsMixin.test_eintrblockStopsReadings v112rEcfGddt}|j||j|y)z If L{Tuntap.doRead} encounters any exception other than one explicitly handled by the code, the exception propagates to the caller. c eZdZy)ETunnelTestsMixin.test_unhandledReadError..UnexpectedExceptionN)rWrXrYr[rErCUnexpectedExceptionrts rEruN) Exceptionrrh)rBrus rCtest_unhandledReadErrorz(TunnelTestsMixin.test_unhandledReadErrors/  )   !7!79L9N rEcb|jt|jttdy)z Just like C{test_unhandledReadError}, but for the case where the exception that is not explicitly handled happens to be of type C{EnvironmentError} (C{OSError} or C{IOError}). zOperation not permittedN)rrrhr rAs rC"test_unhandledEnvironmentReadErrorz3TunnelTestsMixin.test_unhandledEnvironmentReadErrors'  T++WU?@ dii---   T&\DII,C,CC D TYY,, ,Edii---   "&&tyy1  +  !FG  DMM$:$:;rEc2|jj|jj|jjj dd|j _|jj|jtS)z Deliver some data to a L{TuntapPort} hooked up to an application protocol that raises an exception from its C{datagramReceived} method. @return: Whatever L{AttributeError} exceptions are logged. spingN) rr)rr*r~rrrrfreflushLoggedErrorsAttributeErrorrAs rC_datagramReceivedExceptionz+TunnelTestsMixin._datagramReceivedExceptionsj   " dii(33::7C"&  %%n55rEcZ|j}|jdt|y)zt If the protocol's C{datagramReceived} method raises an exception, the exception is logged. r]N)rrr,)rBerrorss rCtest_datagramReceivedExceptionz/TunnelTestsMixin.test_datagramReceivedExceptions& 002 CK(rEcTg}t|j|jt|j|j t d|D}t |}|jdt|jjd|jdy)z The exception raised by C{datagramReceived} is logged with a message identifying the offending protocol. c3,K|] }|ds |yw)isErrorNr[).0ms rC zTTunnelTestsMixin.test_datagramReceivedExceptionIdentifiesProtocol..'s91AiLQ9s zUnhandled exception from z.datagramReceivedrN) r"rrrr#rrr$rr%rr splitlines)rBmessageserrorrs rC0test_datagramReceivedExceptionIdentifiesProtocolzATunnelTestsMixin.test_datagramReceivedExceptionIdentifiesProtocols HOO$ 8 '')999#E* !$--"9"9: =     # rEcd}|jj|jj||j|jj |jj t|gy)zG L{TuntapPort.write} sends a datagram into the tunnel. s a b c d e f gN)rr)rrrr* writeBufferrrBrs rC test_writezTunnelTestsMixin.test_write/s\$   " !  KK ! !$)) , 8 8% :K rEcB|jj|jj|j}|jj t |jjd|jtdg|jy)z If the platform write call is interrupted (causing the Python wrapper to raise C{IOError} with errno set to C{EINTR}), the write is re-tried. s hello, worldN) rr)rr*pendingSignalsrrr rrrrrs rCtest_interruptedWritez&TunnelTestsMixin.test_interruptedWrite:sn   "&&tyy1$$V, ( 0163E3EFrEc|jj|jj|j}|j t |jj d|jzdzy)z{ Any exception raised by the underlying write call, except for EINTR, is propagated to the caller. r{rN)rr)rr*rrrSEND_BUFFER_SIZErs rCtest_unhandledWriteErrorz)TunnelTestsMixin.test_unhandledWriteErrorEsY   "&&tyy1  TYY__dV-D-D&Dt&K rEc&gd}|jj|jj||j|jj |jj tdj|gy)z L{TuntapPort.writeSequence} sends a datagram into the tunnel by concatenating the byte strings in the list passed to it. )abcdrEN) rr) writeSequencerrr*rrjoinrs rCtest_writeSequencez#TunnelTestsMixin.test_writeSequencePsh ,   " )  KK ! !$)) , 8 8%(AS@T:U rEcD|jj|jj}|jt |j |j j|jj|jj|y)zp L{TuntapPort.getHost} returns a L{TunnelAddress} including the tunnel's type and name. N) rr)getHostrr2r&rrdrr*r")rBrs rC test_getHostzTunnelTestsMixin.test_getHost\su   "))##%  $$T[[%<%<= %%dii055    rEc|jj|jt|jt |j j dj|j|jjj|jj|jj}|jt|jj|dk7y) The string representation of a L{TuntapPort} instance includes the tunnel type and interface and the protocol associated with the port. z listening on {}/{}>N)rr) assertRegexstrr%rrformatr&rrdr"rr*rfindrBr2s rCtest_listeningStringz%TunnelTestsMixin.test_listeningStringks   " TYY);DMM > KK ! !$)) , 1 1  DII++H5;rN) rrrr%rrrr&rrdr"rrrs rCtest_unlisteningStringz'TunnelTestsMixin.test_unlisteningStringys TYY);DMM > II  DII++H5;rCrErMrPrSrUrWrZr`rhrkrnrqrwryrrrrrrrrrrrrrrr[rErCrrs   C+2-:<GG 9 9.39 8+*5"493    = =<(6 ) "   G       = =  rErc"eZdZdZdZdZdZy)TunnelAddressTestsz% Tests for L{TunnelAddress}. c r|jttttj dy)zD A L{TunnelAddress} instances provides L{IAddress}. tap0N)rrrr2r3rrAs rCtest_interfacesz"TunnelAddressTests.test_interfacess'  =1D1Df#M N rEcttjd}|jd|d|jd|d|j |j g}d}|jt |dd|j||dd|jt |dd|j||dd|jdt|y ) z A L{TunnelAddress} instance can be indexed to retrieve either the byte string C{"TUNTAP"} or the name of the tunnel interface, while triggering a deprecation warning. rTUNTAPrr]zUTunnelAddress.__getitem__ is deprecated since Twisted 14.0.0 Use attributes instead.r\rN)r2r3rrr_ test_indexingrar,)rBrrbrs rCrz TunnelAddressTests.test_indexings  3 3V< 71:. ,%%t'9'9&:; &  +Xa[-DE (1+i"89 +Xa[-DE (1+i"89 CM*rEcl|jtttjddy)z The string representation of a L{TunnelAddress} instance includes the class name and the values of the C{type} and C{name} attributes. r)r"z*TunnelAddress type=IFF_TUN name=b'device'>N)rreprr2r3rbrAs rC test_reprzTunnelAddressTests.test_reprs*  {22C D 8 rEN)rWrXrYrZrrrr[rErCrrs +( rErcReZdZdZdZdZdZdZdZdZ dZ d Z d Z d Z d Zy )TunnelAddressEqualityTestsz^ Tests for the implementation of equality (C{==} and C{!=}) for L{TunnelAddress}. cttjd|_ttjtjzd|_ttj d|_ttjd|_y)Nrstap1stun1)r2r3rbfirstrYr variedType variedNamerAs rCrz TunnelAddressEqualityTests.setUpsd";#6#6 B $   +"5"5 5y  ( (;(;WE' (;(;WErEcT|j|j|jk(y)z> A L{TunnelAddress} compares equal to itself. NrrrAs rCtest_selfComparesEqualz1TunnelAddressEqualityTests.test_selfComparesEquals  djj01rEcT|j|j|jk7y)zI A L{TunnelAddress} doesn't compare not equal to itself. NrRrrAs rCtest_selfNotComparesNotEqualz7TunnelAddressEqualityTests.test_selfNotComparesNotEquals tzz12rEcT|j|j|jk(y)z Two L{TunnelAddress} instances with the same value for the C{type} and C{name} attributes compare equal to each other. N)rrrYrAs rC test_sameAttributesComparesEqualz;TunnelAddressEqualityTests.test_sameAttributesComparesEquals  dkk12rEcT|j|j|jk7y)z Two L{TunnelAddress} instances with the same value for the C{type} and C{name} attributes don't compare not equal to each other. N)rRrrYrAs rC&test_sameAttributesNotComparesNotEqualzATunnelAddressEqualityTests.test_sameAttributesNotComparesNotEquals t{{23rEcT|j|j|jk(y)z Two L{TunnelAddress} instances that differ only by the value of their type don't compare equal to each other. N)rRrrrAs rC"test_differentTypeComparesNotEqualz=TunnelAddressEqualityTests.test_differentTypeComparesNotEqual t67rEcT|j|j|jk7y)z Two L{TunnelAddress} instances that differ only by the value of their type compare not equal to each other. N)rrrrAs rC"test_differentTypeNotComparesEqualz=TunnelAddressEqualityTests.test_differentTypeNotComparesEqual  doo56rEcT|j|j|jk(y)z Two L{TunnelAddress} instances that differ only by the value of their name don't compare equal to each other. N)rRrrrAs rC"test_differentNameComparesNotEqualz=TunnelAddressEqualityTests.test_differentNameComparesNotEqualrrEcT|j|j|jk7y)z Two L{TunnelAddress} instances that differ only by the value of their name compare not equal to each other. N)rrrrAs rC"test_differentNameNotComparesEqualz=TunnelAddressEqualityTests.test_differentNameNotComparesEqualrrEc@|j|j|k(y)zc A L{TunnelAddress} doesn't compare equal to an instance of another class. NrrAs rC#test_differentClassNotComparesEqualz>TunnelAddressEqualityTests.test_differentClassNotComparesEqual s t+,rEc@|j|j|k7y)zX A L{TunnelAddress} compares not equal to an instance of another class. NrrAs rC#test_differentClassComparesNotEqualz>TunnelAddressEqualityTests.test_differentClassComparesNotEquals  d*+rEN)rWrXrYrZrrrrrrrrrrrr[rErCrrs? F 2 3 348787-,rErc&eZdZdZdZ ddZdZy)IPRecordingProtocolH A protocol which merely records the datagrams delivered to it. cg|_yr:rfrAs rC startProtocolz!IPRecordingProtocol.startProtocol!  rENc:|jj|yr:rfrr)rBrpartialdestrlrs rCr{z$IPRecordingProtocol.datagramReceived$s X&rEcyr:r[)rBnumprotos rCrzIPRecordingProtocol.addProto)s rE)FNNN)rWrXrYrZrr{rr[rErCrrsIM'  rErc>eZdZdZeZee_eddZ y)TunTestszJ Tests for L{TuntapPort} when used to open a Linux I{tun} tunnel. N) rWrXrYrZrr#rrr`rr[rErCrr.s$iG*G tT "FrErceZdZdZdZddZy)EthernetRecordingProtocolrcg|_yr:rrAs rCrz'EthernetRecordingProtocol.startProtocol>rrEc:|jj|yr:r)rBrrs rCr{z*EthernetRecordingProtocol.datagramReceivedAs X&rEN)F)rWrXrYrZrr{r[rErCrr9s'rErcBeZdZdZeZee_edddZ y)TapTestszJ Tests for L{TuntapPort} when used to open a Linux I{tap} tunnel. NFr) rWrXrYrZrr#rrrrr[rErCrrEs&iG0G tTe ,FrErceZdZdZdZy)IOSystemTestsMixinzH Tests that apply to any L{_IInputOutputSystem} implementation. c|j}|jt|jdtj y)zt L{_IInputOutputSystem.open} raises L{OSError} when called with a non-existent device path. s!/dev/there-is-no-such-device-everN)rrrrrrrs rCtest_noSuchDevicez$IOSystemTestsMixin.test_noSuchDeviceUs2 ""$  V[["F  rEN)rWrXrYrZrr[rErCrrPs  rErceZdZdZy)MemoryIOSystemTestszL General L{_IInputOutputSystem} tests applied to L{MemoryIOSystem}. Nrr[rErCrr`rrErceZdZdZy)RealIOSystemTestszI General L{_IInputOutputSystem} tests applied to L{_RealSystem}. Nrr[rErCrrhsrEr)orZrrr collectionsrrrrrrrr r itertoolsr randomr signalr typingrtwisted.python.reflectrrr__annotations__rrzope.interfacerrzope.interface.verifyrtwisted.internet.errorrtwisted.internet.interfacesrrrtwisted.internet.protocolrrrtwisted.internet.taskrtwisted.pair.ethernetrtwisted.pair.iprtwisted.pair.rawrtwisted.pair.rawudpr twisted.python.compatr!twisted.python.logr"r#r$r%twisted.trial.unittestr&r'objectr6r5twisted.pair.testingr(r)r*r+r,r-r.r/twisted.pair.tuntapr0r1r2r3r4rr8r]r`rrrrrsetattrrrrrrr rrrrrrrrrrrrrr[rErCr s   KKK;sm ]L1.4OO (2&/.+MM5@       D ]'"'"'"T ]LN+$ $MM`ffR B% Bf*f*R202E  ))+=+K+KPU02E  ))+=+K+KPT02E   //1C1Q1QR !J[J"JZ  (?02E?& @02E @ 9)9*r r j ) ,) XW,!4W,t   2 ! $#!4# ' 0 '-!4-   +-A*,?AUa* '=