Пример #1
0
 def SinglecastByServiceMask(self, serviceMask, method, *args, **kwargs):
     with bluepy.Timer('machoNet::SinglecastByServiceMask'):
         callTimer = base.CallTimer('SinglecastByServiceMask:: %s (Broadcast\\Client)' % method)
         try:
             self.SinglecastByServiceMaskWithoutTheStars(serviceMask, method, args, kwargs)
         finally:
             callTimer.Done()
Пример #2
0
 def SinglecastByClientID(self, clientid, method, *args):
     with bluepy.Timer('machoNet::SinglecastByClientID'):
         callTimer = base.CallTimer('SinglecastByClientID::%s (Broadcast\\Client)' % method)
         try:
             self.NarrowcastByClientIDsWithoutTheStars([clientid], method, args)
         finally:
             callTimer.Done()
Пример #3
0
 def NarrowcastByNodeIDs(self, nodeids, method, *args, **kwargs):
     with bluepy.Timer('machoNet::NarrowcastByNodeIDs'):
         callTimer = base.CallTimer('NarrowcastByClientIDs::%s (Broadcast\\Client)' % method)
         try:
             self.NarrowcastByNodeIDsWithoutTheStars(nodeids, method, args, kwargs)
         finally:
             callTimer.Done()
Пример #4
0
 def Objectcast(self, object, method, *args):
     with bluepy.Timer('machoNet::Objectcast'):
         callTimer = base.CallTimer('Objectcast::%s (Broadcast\\Client)' % method)
         try:
             self.ObjectcastWithoutTheStars(object, method, args)
         finally:
             callTimer.Done()
Пример #5
0
 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()
Пример #6
0
 def Scattercast(self, idtype, ids, method, *args):
     with bluepy.Timer('machoNet::Scattercast'):
         callTimer = base.CallTimer('Scattercast::%s::%s (Broadcast\\Client)' % (method, idtype))
         try:
             return self.ScattercastWithoutTheStars(idtype, ids, method, args)
         finally:
             callTimer.Done()
    def NotifyUp(self, packet):
        if packet.payload[0]:
            if getattr(packet.destination, 'service', None) is not None:
                if session.contextOnly and packet.command != const.cluster.MACHONETMSG_TYPE_SESSIONCHANGENOTIFICATION and packet.command != const.cluster.MACHONETMSG_TYPE_SESSIONINITIALSTATENOTIFICATION:
                    packet.srcTransport.InstallSessionIfRequired(
                        packet.destination.service, packet.payload[1])
                packet.srcTransport = None
                method = getattr(packet.service, packet.payload[1])
                callTimer = base.CallTimer(
                    '%s::%s (ServiceNotify\\Server)' %
                    (packet.destination.service, packet.payload[1]))
                try:
                    if len(packet.payload) == 3:
                        ClockThisWithoutTheStars(
                            'Remote Service Notify::%s::%s' %
                            (packet.destination.service, packet.payload[1]),
                            method, packet.payload[2])
                    else:
                        ClockThisWithoutTheStars(
                            'Remote Service Notify::%s::%s' %
                            (packet.destination.service, packet.payload[1]),
                            method, packet.payload[2], packet.payload[3])
                finally:
                    callTimer.Done()

                return
        else:
            packet.payload = packet.payload[1]
        return self.ForwardNotifyUp(packet)
Пример #8
0
 def ReliableSinglecastByCharID(self, charid, method, *args):
     with bluepy.Timer('machoNet::ReliableSinglecastByCharID'):
         callTimer = base.CallTimer(
             'ReliableSinglecastByCharID::%s (Broadcast\\Client)' % method)
         try:
             clientIDs = sm.GetService('sessionMgr').GetClientIDsFromID(
                 'charid', charid, refresh=1)
             self.NarrowcastByClientIDsWithoutTheStars(
                 clientIDs, method, args)
         except UnMachoDestination as e:
             self.machoNet.LogInfo(
                 'Character ', charid,
                 " was not reachable, so he didn't get this singlecast.  Should be fine and dandy.  reason=",
                 e.payload)
             sys.exc_clear()
         except UserError as e:
             if e.msg != 'UnMachoDestination':
                 raise
             self.machoNet.LogInfo(
                 'Character ', charid,
                 " was not reachable, so he didn't get this singlecast.  Should be fine and dandy.  reason=",
                 e.msg)
             sys.exc_clear()
         finally:
             callTimer.Done()
