def enablePktInfo(self, flag=1): if (not hasattr(self.socket, 'sendmsg') or not hasattr(self.socket, 'recvmsg')): raise error.CarrierError( 'sendmsg()/recvmsg() interface is not supported by this OS ' 'and/or Python version') try: if self.socket.family == socket.AF_INET: self.socket.setsockopt(socket.SOL_IP, socket.IP_PKTINFO, flag) if self.socket.family == socket.AF_INET6: self.socket.setsockopt(socket.SOL_IPV6, socket.IPV6_RECVPKTINFO, flag) except socket.error as exc: raise error.CarrierError( 'setsockopt() for %s failed: ' '%s' % (self.socket.family == socket.AF_INET6 and "IPV6_RECVPKTINFO" or "IP_PKTINFO", exc)) self._sendto = sockmsg.getSendTo(self.ADDRESS_TYPE) self._recvfrom = sockmsg.getRecvFrom(self.ADDRESS_TYPE) debug.logger & debug.FLAG_IO and debug.logger( 'enablePktInfo: %s option %s on socket ' '%s' % (self.socket.family == socket.AF_INET6 and "IPV6_RECVPKTINFO" or "IP_PKTINFO", flag and "enabled" or "disabled", self.socket.fileno())) return self
def enablePktInfo(self, flag=1): if (not hasattr(self.socket, 'sendmsg') or not hasattr(self.socket, 'recvmsg')): raise error.CarrierError( 'sendmsg()/recvmsg() interface is not supported by this OS and/or Python version' ) try: if self.socket.family in (socket.AF_INET, socket.AF_INET6): self.socket.setsockopt(socket.SOL_IP, socket.IP_PKTINFO, flag) if self.socket.family == socket.AF_INET6: self.socket.setsockopt(socket.SOL_IPV6, socket.IPV6_RECVPKTINFO, flag) except socket.error: raise error.CarrierError( 'setsockopt() for %s failed: %s' % (self.socket.family == socket.AF_INET6 and "IPV6_RECVPKTINFO" or "IP_PKTINFO", sys.exc_info()[1])) self._sendto = sockmsg.getSendTo(self.addressType) self._recvfrom = sockmsg.getRecvFrom(self.addressType) debug.logger & debug.flagIO and debug.logger( 'enablePktInfo: %s option %s on socket %s' % (self.socket.family == socket.AF_INET6 and "IPV6_RECVPKTINFO" or "IP_PKTINFO", flag and "enabled" or "disabled", self.socket.fileno())) return self
def __init__(self, sock=None, sockMap=None): asyncore.dispatcher.__init__(self) if sock is None: if self.sockFamily is None: raise error.CarrierError( 'Address family %s not supported' % self.__class__.__name__ ) if self.sockType is None: raise error.CarrierError( 'Socket type %s not supported' % self.__class__.__name__ ) try: sock = socket.socket(self.sockFamily, self.sockType) except socket.error: raise error.CarrierError('socket() failed: %s' % sys.exc_info()[1]) try: for b in socket.SO_RCVBUF, socket.SO_SNDBUF: bsize = sock.getsockopt(socket.SOL_SOCKET, b) if bsize < self.bufferSize: sock.setsockopt(socket.SOL_SOCKET, b, self.bufferSize) debug.logger & debug.flagIO and debug.logger('%s: socket %d buffer size increased from %d to %d for buffer %d' % (self.__class__.__name__, sock.fileno(), bsize, self.bufferSize, b)) except Exception: debug.logger & debug.flagIO and debug.logger('%s: socket buffer size option mangling failure for buffer: %s' % (self.__class__.__name__, sys.exc_info()[1])) # The socket map is managed by the AsyncoreDispatcher on # which this transport is registered. Here we just prepare # socket and postpone transport registration at dispatcher # till AsyncoreDispatcher invokes registerSocket() sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) sock.setblocking(0) self.set_socket(sock)
def _cbFun(self, incomingTransport, transportAddress, incomingMessage): for name, transport in self.__transports.items(): if transport is incomingTransport: transportDomain = name break else: raise error.CarrierError('Unregistered transport %s' % (incomingTransport, )) if self.__recvCbFun is None: raise error.CarrierError( 'Receive callback not registered -- loosing incoming event') self.__recvCbFun(self, transportDomain, transportAddress, incomingMessage)
def sendMessage(self, outgoingMessage, transportDomain, transportAddress): if transportDomain in self.__transports: self.__transports[transportDomain].sendMessage( outgoingMessage, transportAddress) else: raise error.CarrierError('No suitable transport domain for %s' % (transportDomain, ))
def registerRecvCbFun(self, recvCb, recvId=None): if recvId in self.__recvCallables: raise error.CarrierError( 'Receive callback %r already registered' % (recvId is None and '<default>' or recvId, )) self.__recvCallables[recvId] = recvCb
def openServerMode(self, iface=None): try: self._lport = reactor.listenUNIXDatagram(iface, self) except Exception as why: raise error.CarrierError(why) return self
def unregisterTransport(self, tDomain): if tDomain not in self.__transports: raise error.CarrierError('Transport %s not registered' % (tDomain, )) self.__transports[tDomain].unregisterCbFun() del self.__transportDomainMap[self.__transports[tDomain]] del self.__transports[tDomain]
def registerTransport(self, tDomain, transport): if tDomain in self.__transports: raise error.CarrierError('Transport %s already registered' % (tDomain, )) transport.registerCbFun(self._cbFun) self.__transports[tDomain] = transport self.__transportDomainMap[transport] = tDomain
def handle_read(self): try: incomingMessage, transportAddress = self._recvfrom( self.socket, 65535) transportAddress = self.normalizeAddress(transportAddress) debug.logger & debug.flagIO and debug.logger( 'handle_read: transportAddress %r -> %r incomingMessage (%d octets) %s' % (transportAddress, transportAddress.getLocalAddress(), len(incomingMessage), debug.hexdump(incomingMessage))) if not incomingMessage: self.handle_close() return else: self._cbFun(self, transportAddress, incomingMessage) return except socket.error: if sys.exc_info()[1].args[0] in sockErrors: debug.logger & debug.flagIO and debug.logger( 'handle_read: known socket error %s' % (sys.exc_info()[1], )) sockErrors[sys.exc_info()[1].args[0]] and self.handle_close() return else: raise error.CarrierError('recvfrom() failed: %s' % (sys.exc_info()[1], ))
def openClientMode(self, iface=None): if iface is not None: try: self.socket.bind(iface) except socket.error as why: raise error.CarrierError('bind() failed: %s' % (why, )) return self
def openServerMode(self, iface): try: self._lport = reactor.listenUNIXDatagram(iface, self) except Exception: raise error.CarrierError(sys.exc_info()[1]) return self
def openServerMode(self, iface): try: self.socket.bind(iface) except socket.error as why: raise error.CarrierError('bind() failed: %s' % (why, )) self._iface = iface return self
def handle_read(self): try: incomingMessage, transportAddress = self._recvfrom( self.socket, 65535) transportAddress = self.normalizeAddress(transportAddress) debug.logger & debug.FLAG_IO and debug.logger( 'handle_read: transportAddress %r -> %r incomingMessage (%d ' 'octets) %s' % (transportAddress, transportAddress.getLocalAddress(), len(incomingMessage), debug.hexdump(incomingMessage))) if not incomingMessage: self.handle_close() return else: self._cbFun(self, transportAddress, incomingMessage) return except socket.error as exc: if exc.args[0] in SOCK_ERRORS: debug.logger & debug.FLAG_IO and debug.logger( 'handle_read: known socket error %s' % exc) SOCK_ERRORS[exc.args[0]] and self.handle_close() return else: raise error.CarrierError('recvfrom() failed: %s' % exc)
def handle_write(self): outgoingMessage, transportAddress = self.__outQueue.pop(0) debug.logger & debug.FLAG_IO and debug.logger( 'handle_write: transportAddress %r -> %r outgoingMessage (%d ' 'octets) %s' % (transportAddress.getLocalAddress(), transportAddress, len(outgoingMessage), debug.hexdump(outgoingMessage))) if not transportAddress: debug.logger & debug.FLAG_IO and debug.logger( 'handle_write: missing dst address, loosing outgoing msg') return try: self._sendto(self.socket, outgoingMessage, transportAddress) except socket.error as exc: if exc.args[0] in SOCK_ERRORS: debug.logger & debug.FLAG_IO and debug.logger( 'handle_write: ignoring socket error %s' % exc) else: raise error.CarrierError('sendto() failed for %s: %s' % (transportAddress, exc))
def datagramReceived(self, datagram, transportAddress): if self._cbFun is None: raise error.CarrierError('Unable to call cbFun') else: # Callback fun is called through callLater() in attempt # to make Twisted timed calls work under high load. reactor.callLater(0, self._cbFun, self, transportAddress, datagram)
def openServerMode(self, iface): try: self._lport = reactor.listenUDP(iface[1], self, iface[0]) except Exception as exc: raise error.CarrierError(exc) return self
def openClientMode(self, iface=''): try: self._lport = reactor.connectUNIXDatagram(iface, self) except Exception as exc: raise error.CarrierError(exc) return self
def enableTransparent(self, flag=1): try: if self.socket.family == socket.AF_INET: self.socket.setsockopt( socket.SOL_IP, socket.IP_TRANSPARENT, flag ) if self.socket.family == socket.AF_INET6: self.socket.setsockopt( socket.SOL_IPV6, socket.IP_TRANSPARENT, flag ) except socket.error: raise error.CarrierError('setsockopt() for IP_TRANSPARENT failed: %s' % sys.exc_info()[1]) except OSError: raise error.CarrierError('IP_TRANSPARENT socket option requires superuser priveleges') debug.logger & debug.flagIO and debug.logger('enableTransparent: %s option IP_TRANSPARENT on socket %s' % (flag and "enabled" or "disabled", self.socket.fileno())) return self
def openClientMode(self, iface=None): if iface is not None: try: self.socket.bind(iface) except socket.error: raise error.CarrierError( 'bind() for %s failed: %s' % (iface is None and "<all local>" or iface, sys.exc_info()[1])) return self
def openServerMode(self, iface): try: self.socket.bind(iface) except socket.error as exc: raise error.CarrierError('bind() for %s failed: %s' % (iface, exc)) return self
def openClientMode(self, iface=None): if iface is None: iface = ('', 0) try: self._lport = reactor.listenUDP(iface[1], self, iface[0]) except Exception: raise error.CarrierError(sys.exc_info()[1]) return self
def openServerMode(self, iface): try: c = self.loop.create_datagram_endpoint( lambda: self, local_addr=iface, family=self.sockFamily ) self._lport = asyncio.async(c) except Exception: raise error.CarrierError(';'.join(traceback.format_exception(*sys.exc_info()))) return self
def sendMessage(self, outgoingMessage, transportAddress): debug.logger & debug.flagIO and debug.logger('startProtocol: %s transportAddress %r outgoingMessage %s' % ((self.transport is None and "queuing" or "sending"), transportAddress, debug.hexdump(outgoingMessage))) if self.transport is None: self._writeQ.append((outgoingMessage, transportAddress)) else: try: self.transport.write(outgoingMessage, transportAddress) except Exception: raise error.CarrierError('Twisted exception: %s' % (sys.exc_info()[1],))
def startProtocol(self): debug.logger & debug.flagIO and debug.logger('startProtocol: invoked') while self._writeQ: outgoingMessage, transportAddress = self._writeQ.pop(0) debug.logger & debug.flagIO and debug.logger('startProtocol: transportAddress %r outgoingMessage %s' % (transportAddress, debug.hexdump(outgoingMessage))) try: self.transport.write(outgoingMessage, transportAddress) except Exception: raise error.CarrierError('Twisted exception: %s' % (sys.exc_info()[1],))
def enableBroadcast(self, flag=1): try: self.socket.setsockopt( socket.SOL_SOCKET, socket.SO_BROADCAST, flag ) except socket.error: raise error.CarrierError('setsockopt() for SO_BROADCAST failed: %s' % (sys.exc_info()[1],)) debug.logger & debug.flagIO and debug.logger('enableBroadcast: %s option SO_BROADCAST on socket %s' % (flag and "enabled" or "disabled", self.socket.fileno())) return self
def openServerMode(self, iface): try: self.socket.bind(iface) except socket.error: raise error.CarrierError('bind() for %s failed: %s' % ( iface, sys.exc_info()[1], )) return self
def __init__(self, sock=None, sockMap=None): if sock is None: if self.sockFamily is None: raise error.CarrierError('Address family %s not supported' % self.__class__.__name__) if self.sockType is None: raise error.CarrierError('Socket type %s not supported' % self.__class__.__name__) try: sock = socket.socket(self.sockFamily, self.sockType) except socket.error: raise error.CarrierError('socket() failed: %s' % sys.exc_info()[1]) if sockMap is None: # The socket map is managed by the AsynsockDispatcher on # which this transport is registered, so this is a fake # socket map to avoid registering with deafult asyncore map. sockMap = {} asyncore.dispatcher.__init__(self, sock, sockMap)
def _cbFun(self, incomingTransport, transportAddress, incomingMessage): if incomingTransport in self.__transportDomainMap: transportDomain = self.__transportDomainMap[incomingTransport] else: raise error.CarrierError('Unregistered transport %s' % (incomingTransport, )) if self.__routingCbFun: recvId = self.__routingCbFun(transportDomain, transportAddress, incomingMessage) else: recvId = None if recvId in self.__recvCallables: self.__recvCallables[recvId](self, transportDomain, transportAddress, incomingMessage) else: raise error.CarrierError( 'No callback for "%r" found - loosing incoming event' % (recvId, ))
def connection_made(self, transport): self.transport = transport debug.logger & debug.flagIO and debug.logger('connection_made: invoked') while self._writeQ: outgoingMessage, transportAddress = self._writeQ.pop(0) debug.logger & debug.flagIO and debug.logger('connection_made: transportAddress %r outgoingMessage %s' % (transportAddress, debug.hexdump(outgoingMessage))) try: self.transport.sendto(outgoingMessage, self.normalizeAddress(transportAddress)) except Exception: raise error.CarrierError(';'.join(traceback.format_exception(*sys.exc_info())))