def ProxyBroadcast(self, method, *args): with bluepy.Timer('machoNet::ProxyBroadcast'): callTimer = base.CallTimer( 'ProxyBroadcast::%s (Broadcast\\Client)' % method) try: self.ForwardNotifyDown( macho.Notification(destination=macho.MachoAddress( broadcastID=method, idtype='+nodeID', narrowcast=self.machoNet.GetConnectedProxyNodes()), payload=(1, args))) if macho.mode == 'proxy': if method.startswith('Process'): sm.ChainEventWithoutTheStars(method, args) elif method.startswith('Do'): sm.SendEventWithoutTheStars(method, args) else: sm.ScatterEventWithoutTheStars(method, args) finally: callTimer.Done()
def StartServiceRun(self, svc, args, namen): try: t0 = time.clock() try: if boot.role == 'client' and getattr( prefs, 'clientServicesWait', 'true').lower() != 'true': svc.state = service.SERVICE_RUNNING svc.Run(*args) else: svc.state = service.SERVICE_START_PENDING with bluepy.Timer('StartService::ServiceStartRun::' + namen): svc.Run(*args) svc.state = service.SERVICE_RUNNING if getattr(boot, 'replaceDependencyServiceWrappers', 'false').lower() == 'true': for depName in self.dependants[namen]: depSvc = self.StartService(depName) setattr(depSvc, namen, svc) finally: t = time.clock() - t0 except Exception as e: svc.state = service.SERVICE_FAILED svc.__error__ = sys.exc_info() self.LogError('Failed to start service %s' % namen) raise self.startupTimes[namen] = t if t < 60: svc.LogInfo('Service', namen, 'required %-3.3f' % t, ' seconds to startup') else: svc.LogWarn('Service', namen, 'startup took %-3.3f' % t, ' seconds') serviceStartupTimeTxt = 'Service %s Startup time: %-3.3fs' % (namen, t) print serviceStartupTimeTxt self.LogNotice(serviceStartupTimeTxt)
def Read(self): self.currentReaders += 1 try: thePickle = self.transport.Read() finally: self.currentReaders -= 1 if getattr(self, 'userID', None) and len(thePickle) > 100000: self.machoNet.LogWarn( 'Read a ', len(thePickle), ' byte packet (before decompression) from userID=', getattr(self, 'userID', 'non-user'), ' on address ', self.transport.address) elif len(thePickle) > 5000000: self.machoNet.LogWarn( 'Read a ', len(thePickle), ' byte packet (before decompression) from userID=', getattr(self, 'userID', 'non-user'), ' on address ', self.transport.address) if thePickle[0] not in '}~': before = len(thePickle) try: with bluepy.Timer( 'machoNet::MachoTransport::Read::DeCompress'): thePickle = zlib.decompress(thePickle) except zlib.error as e: raise RuntimeError('Decompression Failure: ' + strx(e)) after = len(thePickle) if after <= before: self.machoNet.LogError('Decompress shrank data from ', before, ' to ', after, ' bytes') else: self.machoNet.decompressedBytes.Add(after - before) if getattr(self, 'userID', None) and len(thePickle) > 100000: self.machoNet.LogWarn( 'Read a ', len(thePickle), ' byte packet (after decompression, if appropriate) from userID=', getattr(self, 'userID', 'non-user'), ' on address ', self.transport.address) elif len(thePickle) > 5000000: self.machoNet.LogWarn( 'Read a ', len(thePickle), ' byte packet (after decompression, if appropriate) from userID=', getattr(self, 'userID', 'non-user'), ' on address ', self.transport.address) if self.clientID: self.machoNet.dataReceived.Add(len(thePickle)) else: self.machoNet.dataReceived.AddFrom(self.nodeID, len(thePickle)) try: message = macho.Loads(thePickle) except GPSTransportClosed as e: self.transport.Close(**e.GetCloseArgs()) raise except StandardError: if self.transportName == 'tcp:packet:client': self._LogPotentialAttackAndClose(thePickle) raise message.SetPickle(thePickle) if macho.mode == 'client' and message.source.addressType == const.ADDRESS_TYPE_NODE and message.destination.addressType == const.ADDRESS_TYPE_BROADCAST: message.oob['sn'] = self.machoNet.notifySequenceIDByNodeID[ message.source.nodeID] self.machoNet.notifySequenceIDByNodeID[message.source.nodeID] += 1 if self.transportName == 'tcp:packet:client': message.source = macho.MachoAddress(clientID=self.clientID, callID=message.source.callID) if message.contextKey is not None or message.applicationID is not None or message.languageID is not None: self._LogPotentialAttackAndClose(thePickle) raise StandardError( 'Packet containing contextKey received on a client transport. Hack?' ) if hasattr(self, 'userID'): message.userID = self.userID if message.command != const.cluster.MACHONETMSG_TYPE_MOVEMENTNOTIFICATION or MACHONET_LOGMOVEMENT: self.LogInfo('Read: ', message) if macho.mode == 'proxy': for objectID, refID in message.oob.get('OID-', {}).iteritems(): s = self.sessions.get(self.clientID, None) if s is None: s = self.sessions.get(self.nodeID, None) if s is not None: s.UnregisterMachoObject(objectID, refID) if macho.mode == 'server': ls = GetLocalStorage() ls['applicationID'] = message.applicationID ls['languageID'] = message.languageID return message
def Write(self, message, jitSession=1): if macho.mode == 'proxy' and jitSession: if message.source.addressType == const.ADDRESS_TYPE_CLIENT: self._JitSessionToOtherSide(message.source.clientID) elif base.IsInClientContext() and session and hasattr( session, 'clientID'): clientID = session.clientID self._JitSessionToOtherSide(clientID) message.contextKey = clientID ls = GetLocalStorage() message.applicationID = ls.get('applicationID', None) message.languageID = ls.get('languageID', None) if hasattr(self, 'userID'): message.userID = self.userID if message.source.addressType == const.ADDRESS_TYPE_ANY and not message.command % 2: message.source.nodeID = self.machoNet.nodeID message.source.addressType = const.ADDRESS_TYPE_NODE message.Changed() elif message.source.addressType == const.ADDRESS_TYPE_NODE and message.source.nodeID is None: message.source.nodeID = self.machoNet.nodeID message.Changed() thePickle = message.GetPickle() if message.command != const.cluster.MACHONETMSG_TYPE_MOVEMENTNOTIFICATION or MACHONET_LOGMOVEMENT: self.LogInfo('Write: ', message) if self.transportName != 'tcp:packet:machoNet' and message.compressedPart * 100 / len( thePickle ) < self.compressionPercentageThreshold and len( thePickle ) - message.compressedPart > self.compressionThreshold and not MACHONET_COMPRESSION_DISABLED: before = len(thePickle) try: with bluepy.Timer('machoNet::MachoTransport::Write::Compress'): compressed = zlib.compress(thePickle, 1) except zlib.error as e: raise RuntimeError('Compression Failure: ' + strx(e)) after = len(compressed) if after > before: self.LogInfo('Compress would have exploded data from ', before, ' to ', after, ' bytes. Sending uncompressed.') elif (before - after) * 100 / before <= 5: self.LogInfo( "Compress didn't help one bit. Would have compressed data from ", before, ' to ', after, " bytes, which is insignificant. Sending uncompressed, rather than wasting the recipient's CPU power for nothing." ) else: thePickle = compressed self.machoNet.compressedBytes.Add(before - after) if self.transportName == 'tcp:packet:client' and macho.mode == 'proxy': for objectID, refID in message.oob.get('OID+', {}).iteritems(): s = self.sessions.get(self.clientID, None) if s is not None: s.RegisterMachoObject(objectID, None, refID) if self.largePacketLogSpamThreshold != None and len( thePickle) > self.largePacketLogSpamThreshold: log.LogTraceback( extraText= 'Packet larger than the %d byte largePacketLogSpamTreshhold being written out to wire (%d > %d)' % (self.largePacketLogSpamThreshold, len(thePickle), self.largePacketLogSpamThreshold)) if len(thePickle) > self.dropPacketThreshold: if self.transportName == 'tcp:packet:client' or macho.mode == 'server' and ( message.destination.addressType == const.ADDRESS_TYPE_CLIENT or message.destination.addressType == const.ADDRESS_TYPE_BROADCAST and message.destination.idtype not in ('nodeID', '+nodeID')): self.machoNet.LogError( 'Attempted to send a deadly (len=', len(thePickle), ') packet to client(s), PACKET DROPPED') self.machoNet.LogError('Packet =', repr(message)[:1024]) self.machoNet.LogError('Pickle starts with =', repr(thePickle)[:1024]) return self.transport.Write(thePickle) self.machoNet.dataSent.Add(len(thePickle))
def Read(self, *args, **keywords): with bluepy.Timer('Socket::GPS::Read'): if stackless.getcurrent().is_main: raise RuntimeError( "You can't Read from a socket in a synchronous manner without blocking, dude." ) try: while True: if self.packetNumber in self.packetQueue: r = self.packetQueue[self.packetNumber] serial = self.packetNumber del self.packetQueue[self.packetNumber] log.LogInfo('[Packet Order] address:', self.address, 'removed packet', self.packetNumber, 'from reordering map (queue:', len(self.packetQueue), 'elems)') break else: value = self.socket.recvpacketoob() if value is not None: r, oob, serial = value if self.packetNumber == -1: self.packetNumber = serial if self.packetNumber < serial: log.LogInfo('[Packet Order] address:', self.address, 'got', serial, 'expected', self.packetNumber, ', adding to map (queue:', len(self.packetQueue), ' elems)') self.packetQueue[serial] = r self.numReorderedPackets += 1 continue elif self.packetNumber > serial: log.LogError('[Packet Order] address:', self.address, 'got', serial, 'expected', self.packetNumber, ', dropping old packet (queue:', len(self.packetQueue), ' elems)') continue break else: r = None break self.packetNumber += 1 except socket.error as e: if e[0] == errno.WSAENOBUFS: log.LogException() self.Close(localization.GetByLabel( '/Carbon/MachoNet/SocketWasClosed'), exception=e) raise GPSTransportClosed(**self.closeReason) except Exception as e: if isinstance( e, RuntimeError ) and e.args and 'too large a packet' in e.args[0]: self.Close(localization.GetByLabel( '/Carbon/MachoNet/ConnectionWasClosed'), exception=e) raise GPSTransportClosed(**self.closeReason) self.Close(localization.GetByLabel( '/Carbon/MachoNet/SomethingHappenedSocketWasClosed'), exception=e) log.LogTraceback() raise if r is None: self.Close( localization.GetByLabel( '/Carbon/MachoNet/ConnectionWasClosed')) raise GPSTransportClosed(**self.closeReason) if self.socketStatsEnabled: self.statsBytesReadPerPacket.AddSample(len(r)) self.statsBytesRead.Add(len(r)) self.statsPacketsRead.Add() return r
def _CreateEntity(self, entity, loadSemaphore, initData): if loadSemaphore is not None: loadSemaphore.wait() with bluepy.Timer('EntityService::_SetupComponents'): self._SetupComponents(entity, initData)