Пример #9
0
 def NarrowcastByClientIDs(self, clientids, method, *args):
     with bluepy.Timer('machoNet::NarrowcastByClientIDs'):
         callTimer = base.CallTimer('NarrowcastByClientIDs::%s (Broadcast\\Client)' % method)
         try:
             return self.NarrowcastByClientIDsWithoutTheStars(clientids, method, args)
         finally:
             callTimer.Done()
Пример #10
0
 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()
Пример #11
0
 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()
Пример #12
0
 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()
Пример #13
0
    def NotifyUp(self, packet):
        if packet.payload[0] == 1:
            tup = self.FromPickle(packet.payload[1], packet.source)
            objectID, method, args = tup[0], tup[1], tup[2]
            if method == 'ClientHasReleasedTheseObjects':
                oidsandrefs = objectID
                for each in oidsandrefs:
                    objectID, refID = each
                    if objectID in session.machoObjectsByID:
                        object = session.machoObjectsByID[objectID][1]
                        objectType, guts = self.__GetObjectTypeAndGuts(object)
                        session.UnregisterMachoObject(objectID, refID)

                return
            else:
                if objectID[0] == 'C' and macho.mode == 'client':
                    cid, oid = objectID.split(':')
                    objectID = '%s:%s' % (self.identifier, oid)
                if objectID not in session.machoObjectsByID:
                    raise UnMachoDestination(
                        'The specified object (%s) is not a member of this session'
                        % objectID)
                object = session.machoObjectsByID[objectID][1]
                if isinstance(object, base.ObjectConnection):
                    objclass = object.GetObjectConnectionLogClass()
                else:
                    objclass = macho.AssignLogName(object)
                callTimer = base.CallTimer('%s::%s (ObjectNotify\\Server)' %
                                           (objclass, method))
                try:
                    func = getattr(object, method)
                    if method in object.__dict__.get(
                            '__restrictedcalls__',
                        {}) or method.startswith('_'):
                        raise RuntimeError(
                            'This call can only be the result of a hack attack',
                            method)
                    if not isinstance(object, base.ObjectConnection) and len(
                            tup) == 4 and 'machoVersion' in tup[3]:
                        if len(tup[3]) == 1:
                            tup = (tup[0], tup[1], tup[2])
                        else:
                            del tup[3]['machoVersion']
                    if len(tup) == 3:
                        ClockThisWithoutTheStars(
                            'Remote Object Notify::%s::%s' %
                            (objclass, method), func, args)
                    else:
                        ClockThisWithoutTheStars(
                            'Remote Object Notify::%s::%s' %
                            (objclass, method), func, args, tup[3])
                finally:
                    callTimer.Done()

                return
        else:
            packet.payload = self.FromPickle(packet.payload[1], packet.source)
        self.ForwardNotifyUp(packet)
Пример #14
0
 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 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()
Пример #16
0
 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()
Пример #17
0
            def doCall():
                method = attribute
                mask = self.session.Masquerade()
                try:
                    callTimer = base.CallTimer('%s::%s (RemoteServiceCall)' % (self.service, method))
                    try:
                        return call(self.session, self.nodeID, self.servicename, method, args, kwargs)
                    finally:
                        callTimer.Done()

                finally:
                    mask.UnMask()
Пример #18
0
    def __call__(self, *args, **keywords):
        mask = self.session.Masquerade()
        try:
            callTimer = base.CallTimer('%s::%s (UberMachoRemoteServiceCall)' % (self.service, self.method))
            try:
                return self.gpcs.UberMachoRemoteServiceCall(self.nodeGroup, self.batchInterval, self.session, self.service, self.method, *args, **keywords)
            finally:
                callTimer.Done()

        finally:
            mask.UnMask()
            self.__dict__.clear()
 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()
