o bH@s`dZddlZddlZddlZddlmZddlmZddlm Z e dkrWddl m Z ddl m Z dd l m Z mZmZmZmZmZmZee ee gZe eeegZeZe Ze ZeZndd l mZmZmZmZmZmZeeegZegZdd lmZmZmZm Z m!Z!m"Z"dd l#m$Z$m%Z%ee"j&e"j'e"j(Gd ddej)Z*GdddZ+ee"j,Gddde+e*Z-dS)a Various asynchronous UDP classes. Please do not use this module directly. @var _sockErrReadIgnore: list of symbolic error constants (from the C{errno} module) representing socket errors where the error is temporary and can be ignored. @var _sockErrReadRefuse: list of symbolic error constants (from the C{errno} module) representing socket errors that indicate connection refused. N)Optional) implementer) platformTypewin32)WSAEINPROGRESS)WSAEWOULDBLOCK)WSAECONNREFUSED WSAECONNRESETWSAEINTR WSAEMSGSIZE WSAENETRESETWSAENOPROTOOPT WSAETIMEDOUT)EAGAIN ECONNREFUSEDEINTREMSGSIZE ENOPROTOOPT EWOULDBLOCK)abstractaddressbasedefererror interfaces)failurelogc@seZdZUdZejZejZdZ dZ e e e d<dZd2ddZed d Zd efd d ZddZddZddZddZddZd3ddZddZddZddZd d!Zd"d#Zd3d$d%Zd&d'Z d(d)Z!d*d+Z"d,d-Z#d.d/Z$d0d1Z%dS)4Porta UDP port, listening for packets. @ivar maxThroughput: Maximum number of bytes read in one event loop iteration. @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. @ivar _realPortNumber: Actual port number being listened on. The value will be L{None} until this L{Port} is listening. @ivar _preexistingSocket: If not L{None}, a L{socket.socket} instance which was created and initialized outside of the reactor and will be used to listen for connections (instead of a new socket being created by this L{Port}). iN_realPortNumber cCs@tj||||_||_||_||_|d|_| dS)a @param port: A port number on which to listen. @type port: L{int} @param proto: A C{DatagramProtocol} instance which will be connected to the given C{port}. @type proto: L{twisted.internet.protocol.DatagramProtocol} @param interface: The local IPv4 or IPv6 address to which to bind; defaults to '', ie all IPv4 addresses. @type interface: L{str} @param maxPacketSize: The maximum packet size to accept. @type maxPacketSize: L{int} @param reactor: A reactor which will notify this C{Port} when its socket is ready for reading or writing. Defaults to L{None}, ie the default global reactor. @type reactor: L{interfaces.IReactorFDSet} N) rBasePort__init__portprotocol maxPacketSize interface setLogStr_connectedAddr_setAddressFamily)selfr#protor&r%reactorr-6/usr/lib/python3/dist-packages/twisted/internet/udp.pyr"[s z Port.__init__c Cs8t|||j}|d}|d||||d}||_|S)a Create a new L{Port} based on an existing listening I{SOCK_DGRAM} socket. @param reactor: A reactor which will notify this L{Port} when its socket is ready for reading or writing. Defaults to L{None}, ie the default global reactor. @type reactor: L{interfaces.IReactorFDSet} @param fd: An integer file descriptor associated with a listening socket. The socket must be in non-blocking mode. Any additional attributes desired, such as I{FD_CLOEXEC}, must also be set already. @type fd: L{int} @param addressFamily: The address family (sometimes called I{domain}) of the existing socket. For example, L{socket.AF_INET}. @type addressFamily: L{int} @param protocol: A C{DatagramProtocol} instance which will be connected to the C{port}. @type protocol: L{twisted.internet.protocol.DatagramProtocol} @param maxPacketSize: The maximum packet size to accept. @type maxPacketSize: L{int} @return: A new instance of C{cls} wrapping the socket given by C{fd}. @rtype: L{Port} rN)r&r,r%)socketfromfd socketType getsockname_preexistingSocket) clsr,fd addressFamilyr$r%r#r&r*r-r-r._fromListeningDescriptorys zPort._fromListeningDescriptorreturncCs2|jdurd|jjd|jdSd|jjdS)Nz not connected>)rr$ __class__r*r-r-r.__repr__s z Port.__repr__cC|jS)z) Return a socket object. )r/r<r-r-r. getHandlezPort.getHandlecCs||dS)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.startListenings zPort.startListeningc Cs|jdur*z|}||j|jfWnty)}z t|j|j|d}~ww|j}d|_|d|_ t d| |j |j fd|_||_|jj|_dS)aJ Prepare and assign a L{socket.socket} instance to C{self.socket}. Either creates a new SOCK_DGRAM L{socket.socket} bound to C{self.interface} and C{self.port} or takes an existing L{socket.socket} provided via the L{interfaces.IReactorSocket.adoptDatagramPort} interface. Nz%s starting on %s)r3createInternetSocketbindr&r#OSErrorrCannotListenErrorr2rrmsg _getLogPrefixr$ connectedr/filenor*sktler-r-r.rAs& zPort._bindSocketcCs|j||dSN)r$makeConnection startReadingr<r-r-r.rBs  zPort._connectToProtocolc Csd}||jkrsz |j|j\}}Wn0tyB}z$|jd}|tvr*WYd}~dS|tvr=|jr6|j WYd}~dSd}~ww|t |7}|j tj krU|dd}z |j ||Wn tyktYnw||jksdSdS)z= Called when my socket is ready for reading. rN) maxThroughputr/recvfromr%rGargs_sockErrReadIgnore_sockErrReadRefuser(r$connectionRefusedlenr6AF_INET6datagramReceived BaseExceptionrerr)r*readdataaddrsenor-r-r.doReads0       z Port.doReadc Cs|jrO|d|jfvs Jz|j|WStyN}z/|jd}|tkr/||WYd}~S|tkr8t d|t krB|j nWYd}~dSd}~ww|dksUJt |dsqt |dsq|ddkrqt|ddt |ds~|ddkr|jtjkrt|ddt |dr|jtjkrt|ddz|j||WSty}z*|jd}|tkr|||WYd}~S|tkrt d|t krWYd}~dSd}~ww)az Write a datagram. @type datagram: L{bytes} @param datagram: The datagram to be sent. @type addr: L{tuple} containing L{str} as first element and L{int} as second element, or L{None} @param addr: A tuple of (I{stringified IPv4 or IPv6 address}, I{integer port number}); can be L{None} in connected mode. Nrzmessage too longz z0write() only accepts IP addresses, not hostnamesz7IPv6 port write() called with IPv4 or broadcast addressz*IPv4 port write() called with IPv6 address)r(r/sendrGrVrwriterrMessageLengthErrorrr$rYr isIPAddress isIPv6AddressInvalidAddressErrorr6r[AF_INETsendto)r*datagramrarbrcr-r-r.rfsb            z Port.writecCs|d||dS)a Write a datagram constructed from an iterable of L{bytes}. @param seq: The data that will make up the complete datagram to be written. @type seq: an iterable of L{bytes} @type addr: L{tuple} containing L{str} as first element and L{int} as second element, or L{None} @param addr: A tuple of (I{stringified IPv4 or IPv6 address}, I{integer port number}); can be L{None} in connected mode. N)rfjoin)r*seqrar-r-r. writeSequence@s zPort.writeSequencecCsL|jrtdt|st|st|d||f|_|j||fdS)z- 'Connect' to remote server. z:already connected, reconnecting is not currently supportednot an IPv4 or IPv6 address.N) r( RuntimeErrorrrhrirrjr/connect)r*hostr#r-r-r.rtOs  z Port.connectcCs&||jr|jd|jdSdS)Nr) stopReadingrKr, callLaterconnectionLostr<r-r-r._loseConnection\szPort._loseConnectioncCs&|jr t}|_nd}||SrP)rKrDeferreddry)r*resultr-r-r. stopListeningas zPort.stopListeningcCstjdtdd|dS)Nz-Please use stopListening() to disconnect portrS) stacklevel)warningswarnDeprecationWarningr}r<r-r-r.loseConnectionis  zPort.loseConnectioncCshtd|jd|_d|_tj|||j|j |` |` t |dr2|j d|` dSdS)z& Cleans up my socket. z(UDP Port %s Closed)Nr{)rrIrrTrr!rxr$doStopr/closerLhasattrr{callback)r*reasonr-r-r.rxqs    zPort.connectionLostcCs||j}d||_dS)zP Initialize the C{logstr} attribute to be used by C{logPrefix}. z%s (UDP)N)rJr$logstr)r* logPrefixr-r-r.r's zPort.setLogStrcCsHt|jr tj|_dSt|jrtj|_dS|jr"t |jddS)z8 Resolve address family for the socket. rrN) rrir&r/r[r6rhrkrrjr<r-r-r.r)s    zPort._setAddressFamilycCr>)z0 Return the prefix to log with. )rr<r-r-r.rr@zPort.logPrefixcCsR|j}|jtjkrtjdg|RS|jtjkr'tjdg|ddRSdS)z Return the local address of the UDP connection @returns: the local address of the UDP connection @rtype: L{IPv4Address} or L{IPv6Address} UDPNrS)r/r2r6rkr IPv4Addressr[ IPv6Addressr*rar-r-r.getHosts   z Port.getHostcCs|jtjtj|dS)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)r*enabledr-r-r.setBroadcastAllowedszPort.setBroadcastAllowedcCst|jtjtjS)z Checks if broadcast is currently allowed on this port. @return: Whether this port may broadcast. @rtype: L{bool} )boolr/ getsockoptrrr<r-r-r.getBroadcastAllowedszPort.getBroadcastAllowed)rr NrP)&__name__ __module__ __qualname____doc__r/rkr6 SOCK_DGRAMr1rTrrint__annotations__r3r" classmethodr7strr=r?rCrArBrdrfrqrtryr}rrxr'r)rrrrr-r-r-r.r>s:   + # >    rc@sleZdZdZddZddZddZdd Zd d Zd d Z ddZ dddZ ddZ ddZ dddZdS)MulticastMixinz, Implement multicast functionality. cCs$|jtjtj}ttd|S)Nz@i)r/r IPPROTO_IPIP_MULTICAST_IF inet_ntoastructpack)r*ir-r-r.getOutgoingInterfacesz#MulticastMixin.getOutgoingInterfacecCs|j||jS)zReturns Deferred of success.)r,resolve addCallback _setInterfacerr-r-r.setOutgoingInterfacesz#MulticastMixin.setOutgoingInterfacecCs"t|}|jtjtj|dS)NrD)r/ inet_atonrrr)r*rarr-r-r.rs zMulticastMixin._setInterfacecC|jtjtjSrP)r/rrIP_MULTICAST_LOOPr<r-r-r.getLoopbackModezMulticastMixin.getLoopbackModecCs(tdt|}|jtjtj|dS)Nb)rrrr/rrr)r*moder-r-r.setLoopbackModeszMulticastMixin.setLoopbackModecCrrP)r/rrIP_MULTICAST_TTLr<r-r-r.getTTLrzMulticastMixin.getTTLcCs$td|}|jtjtj|dS)NB)rrr/rrr)r*ttlr-r-r.setTTLs zMulticastMixin.setTTLrcC|j||j|dS)z4Join a multicast group. Returns Deferred of success.rDr,rr _joinAddr1r*rar&r-r-r. joinGroupzMulticastMixin.joinGroupcCs|j||j||SrP)r,rr _joinAddr2)r*rar&ror-r-r.rszMulticastMixin._joinAddr1c Cst|}t|}|rtj}ntj}z|jtj|||WdStyA}ztt j ||g|j RWYd}~Sd}~wwrP) r/rIP_ADD_MEMBERSHIPIP_DROP_MEMBERSHIPrrrGrFailurerMulticastJoinErrorrV)r*r&rarocmder-r-r.rs  (zMulticastMixin._joinAddr2cCr)z2Leave multicast group, return Deferred of success.rrrr-r-r. leaveGrouprzMulticastMixin.leaveGroupN)r)rrrrrrrrrrrrrrrr-r-r-r.rs  rc@s*eZdZdZ    d ddZdd ZdS) MulticastPortz. UDP Port that supports multicasting. rr NFcCst||||||||_dS)zX @see: L{twisted.internet.interfaces.IReactorMulticast.listenMulticast} N)rr"listenMultiple)r*r#r+r&r%r,rr-r-r.r"s zMulticastPort.__init__c Cs~t|}|jr=|tjtjdttdr=z |tjtjdW|St y<}z|j t kr0nWYd}~|Sd}~ww|S)NrD SO_REUSEPORT) rrErrr/r SO_REUSEADDRrrrGerrnorrMr-r-r.rEs    z"MulticastPort.createInternetSocket)rr NF)rrrrr"rEr-r-r-r.rs r).rr/rrtypingrzope.interfacertwisted.python.runtimerrrrrr r r r r rrrWrXrrrrrtwisted.internetrrrrrrtwisted.pythonrrIListeningPort IUDPTransport ISystemHandler!rrIMulticastTransportrr-r-r-r.s>     $     |8