def __init__(self, sess, gpcs, objectID, pa, refID): try: self.__dict__['session'] = weakref.proxy(sess) except TypeError: self.__dict__['session'] = sess sys.exc_clear() self.__dict__['objectID'] = objectID self.__dict__['sessionCheck'] = None self.__dict__['persistantObjectID'] = objectID self.__dict__['gpcs'] = weakref.proxy(gpcs) self.__dict__['__publicattributes__'] = pa self.__dict__['objectChangeHandlers'] = weakref.WeakKeyDictionary({}) mask = sess.Masquerade() try: self.__dict__['clisid'] = gpcs.machoNet.GetClientSessionID() finally: mask.UnMask() if objectID[0] == 'C': self.__dict__['blocking'] = 0 cid, oid = objectID.split(':') cid = cid.split('=')[1] self.__dict__['destination'] = macho.MachoAddress(clientID=long(cid)) else: self.__dict__['blocking'] = 1 nid, oid = objectID.split(':') nid = nid.split('=')[1] self.__dict__['destination'] = macho.MachoAddress(nodeID=long(nid)) self.__dict__['deleted'] = 0 sess.RegisterMachoObjectConnection(objectID, self, refID)
def CallUp(self, packet): if getattr(packet.destination, 'service', 0): if packet.payload[1] == 'MachoBindObject': nodeID = None else: nodeID = ClockThis( 'machoNet::GPCS::gpcs.Resolve::CallUp::MachoResolve', sm.StartServiceAndWaitForRunningState( packet.destination.service).MachoResolve, session.GetActualSession()) if type(nodeID) == types.StringType: if packet.command == const.cluster.MACHONETMSG_TYPE_RESOLVE_REQ: return packet.Response(0, nodeID) raise UnMachoDestination("Failed to resolve %s, reason='%s'" % (packet.destination.service, nodeID)) elif nodeID is None: if packet.command == const.cluster.MACHONETMSG_TYPE_RESOLVE_REQ: rsp = packet.Response(1, '') rsp.source = macho.MachoAddress( service=packet.destination.service) return rsp else: if packet.command == const.cluster.MACHONETMSG_TYPE_RESOLVE_REQ: rsp = packet.Response(1, '') rsp.source = macho.MachoAddress( nodeID=nodeID, service=packet.destination.service) return rsp if nodeID != self.machoNet.GetNodeID(): raise WrongMachoNode(nodeID) return self.ForwardCallUp(packet)
def __init__(self, *args, **keywords): self.userID = None self.compressedPart = 0 self.source = macho.MachoAddress() self.destination = macho.MachoAddress() self.contextKey = None self.applicationID = None self.languageID = None self.oob = {} dtc = 0 for each in keywords.iterkeys(): if each != 'donttypecheck': setattr(self, each, keywords[each]) else: dtc = 1 self.command = self.__machodesc__['command'] if not dtc: for each in self.__machodesc__['params']: if each[-1:] != '?': if not hasattr(self, each): raise TypeError('%s requires %s to be specified' % (self.__class__.__name__, each)) self.pickleSize = 0
def GetMachoAddressOfOtherSide(self): if macho.mode == 'client': return macho.MachoAddress(nodeID=self.machoNet.myProxyNodeID) elif self.clientID: return macho.MachoAddress(clientID=self.clientID) else: return macho.MachoAddress(nodeID=self.nodeID)
def _JitSessionToOtherSide(self, clientID): clientTransportID = self.machoNet.transportIDbyClientID[clientID] clientTransport = self.machoNet.transportsByID[clientTransportID] remoteSessionVersion = clientTransport.dependants.get( self.transportID, 0) sess = clientTransport.sessions[clientID] if remoteSessionVersion != sess.version: sessData = {} self.machoNet.LogInfo('JITing session ', sess.sid, ' (clientID ', clientID, '), localVer = ', sess.version, ' remoteVer = ', remoteSessionVersion) if remoteSessionVersion == 0: for v in sess.GetDistributedProps(0): sessData[v] = getattr(sess, v) sessionprops = macho.SessionInitialStateNotification( source=macho.MachoAddress(clientID=clientID), destination=macho.MachoAddress(nodeID=self.nodeID), sid=sess.sid, sessionType=sess.sessionType, initialstate=sessData) else: for v in sess.GetDistributedProps(1): sessData[v] = (None, getattr(sess, v)) sessionprops = macho.SessionChangeNotification( source=macho.MachoAddress(clientID=clientID), destination=macho.MachoAddress(nodeID=self.nodeID), sid=sess.sid, change=(1, sessData)) clientTransport.dependants[self.transportID] = sess.version self.Write(sessionprops, jitSession=0)
def NarrowcastByNodeIDsWithoutTheStars(self, nodeids, method, args, kwargs): if len(nodeids): if 'sourceNodeID' in kwargs: source = macho.MachoAddress(nodeID=kwargs['sourceNodeID'], service=None, callID=None) else: source = macho.MachoAddress() destination = macho.MachoAddress(broadcastID=method, idtype='nodeID', narrowcast=nodeids) self.ForwardNotifyDown(macho.Notification(source=source, destination=destination, payload=(1, args)))
def SinglecastByServiceMaskWithoutTheStars(self, serviceMask, method, args, kwargs): destination = macho.MachoAddress(broadcastID=method, idtype='serviceMask', narrowcast=[serviceMask]) source = macho.MachoAddress() self.ForwardNotifyDown(macho.Notification(source=source, destination=destination, payload=(1, args))) if macho.mode == 'server' and self.machoNet.serviceMask & serviceMask: if method.startswith('Process'): sm.ChainEventWithoutTheStars(method, args) elif method.startswith('Do'): sm.SendEventWithoutTheStars(method, args) else: sm.ScatterEventWithoutTheStars(method, args)
def ClusterBroadcast(self, method, *args): with bluepy.Timer('machoNet::ClusterBroadcast'): callTimer = base.CallTimer('ClusterBroadcast::%s (Broadcast\\Client)' % method) try: self.ForwardNotifyDown(macho.Notification(destination=macho.MachoAddress(broadcastID=method, idtype='nodeID'), payload=(1, args))) self.ForwardNotifyDown(macho.Notification(destination=macho.MachoAddress(broadcastID=method, idtype='+nodeID', narrowcast=self.machoNet.GetConnectedProxyNodes()), payload=(1, args))) 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 SinglecastByWorldSpaceID(self, instanceid, method, *args): with bluepy.Timer('machoNet::SinglecastByWorldSpaceID'): callTimer = base.CallTimer('SinglecastByWorldSpaceID::%s (Broadcast\\Client)' % method) try: self.ForwardNotifyDown(macho.Notification(destination=macho.MachoAddress(broadcastID=method, idtype='worldspaceid', narrowcast=[instanceid]), payload=(1, args))) finally: callTimer.Done()
def NotifyUp(self, packet): if getattr(packet.destination, 'service', 0): nodeID = sm.StartServiceAndWaitForRunningState( packet.destination.service).MachoResolve( session.GetActualSession()) if type(nodeID) == types.StringType: self.machoNet.LogError( 'Resolve failed during notification. Packet lost. Failure reason=', nodeID) raise UnMachoDestination("Failed to resolve %s, reason='%s'" % (packet.destination.service, nodeID)) elif nodeID is None: pass else: thisNodeID = self.machoNet.GetNodeID() if nodeID != thisNodeID: self.machoNet.LogInfo( 'Notification packet recieved on the wrong node(', thisNodeID, '), forwarding to the correct one ', nodeID) packet.destination = macho.MachoAddress( nodeID=nodeID, service=packet.destination.service) proxyID = self.machoNet.GetProxyNodeIDFromClientID( packet.source.clientID) proxyMachoNet = self.machoNet.session.ConnectToRemoteService( 'machoNet', nodeID=proxyID) proxyMachoNet.NoBlock.ForwardNotificationToNode( packet.source, packet.destination, packet.userID, packet.payload) return return self.ForwardNotifyUp(packet)
def ClientBroadcast(self, method, *args): with bluepy.Timer('machoNet::ClientBroadcast'): callTimer = base.CallTimer('ClientBroadcast::%s (Broadcast\\Client)' % method) try: packet = macho.Notification(destination=macho.MachoAddress(broadcastID=method, idtype='clientID'), payload=(1, args)) self.ForwardNotifyDown(packet) finally: callTimer.Done()
def ScattercastWithoutTheStars(self, idtype, ids, method, args): if not idtype.startswith('+'): idtype = '*%s' % idtype if ids: self.ForwardNotifyDown( macho.Notification(destination=macho.MachoAddress( broadcastID=method, idtype=idtype, narrowcast=ids), payload=(1, args)))
def NarrowcastByShipIDs(self, shipids, method, *args): if not shipids: return callTimer = base.CallTimer('NarrowcastByShipIDs::%s (Broadcast\\Client)' % method) try: self.ForwardNotifyDown(macho.Notification(destination=macho.MachoAddress(broadcastID=method, idtype='shipid', narrowcast=shipids), payload=(1, args))) finally: callTimer.Done()
def NarrowcastBySolarSystemID2s(self, solarsystemid2s, method, *args): if not solarsystemid2s: return callTimer = base.CallTimer('NarrowcastBySolarSystemID2s::%s (Broadcast\\Client)' % method) try: self.ForwardNotifyDown(macho.Notification(destination=macho.MachoAddress(broadcastID=method, idtype='solarsystemid2', narrowcast=solarsystemid2s), payload=(1, args))) finally: callTimer.Done()
def NarrowcastByCharIDs(self, charids, method, *args): if not charids: return with bluepy.Timer('machoNet::NarrowcastByCharIDs'): callTimer = base.CallTimer('NarrowcastByCharIDs::%s (Broadcast\\Client)' % method) try: self.ForwardNotifyDown(macho.Notification(destination=macho.MachoAddress(broadcastID=method, idtype='charid', narrowcast=charids), payload=(1, args))) finally: callTimer.Done()
def SessionChanged(self, clientID, sid, change, nodesOfInterest=None): """ Called by CoreSession.SetAttributes() of 'clientID' client session 'sid' after applying 'change' to the session """ if nodesOfInterest: tmp = [] for each in nodesOfInterest: if type(each) == types.ListType or type( each) == types.TupleType: for other in each: if other and other not in tmp: tmp.append(other) elif (type(each) == types.IntType or type(each) == types.LongType) and each not in tmp: tmp.append(each) nodesOfInterest = tmp packet = macho.SessionChangeNotification( destination=macho.MachoAddress(clientID=clientID), sid=sid, change=(0, change), nodesOfInterest=nodesOfInterest) if macho.mode == 'proxy': transport = self.machoNet.GetMachoTransportByClientID(clientID) if transport is not None: nodesOfInterest = getattr(packet, 'nodesOfInterest', None) if nodesOfInterest is None or -1 in nodesOfInterest: if nodesOfInterest is None: nodesOfInterest = [] for each in self.machoNet.GetMachoTransportsByTransportIDs( transport.dependants.iterkeys()): if each.nodeID not in nodesOfInterest: nodesOfInterest.append(each.nodeID) for each in nodesOfInterest: if each != -1: c = copy.copy(packet) c.source = macho.MachoAddress(clientID=clientID) c.destination = macho.MachoAddress(nodeID=each) self.ForwardNotifyDown(c) self.ForwardNotifyDown(packet)
def SinglecastByCorporationID(self, corpid, method, *args): callTimer = base.CallTimer( 'SinglecastByCorporationID::%s (Broadcast\\Client)' % method) try: self.ForwardNotifyDown( macho.Notification(destination=macho.MachoAddress( broadcastID=method, idtype='corpid', narrowcast=[corpid]), payload=(1, args))) finally: callTimer.Done()
def NarrowcastToObservers(self, sourceEntityID, method, *args): with bluepy.Timer('machoNet::NarrowcastToObservers'): callTimer = base.CallTimer('NarrowcastToObservers::%s (Broadcast\\Client)' % method) try: if not self.apertureService: self.apertureService = sm.GetService('apertureServer') charids = self.apertureService.GetSubjectObservers(sourceEntityID) if charids: self.ForwardNotifyDown(macho.Notification(destination=macho.MachoAddress(broadcastID=method, idtype='charid', narrowcast=charids), payload=(1, args))) finally: callTimer.Done()
def SinglecastBySolarSystemID2(self, solarsystemid2, method, *args): callTimer = base.CallTimer( 'SinglecastBySolarSystemID2::%s (Broadcast\\Client)' % method) try: self.ForwardNotifyDown( macho.Notification(destination=macho.MachoAddress( broadcastID=method, idtype='solarsystemid2', narrowcast=[solarsystemid2]), payload=(1, args))) finally: callTimer.Done()
def InvalidateCachedObjects(self, objectIDs, forward=1): deleted = 0 for each in objectIDs: if each in self.cachedMethodCalls: del self.cachedMethodCalls[each] self.__CacheIsDirty('cachedMethodCalls', each) if type(each) in (types.TupleType, types.ListType): objectID = each[0] version = each[1] else: objectID = each version = None if objectID in self.cachedObjects and not isinstance( self.cachedObjects[objectID], uthread.Semaphore): if version is None or self.__OlderVersion( self.cachedObjects[objectID].version, version): del self.cachedObjects[objectID] self.__CacheIsDirty('cachedObjects', objectID) gpcs = sm.services['machoNet'] gpcs.GetGPCS() if macho.mode == 'client': return if macho.mode == 'proxy': for eachNodeID in sm.services['machoNet'].GetConnectedSolNodes(): gpcs.RemoteServiceNotify( self.session, macho.MachoAddress(nodeID=eachNodeID, service='objectCaching'), 'objectCaching', 'InvalidateCachedObjects', objectIDs, 0) elif forward and sm.services['machoNet'].GetConnectedProxyNodes(): eachNodeID = random.choice( sm.services['machoNet'].GetConnectedProxyNodes()) gpcs.RemoteServiceNotify( self.session, macho.MachoAddress(nodeID=eachNodeID, service='objectCaching'), 'objectCaching', 'InvalidateCachedObjects', objectIDs, 0)
def ServerBroadcast(self, method, *args): with bluepy.Timer('machoNet::ServerBroadcast'): callTimer = base.CallTimer('ServerBroadcast::%s (Broadcast\\Client)' % method) try: self.ForwardNotifyDown(macho.Notification(destination=macho.MachoAddress(broadcastID=method, idtype='nodeID'), payload=(1, args))) if macho.mode == 'server': 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 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 ObjectcastWithoutTheStars(self, object, method, args): objectID = base.GetObjectUUID(object) self.ForwardNotifyDown(macho.Notification(destination=macho.MachoAddress(broadcastID=method, idtype='objectID', narrowcast=[objectID]), payload=(1, args)))
def NotifyUp(self, packet): if packet.command == const.cluster.MACHONETMSG_TYPE_SESSIONCHANGENOTIFICATION: nodesOfInterest = None if macho.mode == 'proxy': nodesOfInterest = getattr(packet, 'nodesOfInterest', None) transport = self.machoNet.GetMachoTransportByClientID( packet.source.clientID) if transport is not None: if nodesOfInterest is None or -1 in nodesOfInterest: if nodesOfInterest is None: nodesOfInterest = [] for each in self.machoNet.GetMachoTransportsByTransportIDs( transport.dependants.iterkeys()): if each.nodeID not in nodesOfInterest: nodesOfInterest.append(each.nodeID) if not getattr(session, 'clientID', 0) and macho.mode != 'client': self.machoNet.LogError( 'Received a session change notification on a non-client session' ) self.machoNet.LogError('Packet=', packet) log.LogTraceback() session.DumpSession( 'NONCLIENT', 'Session change notification received on non-client session' ) else: session.ApplyRemoteAttributeChanges(packet.change[1], initialState=False) if macho.mode == 'proxy' and packet.source.clientID != getattr( session, 'clientID', 0): self.machoNet.LogError( "Session change notification - clientID doesn't match in packet and session" ) self.machoNet.LogError('packet: ', packet.source.clientID, ' details=', packet) self.machoNet.LogError('session: ', getattr(session, 'clientID', 0), ' details=', session) if getattr(session, 'clientID', 0) and macho.mode == 'proxy': if transport is None: self.machoNet.LogWarn( 'Transport is None in session change, nodesOfInterest is ', nodesOfInterest) self.machoNet.LogWarn('session = ', session) elif nodesOfInterest is not None: sessionVersion = session.version + 1 self.machoNet.LogInfo('SessionChangeGPCS: session(', session.sid, ")'s new version number is ", session.version, ' we have ', len(nodesOfInterest), ' noi') for each in nodesOfInterest: if each != packet.destination.nodeID and each != -1: transportOfNode = self.machoNet.GetTransportOfNode( each) transportIsKnown = transport.dependants.has_key( transportOfNode.transportID) if transportIsKnown: transportVersion = transport.dependants[ transportOfNode.transportID] if not transportIsKnown: sessionprops = {} for v in session.GetDistributedProps(0): sessionprops[v] = getattr(session, v) self.ForwardNotifyDown( macho.SessionInitialStateNotification( source=macho.MachoAddress( clientID=session.clientID), destination=macho.MachoAddress( nodeID=each), sid=session.sid, sessionType=session.sessionType, initialstate=sessionprops)) elif sessionVersion > transportVersion: change = {} for v in session.GetDistributedProps(1): change[v] = (None, getattr(session, v)) self.ForwardNotifyDown( macho.SessionChangeNotification( source=macho.MachoAddress( clientID=session.clientID), destination=macho.MachoAddress( nodeID=each), sid=session.sid, change=(1, change))) if macho.mode == 'proxy': packet.source, packet.destination = packet.destination, packet.source self.ForwardNotifyDown(packet) elif packet.command == const.cluster.MACHONETMSG_TYPE_SESSIONINITIALSTATENOTIFICATION: if not getattr(session, 'clientID', 0) and macho.mode != 'client': self.machoNet.LogError( 'Received a session initial state notification on a non-client session' ) self.machoNet.LogError('Packet=', packet) log.LogTraceback() else: session.ApplyRemoteAttributeChanges(packet.initialstate, initialState=True)
def RemoteServiceCallWithoutTheStars(self, sess, nodeID, service, method, args, keywords): while 1: try: if sess is None: self.machoNet.LogError('Session is None during RemoteServiceCall') log.LogTraceback() sessionVars1 = self._GetRemoteServiceCallVariables(sess) mask = sess.Masquerade() try: cachable, versionCheck, throwOK, cachedResultRecord, cacheKey, cacheDetails = sm.GetService('objectCaching').PerformCachedMethodCall(None, service, method, args) if cachable: if not versionCheck: if throwOK: self.LogMethodCall(objectCaching.CacheOK(), service, method + '[Cached]', args, keywords) raise objectCaching.CacheOK() elif cachedResultRecord: self.LogMethodCall(cachedResultRecord['lret'], service, method + '[Cached]', args, keywords) return cachedResultRecord['lret'] if nodeID is None and macho.mode == 'client': nodeID = self.services.get(service, None) if nodeID is None and service in self.machoNet.serviceInfo: where = self.machoNet.serviceInfo[service] if where: for k, v in self.machoNet.serviceInfo.iteritems(): if k != service and v and (v.startswith(where) or where.startswith(v)): nodeID = self.services.get(k, None) break if nodeID is None and self.services and service not in ('DB2',): self.machoNet.LogInfo("I haven't got a clue where ", service, ' should run, although I could guess any of these: ', str(self.services.keys())) if nodeID is None: if macho.mode == 'server': proxies = self.machoNet.GetConnectedProxyNodes() if not proxies: raise UnMachoDestination('No proxy available') destination = macho.MachoAddress(nodeID=random.choice(proxies), service=service) else: destination = macho.MachoAddress(service=service) elif isinstance(nodeID, macho.MachoAddress): destination = nodeID else: destination = macho.MachoAddress(nodeID=nodeID, service=service) if keywords: kw2 = copy.copy(keywords) else: kw2 = {} if kw2.get('machoVersion', None) is None: if cachedResultRecord is not None and cachedResultRecord['version'] is not None: kw2['machoVersion'] = cachedResultRecord['version'] else: kw2['machoVersion'] = 1 if currentcall: machoTimeout = kw2.get('machoTimeout', currentcall.packet.oob.get('machoTimeout', None)) else: machoTimeout = kw2.get('machoTimeout', None) if 'machoTimeout' in kw2: del kw2['machoTimeout'] payload = (1, method, args, kw2) packet = macho.CallReq(destination=destination, payload=payload) if machoTimeout is not None: packet.oob['machoTimeout'] = machoTimeout callTimer = base.CallTimer('%s::%s (ServiceCall\\Client)' % (service, method)) try: ret = self.ForwardCallDown(packet).payload self.UpdateSendServiceCallStats(service, method) self.LogMethodCall(ret, service, method, args, keywords) except util.UpdateMoniker as e: raise except RuntimeError: raise except UserError: raise except ProxyRedirect: raise except WrongMachoNode: raise except objectCaching.CacheOK: if cachedResultRecord is None: raise sys.exc_clear() self.LogMethodCall(cachedResultRecord['lret'], service, method, args, keywords) sm.GetService('objectCaching').UpdateVersionCheckPeriod(cacheKey) return cachedResultRecord['lret'] finally: callTimer.Done() if isinstance(ret, objectCaching.CachedMethodCallResult): sm.GetService('objectCaching').CacheMethodCall(service, method, args, ret) ret = ret.GetResult() return ret finally: mask.UnMask() sessionVars2 = self._GetRemoteServiceCallVariables(sess) except WrongMachoNode as e: sys.exc_clear() self._HandleServiceCallWrongNode(e, service, sessionVars1, sessionVars2) self.services[service] = e.payload if nodeID == e.payload: self.machoNet.LogError('Redirected to same node', nodeID) raise UnMachoDestination('Failed to redirect call, because we were being redirected to the same place we were trying to call in the first place (%s)' % nodeID) else: self.machoNet.LogInfo('Redirecting call to node ', e.payload, ' that was originally intended for node ', nodeID) nodeID = e.payload except UserError as e: if e.msg in ('UnMachoDestination', 'GPSTransportClosed'): self.services.clear() raise except StandardError: if service in self.services: otherNodeID = self.services[service] for s, n in self.services.items()[:]: if n and n in (otherNodeID, nodeID): del self.services[s] raise
def RemoteServiceNotifyWithoutTheStars(self, sess, nodeID, service, method, args, keywords): while 1: try: if sess is None: self.machoNet.LogError('Session is None during RemoteServiceNotify') log.LogTraceback() if nodeID is None and macho.mode == 'client': nodeID = self.services.get(service, None) if nodeID is None and service in self.machoNet.serviceInfo: where = self.machoNet.serviceInfo[service] for k, v in self.machoNet.serviceInfo.iteritems(): if k != service and v == where: nodeID = self.services.get(k, None) break if nodeID is None and self.machoNet.serviceInfo.get(service, None) is not None: self.machoNet.LogInfo("I haven't got a clue where ", service, ' should run, although I could guess any of these: ', str(self.services.keys())) if nodeID is None: if macho.mode == 'server': proxies = self.machoNet.GetConnectedProxyNodes() if not proxies: raise UnMachoDestination('No proxy available') destination = macho.MachoAddress(nodeID=random.choice(proxies), service=service) else: destination = macho.MachoAddress(service=service) elif isinstance(nodeID, macho.MachoAddress): destination = nodeID else: destination = macho.MachoAddress(nodeID=nodeID, service=service) if keywords: kw2 = copy.copy(keywords) else: kw2 = {} if currentcall: machoTimeout = kw2.get('machoTimeout', currentcall.packet.oob.get('machoTimeout', None)) else: machoTimeout = kw2.get('machoTimeout', None) if 'machoTimeout' in kw2: del kw2['machoTimeout'] if kw2: payload = (1, method, args, kw2) else: payload = (1, method, args) packet = macho.Notification(destination=destination, payload=payload) if machoTimeout is not None: packet.oob['machoTimeout'] = machoTimeout mask = sess.Masquerade() try: callTimer = base.CallTimer('%s::%s (ServiceNotify\\Client)' % (service, method)) try: self.ForwardNotifyDown(packet) finally: callTimer.Done() finally: mask.UnMask() except WrongMachoNode as e: sys.exc_clear() self.services[service] = e.payload if nodeID == e.payload: self.machoNet.LogError('Redirected to same node', nodeID) raise UnMachoDestination('Failed to redirect call, because we were being redirected to the same place we were trying to call in the first place (%s)' % nodeID) else: self.machoNet.LogInfo('Redirecting call to node ', e.payload, ' that was originally intended for node ', nodeID) nodeID = e.payload continue except UserError as e: if e.msg in ('UnMachoDestination', 'GPSTransportClosed'): self.services.clear() raise except StandardError: self.services.clear() raise return
def NarrowcastByClientIDsWithoutTheStars(self, clientids, method, args): if len(clientids): packet = macho.Notification(destination=macho.MachoAddress(broadcastID=method, idtype='clientID', narrowcast=clientids), payload=(1, args)) self.ForwardNotifyDown(packet)