Пример #20
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()
Пример #21
0
 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()
Пример #22
0
    def CallUp(self, packet):
        if packet.payload[0]:
            if getattr(packet.destination, 'service', None) is not None:
                if packet.payload[1] in packet.service.__dict__.get('__restrictedcalls__', {}) or packet.payload[1].startswith('_'):
                    raise RuntimeError('This call can only be the result of a hack attack', packet.payload[1])
                if packet.payload[1] == 'MachoBindObject':
                    args = packet.payload[2][:-1]
                    nodeID = packet.service.MachoResolveObject(args[0], 0)
                    if nodeID and nodeID != self.machoNet.GetNodeID():
                        self.machoNet.LogError('MachoBindObject received on wrong node.  Should have gone to ', nodeID, ', bindParams=', args[0], ', packet=', packet)
                        raise WrongMachoNode(nodeID)
                    call = packet.payload[2][-1]
                    boundObject = packet.service.MachoGetObjectBoundToSession(packet.payload[2][0], session)
                    if self.logClientCall and packet.source.addressType == const.ADDRESS_TYPE_CLIENT:
                        kwargs = packet.payload[3] if len(packet.payload) >= 4 else None
                        self.machoNet.LogClientCall(session, packet.destination.service, packet.payload[1], packet.payload[2], kwargs)
                    if call is not None:
                        if isinstance(boundObject, base.ObjectConnection):
                            objclass = boundObject.GetObjectConnectionLogClass()
                        else:
                            objclass = macho.AssignLogName(object)
                        method, args, keywords = call
                        if method in boundObject.__dict__.get('__restrictedcalls__', {}) or method.startswith('_'):
                            raise RuntimeError('This call can only be the result of a hack attack', method)
                        callTimer = base.CallTimer('%s::%s (UnBoundObjectCall\\Server)' % (objclass, method))
                        try:
                            func = getattr(boundObject, method)
                            self.UpdateRecvServiceCallStats(objclass, method, packet.source)
                            if not keywords:
                                retval = ClockThisWithoutTheStars('Remote Unbound Object Call::%s::%s' % (objclass, method), func, args)
                            else:
                                retval = ClockThisWithoutTheStars('Remote Unbound Object Call::%s::%s' % (objclass, method), func, args, keywords)
                            payload = (boundObject, retval)
                        finally:
                            callTimer.Done()

                    else:
                        payload = (boundObject, None)
                else:
                    args = packet.payload[2]
                    method = getattr(packet.service, packet.payload[1])
                    callTimer = base.CallTimer('%s::%s (ServiceCall\\Server)' % (packet.destination.service, packet.payload[1]))
                    if self.logClientCall and packet.source.addressType == const.ADDRESS_TYPE_CLIENT and packet.payload[1] != 'MachoBindObject':
                        kwargs = packet.payload[3] if len(packet.payload) >= 4 else None
                        self.machoNet.LogClientCall(session, packet.destination.service, packet.payload[1], args, kwargs)
                    try:
                        self.UpdateRecvServiceCallStats(packet.destination.service, method.__method__, packet.source)
                        if len(packet.payload) == 3:
                            payload = ClockThisWithoutTheStars('Remote Service Call::%s::%s' % (packet.destination.service, packet.payload[1]), method, args)
                        else:
                            payload = ClockThisWithoutTheStars('Remote Service Call::%s::%s' % (packet.destination.service, packet.payload[1]), method, args, packet.payload[3])
                    finally:
                        callTimer.Done()

                if session.contextOnly:
                    packet.srcTransport.InstallSessionIfRequired(packet.destination.service, packet.payload[1])
                packet.srcTransport = None
                return packet.Response(payload=payload)
        else:
            packet.payload = packet.payload[1]
        return self.ForwardCallUp(packet)
Пример #23
0
    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
Пример #24
0
    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 
