def _make_reply_packet(self, payload='', guid=None): if guid not in self.guids: LOGGER.error("No session with guid %s" % str_uuid(guid)) pb = sfk_pb2.Msg() pb.mtype = pb.DATA pb.data.content_type = "simple" pb.data.payload = "test" protobuf = pb.SerializeToString() data = "%s %s %s" % (self.appid, payload, str_uuid(guid)) spif = prot.Spif2Packet(protobuf=protobuf, data=data) return prot.ScpPacket(guid=guid, data=spif.assemble())
def mainloop(self, callback=lambda: None): try: while True: packet = self.sfk.get_packet() msg_type = packet.get_msg_type() if msg_type == 'msg': guid = packet.get_guid() client_sockwrap = self.client_sockwraps.get(guid, None) if client_sockwrap is None: # client already disconnected LOGGER.info('Client with guid %s not connected' % str_uuid(guid)) continue else: spif2packet = self._unpack_scp_to_spif2(packet) client_sockwrap.put_packet(spif2packet) elif msg_type == 'ping': pong = packet.make_pong() self.sfk.put_packet(pong) LOGGER.debug("appid %s; sfk_id %s - recieved ping" % \ (self.appid, self.sfk_id)) else: raise DockerError("unknown msg_type") except Exception: LOGGER.exception("Sfk Docker fails") callback()
def mainloop(self, callback=lambda: None): try: while True: packet = self.client_sockwrap.get_packet() new_packet = self._pack_spif2_to_scp(packet) self.sfk_sockwrap.put_packet(new_packet) except Exception as e: LOGGER.error("ClientDocker {0} {1}".format(str_uuid(self.guid), str(e))) callback()
def register_sfk(self, sfk_sock, sfk_addr): auth_packet = self._recv_packet(ScpPacket, sfk_sock) # basic auth packet check basic_test_passed = False # just init value error_msg = "" if auth_packet == None: error_msg = "Error when auth packed recved" elif auth_packet.get_msg_type() != 'auth': error_msg = "Unexpected message type while auth attempt" elif len(auth_packet.data) != 0: error_msg = "Auth packet contains unexpected data" else: basic_test_passed = True if not basic_test_passed: LOGGER.error(error_msg) sfk_sock.close() return appid, token = auth_packet.get_auth_info() # check authorization auth_check_passed = False if not appid or not token: LOGGER.error("Appid or Token not supplied") elif NEED_AUTH and not authorized_sfk(appid, token): LOGGER.error( "Bad appid/token pair from just connected sfk: %s %s" % (appid, token)) else: auth_check_passed = True if not auth_check_passed: sfk_sock.close() return sfk_id = str(uuid.uuid4()) LOGGER.info("Sfk with appid %s, sfk_id %s connected" % (str_uuid(appid), sfk_id)) # waiting for death_event prevents eventlet.serve from closing socket death_event = eventlet.event.Event() sfk_supervizor = SfkSupervizor(sfk_sock=sfk_sock, registrar=self, appid=appid, sfk_id=sfk_id, sfk_addr=sfk_addr, death_event=death_event) self.remember_sfk(sfk_supervizor, appid, sfk_id) self.info.add_sfk_instance(appid, sfk_id, sfk_addr) death_event.wait() LOGGER.info( 'Register: death_event from sfk appid {0}; sfk_id {1}'.format( appid, sfk_id))
def register_rengine(self, sock, addr): packet = self._recv_packet(Spif2Packet, sock) if packet == None: sock.close() return try: appid = packet.get_appid() except ProtocolError: LOGGER.error( "cannot extract appid needed for just connected client") sock.close() return if not self._is_sfk_connectable(appid): LOGGER.error( "attempt connecting to non-connected sfk with appid " \ + str(appid)) sock.close() return sfk, sfk_id = self._get_sfk(appid) # after _is_connectable check # always correct guid = self._generate_guid() self.info.add_client(appid, sfk_id, guid, addr) LOGGER.info( 'Register: Client connected to appid {0} with guid {1}'.format( appid, str_uuid(guid))) # waiting for death_event prevents eventlet.serve from closing socket death_event = eventlet.event.Event() sfk.start_client(sock=sock, guid=guid, addr=addr, first_packet=packet, death_event=death_event) death_event.wait() LOGGER.info('Register: death_event from rengine guid {0}'.format( str_uuid(guid)))
def register_sfk(self, sfk_sock, sfk_addr): auth_packet = self._recv_packet(ScpPacket, sfk_sock) # basic auth packet check basic_test_passed = False # just init value error_msg = "" if auth_packet == None: error_msg = "Error when auth packed recved" elif auth_packet.get_msg_type() != 'auth': error_msg = "Unexpected message type while auth attempt" elif len(auth_packet.data) != 0: error_msg = "Auth packet contains unexpected data" else: basic_test_passed = True if not basic_test_passed: LOGGER.error(error_msg) sfk_sock.close() return appid, token = auth_packet.get_auth_info() # check authorization auth_check_passed = False if not appid or not token: LOGGER.error("Appid or Token not supplied") elif NEED_AUTH and not authorized_sfk(appid, token): LOGGER.error("Bad appid/token pair from just connected sfk: %s %s" % (appid, token)) else: auth_check_passed = True if not auth_check_passed: sfk_sock.close() return sfk_id = str(uuid.uuid4()) LOGGER.info("Sfk with appid %s, sfk_id %s connected" % (str_uuid(appid), sfk_id)) # waiting for death_event prevents eventlet.serve from closing socket death_event = eventlet.event.Event() sfk_supervizor = SfkSupervizor(sfk_sock=sfk_sock, registrar=self, appid=appid, sfk_id=sfk_id, sfk_addr=sfk_addr, death_event=death_event) self.remember_sfk(sfk_supervizor, appid, sfk_id) self.info.add_sfk_instance(appid, sfk_id, sfk_addr) death_event.wait() LOGGER.info('Register: death_event from sfk appid {0}; sfk_id {1}'.format(appid, sfk_id))
def register_rengine(self, sock, addr): packet = self._recv_packet(Spif2Packet, sock) if packet == None: sock.close() return try: appid = packet.get_appid() except ProtocolError: LOGGER.error( "cannot extract appid needed for just connected client") sock.close() return if not self._is_sfk_connectable(appid): LOGGER.error( "attempt connecting to non-connected sfk with appid " \ + str(appid)) sock.close() return sfk, sfk_id = self._get_sfk(appid) # after _is_connectable check # always correct guid = self._generate_guid() self.info.add_client(appid, sfk_id, guid, addr) LOGGER.info( 'Register: Client connected to appid {0} with guid {1}'.format( appid, str_uuid(guid))) # waiting for death_event prevents eventlet.serve from closing socket death_event = eventlet.event.Event() sfk.start_client(sock=sock, guid=guid, addr=addr, first_packet=packet, death_event=death_event) death_event.wait() LOGGER.info( 'Register: death_event from rengine guid {0}'.format( str_uuid(guid)))
def recved_packets_processor(self): try: while True: packet = self.queue_recv.get() self.guids.add(packet.guid) mtype = packet.get_msg_type() payload = None if mtype == 'msg': buf = StringIO.StringIO(packet.data) pack_class = prot.determine_packet_type(buf) client_pack = pack_class() client_pack.read_fields(buf) payload = client_pack.bindata elif mtype == 'sfkcontent': SfkModel.sfkcontent_handler(packet) continue elif mtype == 'session_dropped': self.guids.remove(packet.guid) LOGGER.info('session dropped guid {0}'.format( str_uuid(packet.guid))) continue elif mtype == 'pong': LOGGER.info('Pong recieved') else: LOGGER.error("Unknown message type: {0}".format(mtype)) LOGGER.info('recved packet guid {0}; mtype {1}'.format( str_uuid(packet.guid), mtype)) if payload: LOGGER.info('message: %s' % payload) reply = self._make_reply_packet(payload=payload, guid=packet.guid) self.queue_send.put(reply) LOGGER.info('reply is sent') except Exception as e: LOGGER.exception("recved_packets_processor: " + str(e))
def drop_client(self, guid): # prevent to call this method from multiple threads try: if self.clients[guid].alive: self.clients[guid].alive = False else: return except KeyError: return self.clients[guid].kill_threads() self.clients[guid].sockwrap.close_socket() self.clients[guid].death_event.send() self.sfk.docker.del_client(guid) del self.clients[guid] LOGGER.info("Client guid {0} was dropped".format(str_uuid(guid))) self.info.drop_client(self.appid, self.sfk_id, guid) # send signal to sfk <<session dropped>> session_dropped = ScpPacket.make_session_dropped(guid) self.sfk.sockwrap.put_packet(session_dropped)
def __repr__(self): return "%s:%s" % ("SfkSockWrap", str_uuid(self.appid))
def __repr__(self): return "%s:%s" % ("ClientSockWrap", str_uuid(self.guid))
def drop_client(self, appid, sfk_id, guid): connects = self.connect_tree[appid][sfk_id]['connects'] del connects[str_uuid(guid)]
def add_client(self, appid, sfk_id, guid, addr): connects = self.connect_tree[appid][sfk_id]['connects'] connects[str_uuid(guid)] = {'addr': addr}