Пример #25
0
    def CallUp(self, packet):
        if packet.command == const.cluster.MACHONETMSG_TYPE_AUTHENTICATION_REQ:
            retval = self.ForwardCallUp(packet)
            self.__StringifyPayloadForLogging(retval, retval.payload)
            retval.payload = self.ToPickle(retval.payload)
            if self.added_objects:
                retval.oob['OID+'] = self.added_objects
            retval.compressedPart = self.compressedPart
            return retval
        elif packet.payload[0]:
            tup = self.FromPickle(packet.payload[1], packet.source)
            objectID, method, args = tup[0], tup[1], tup[2]
            if objectID[0] == 'C' and macho.mode == 'client':
                cid, oid = objectID.split(':')
                objectID = '%s:%s' % (self.identifier, oid)
            if objectID not in session.machoObjectsByID:
                session.DumpSession('OBJECTNOTMEMBER', 'The specified object (%s) is not a member of this session' % objectID)
                raise UnMachoDestination('The specified object (%s) is not a member of this session' % objectID)
            object = session.machoObjectsByID[objectID][1]
            if isinstance(object, base.ObjectConnection):
                objclass = object.GetObjectConnectionLogClass()
            else:
                objclass = macho.AssignLogName(object)
            callTimer = base.CallTimer('%s::%s (ObjectCall\\Server)' % (objclass, method))
            if self.logClientCall and packet.source.addressType == const.ADDRESS_TYPE_CLIENT:
                kwargs = tup[3] if len(tup) >= 4 else None
                self.machoNet.LogClientCall(session, objclass, method, args, kwargs)
            try:
                func = getattr(object, method)
                if method in object.__dict__.get('__restrictedcalls__', {}) or method.startswith('_'):
                    raise RuntimeError('This call can only be the result of a hack attack', method)
                if not isinstance(object, base.ObjectConnection):
                    if 0 == session.role & service.ROLE_SERVICE and hasattr(object, '__exportedcalls__') and method not in object.__exportedcalls__:
                        raise RuntimeError('%s call is not exported from this pass-by-reference object.' % method)
                    if not session.role & service.ROLE_SERVICE:
                        paramList = object.__exportedcalls__.get(method, None)
                        paramDict = None
                        if paramList is not None:
                            if type(paramList) is list:
                                if len(paramList):
                                    tmp = {}
                                    tmp['role'] = paramList[0]
                                    tmp['preargs'] = paramList[1:]
                                    paramDict = tmp
                            elif type(paramList) is dict:
                                paramDict = paramList
                        if paramDict is not None:
                            role = paramDict.get('role', service.ROLE_SERVICE)
                            if not role & session.role:
                                session.LogSessionError("Called %s::%s, which requires role 0x%x, which the user doesn't have. User has role 0x%x" % (object.__class__.__name__,
                                 method,
                                 role,
                                 session.role))
                                raise RuntimeError('RoleNotAssigned', "%s::%s requires role 0x%x, which the user doesn't have. User has role 0x%x. Calling session: %s" % (object.__class__.__name__,
                                 method,
                                 role,
                                 session.role,
                                 str(session)))
                            preargs = paramDict.get('preargs', [])
                            args2 = len(preargs) * [None] + list(args)
                            for i in range(len(preargs)):
                                args2[i] = getattr(session, preargs[i])

                            args = tuple(args2)
                    if len(tup) == 4 and 'machoVersion' in tup[3]:
                        if len(tup[3]) == 1:
                            tup = (tup[0], tup[1], tup[2])
                        else:
                            del tup[3]['machoVersion']
                if len(tup) == 3:
                    retval = ClockThisWithoutTheStars('Remote Object Call::%s::%s' % (objclass, method), func, args)
                else:
                    retval = ClockThisWithoutTheStars('Remote Object Call::%s::%s' % (objclass, method), func, args, tup[3])
                retpickle = self.ToPickle(retval)
                retval = packet.Response(payload=retpickle)
                if self.added_objects:
                    retval.oob['OID+'] = self.added_objects
                self.__StringifyPayloadForLogging(retval, retpickle)
                retval.compressedPart = self.compressedPart
            finally:
                callTimer.Done()

            return retval
        else:
            packet.payload = self.FromPickle(packet.payload[1], packet.source)
            retval = self.ForwardCallUp(packet)
            self.__StringifyPayloadForLogging(retval, retval.payload)
            retval.payload = self.ToPickle(retval.payload)
            if self.added_objects:
                retval.oob['OID+'] = self.added_objects
            retval.compressedPart = self.compressedPart
            return retval
Пример #26
0
    def ObjectCallWithoutTheStars(self, oob, persistantObjectID, blocking, sess, destination, objectID, method, args, keywords):
        cachable, versionCheck, throwOK, cachedResultRecord, cacheKey, cacheDetails = sm.GetService('objectCaching').PerformCachedMethodCall(None, persistantObjectID, method, args)
        if cachable:
            if not versionCheck:
                if throwOK:
                    sm.GetService('objectCaching').LogInfo('Local cache hit with throw for remote object ', persistantObjectID, '::', method, '(', args, ')')
                    raise objectCaching.CacheOK()
                elif cachedResultRecord:
                    sm.GetService('objectCaching').LogInfo('Local cache hit for remote object ', persistantObjectID, '::', method, '(', args, ')')
                    return cachedResultRecord['lret']
        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, self.ToPickle((objectID,
          method,
          args,
          kw2)))
        if blocking == 1:
            packet = macho.CallReq(destination=destination, payload=payload)
            if oob:
                packet.oob = oob
            if machoTimeout is not None:
                packet.oob['machoTimeout'] = machoTimeout
            if self.added_objects:
                if 'OID+' in packet.oob:
                    packet.oob['OID+'].update(self.added_objects)
                else:
                    packet.oob['OID+'] = self.added_objects
            try:
                callTimer = base.CallTimer('Remote Object Call::%s (ObjectCall\\Client)' % (method,))
                try:
                    retval = self.ForwardCallDown(packet)
                finally:
                    callTimer.Done()

                retval = self.FromPickle(retval.payload, packet.destination)
            except objectCaching.CacheOK:
                if cachedResultRecord is None:
                    raise 
                sys.exc_clear()
                sm.GetService('objectCaching').LogInfo('Version matches for remote object ', persistantObjectID, '::', method, '(', args, ')')
                sm.GetService('objectCaching').UpdateVersionCheckPeriod(cacheKey)
                return cachedResultRecord['lret']

            if isinstance(retval, objectCaching.CachedMethodCallResult):
                sm.GetService('objectCaching').CacheMethodCall(persistantObjectID, method, args, retval)
                retval = retval.GetResult()
            return retval
        else:
            packet = macho.Notification(destination=destination, payload=payload)
            if oob:
                packet.oob = oob
            if machoTimeout is not None:
                packet.oob['machoTimeout'] = machoTimeout
            if self.added_objects:
                if 'OID+' in packet.oob:
                    packet.oob['OID+'].update(self.added_objects)
                else:
                    packet.oob['OID+'] = self.added_objects
            self.ForwardNotifyDown(packet)
            return MachoBoobyTrap()
Пример #27
0
    def GetCachableObject(self, shared, objectID, objectVersion, nodeID):
        """
            Returns a cached copy of object 'objectID' or returns None if 'objectID' is not found in cache.
            If the cached version is older than 'objectVersion': acquire it from node nodeID (through
              our proxy, of course, if we're a client).
            'shared' is true iff object has been cached in "shared" mode (meaning: a copy is cached on servers and proxies).
            Returns a utilCachedObject or objectCaching.CachedObject.
        """
        callTimer = base.CallTimer('objectCaching::GetCachableObject')
        try:
            if macho.mode == 'client':
                gpcs = sm.services['machoNet']
            else:
                gpcs = sm.services['machoNet']
                gpcs.GetGPCS()
            if objectID in self.cachedObjects and isinstance(
                    self.cachedObjects[objectID],
                    utilCachedObject) and macho.mode == 'proxy':
                if sm.services['machoNet'].GetTransportOfNode(
                        self.cachedObjects[objectID].__nodeID__) is None:
                    del self.cachedObjects[objectID]
            if objectID in self.cachedObjects and isinstance(
                    self.cachedObjects[objectID], uthread.Semaphore
            ) or objectID not in self.cachedObjects or not isinstance(
                    self.cachedObjects[objectID],
                    uthread.Semaphore) and self.__OlderVersion(
                        self.cachedObjects[objectID].version, objectVersion):
                if objectID not in self.cachedObjects or not isinstance(
                        self.cachedObjects[objectID],
                        uthread.Semaphore) and self.__OlderVersion(
                            self.cachedObjects[objectID].version,
                            objectVersion):
                    self.cachedObjects[objectID] = uthread.Semaphore(
                        ('objectCaching', objectID))
                while 1:
                    semaphore = self.cachedObjects[objectID]
                    semaphore.acquire()
                    try:
                        if not isinstance(self.cachedObjects[objectID],
                                          uthread.Semaphore):
                            self.__UpdateStatisticsGetCachableObject(
                                objectID, objectVersion,
                                self.cachedObjects[objectID])
                            return self.cachedObjects[objectID]
                        if macho.mode == 'client':
                            if shared:
                                if not sm.services['machoNet'].myProxyNodeID:
                                    proxyNodeID = nodeID
                                else:
                                    proxyNodeID = sm.services[
                                        'machoNet'].myProxyNodeID
                                remoteObject = gpcs.RemoteServiceCall(
                                    session, proxyNodeID, 'objectCaching',
                                    'GetCachableObject', shared, objectID,
                                    objectVersion, nodeID)
                            else:
                                remoteObject = gpcs.RemoteServiceCall(
                                    session, nodeID, 'objectCaching',
                                    'GetCachableObject', shared, objectID,
                                    objectVersion, nodeID)
                            self.cachedObjects[objectID] = remoteObject
                            self.__CacheIsDirty('cachedObjects', objectID)
                        elif macho.mode == 'proxy':
                            remoteObject = gpcs.RemoteServiceCall(
                                self.session, nodeID, 'objectCaching',
                                'GetCachableObject', shared, objectID,
                                objectVersion, nodeID)
                            if not remoteObject.compressed and len(
                                    remoteObject.pickle) > 200:
                                try:
                                    t = ClockThis('objectCaching::compress',
                                                  zlib.compress,
                                                  remoteObject.pickle, 1)
                                except zlib.error as e:
                                    raise RuntimeError(
                                        'Compression Failure: ' + strx(e))

                                if len(t) < len(remoteObject.pickle):
                                    remoteObject.compressed = 1
                                    remoteObject.pickle = t
                            if remoteObject.shared:
                                self.cachedObjects[objectID] = remoteObject
                                self.__CacheIsDirty('cachedObjects', objectID)
                            else:
                                del self.cachedObjects[objectID]
                                return remoteObject
                        elif macho.mode == 'server':
                            self.LogError(
                                "Some dude asked me for a cached object I just don't have, objectID=",
                                objectID, ', objectVersion=', objectVersion,
                                ', nodeID=', nodeID)
                            del self.cachedObjects[objectID]
                            raise RuntimeError(
                                "I don't have %s, which just don't make sense...."
                                % repr(objectID))
                    finally:
                        semaphore.release()

                    if not isinstance(self.cachedObjects[objectID],
                                      uthread.Semaphore):
                        self.__UpdateStatisticsGetCachableObject(
                            objectID, objectVersion,
                            self.cachedObjects[objectID])
                        return self.cachedObjects[objectID]

            else:
                if macho.mode == 'server' and not self.cachedObjects[
                        objectID].shared:
                    tmp = self.cachedObjects[objectID]
                    self.__UpdateStatisticsGetCachableObject(
                        objectID, objectVersion, self.cachedObjects[objectID])
                    del self.cachedObjects[objectID]
                    return tmp
                self.__UpdateStatisticsGetCachableObject(
                    objectID, objectVersion, self.cachedObjects[objectID])
                return self.cachedObjects[objectID]
        finally:
            callTimer.Done()