def _process_msg_pull(self, addr, msg): """ Processes incoming message for clients that are in pull mode, not injecting any fault :param addr: The address of the sender :param msg: The message dictionary """ # We process status messages for connections that are in the queue is_status, status = MessageClient.is_status_message(msg) if is_status and status == MessageClient.CONNECTION_LOST_MSG: if not self._suppressOutput: self._writers[addr].write_entry( MessageBuilder.status_connection(time())) elif is_status and status == MessageClient.CONNECTION_RESTORED_MSG: if not self._suppressOutput: self._writers[addr].write_entry( MessageBuilder.status_connection(time(), restored=True)) else: # Messages are popped from the input queue, and their content stored if not self._suppressOutput: self._writers[addr].write_entry(msg) msg_type = msg[MessageBuilder.FIELD_TYPE] if msg_type == MessageBuilder.STATUS_START: InjectorController.logger.info( "Task %s started on host %s" % (msg[MessageBuilder.FIELD_DATA], formatipport(addr))) elif msg_type == MessageBuilder.STATUS_RESTART: InjectorController.logger.info( "Task %s restarted on host %s" % (msg[MessageBuilder.FIELD_DATA], formatipport(addr))) elif msg_type == MessageBuilder.STATUS_END: InjectorController.logger.info( "Task %s terminated successfully on host %s" % (msg[MessageBuilder.FIELD_DATA], formatipport(addr))) if not self._suppressOutput: self._write_task_output(addr, msg) elif msg_type == MessageBuilder.STATUS_ERR: InjectorController.logger.error( "Task %s terminated with error code %s on host %s" % (msg[MessageBuilder.FIELD_DATA], str(msg[MessageBuilder.FIELD_ERR]), formatipport(addr))) if not self._suppressOutput: self._write_task_output(addr, msg) elif msg_type == MessageBuilder.STATUS_GREET: status_string = 'An injection session is in progress' if msg[MessageBuilder.FIELD_ISF] else \ 'No injection session is in progress' InjectorController.logger.info( "Greetings. Engine %s is alive with %s currently active tasks. %s" % (formatipport(addr), str( msg[MessageBuilder.FIELD_DATA]), status_string))
def _process_msg_inject(self, addr, msg): """ Processes incoming message for clients involved in an injection session :param addr: The address of the sender :param msg: The message dictionary """ # We process status messages for connections that are in the queue is_status, status = MessageClient.is_status_message(msg) if is_status and status == MessageClient.CONNECTION_LOST_MSG: # If connection has been lost with an host, we remove its pendingTasks entry if not self._suppressOutput: self._writers[addr].write_entry( MessageBuilder.status_connection(time())) elif is_status and status == MessageClient.CONNECTION_RESTORED_MSG: # If connection has been restored with an host, we send a new session start command self._client.send_msg( addr, MessageBuilder.command_session(self._session_id)) self._client.send_msg( addr, MessageBuilder.command_set_time(self._get_timestamp(time()))) elif is_status and status == MessageClient.CONNECTION_FINALIZED_MSG: self._pendingTasks.pop(addr, None) # If all connections to servers were finalized we assume that the injection can be terminated if len(self._pendingTasks) == 0: self._endReached = True self._reader.close() else: msg_type = msg[MessageBuilder.FIELD_TYPE] if msg_type != MessageBuilder.ACK_YES and msg_type != MessageBuilder.ACK_NO: # Ack messages are not written to the output log if not self._suppressOutput: self._writers[addr].write_entry(msg) # We log on the terminal the content of the message in a pretty form if msg_type == MessageBuilder.STATUS_START: InjectorController.logger.info( "Task %s started on host %s" % (msg[MessageBuilder.FIELD_DATA], formatipport(addr))) elif msg_type == MessageBuilder.STATUS_RESTART: InjectorController.logger.info( "Task %s restarted on host %s" % (msg[MessageBuilder.FIELD_DATA], formatipport(addr))) elif msg_type == MessageBuilder.STATUS_END: InjectorController.logger.info( "Task %s terminated successfully on host %s" % (msg[MessageBuilder.FIELD_DATA], formatipport(addr))) # If a task terminates, we remove its sequence number from the set of pending tasks for the host self._pendingTasks[addr].discard( msg[MessageBuilder.FIELD_SEQNUM]) if not self._suppressOutput: self._write_task_output(addr, msg) elif msg_type == MessageBuilder.STATUS_ERR: InjectorController.logger.error( "Task %s terminated with error code %s on host %s" % (msg[MessageBuilder.FIELD_DATA], str(msg[MessageBuilder.FIELD_ERR]), formatipport(addr))) self._pendingTasks[addr].discard( msg[MessageBuilder.FIELD_SEQNUM]) if not self._suppressOutput: self._write_task_output(addr, msg) elif msg_type == MessageBuilder.ACK_YES: # ACK messages after the initialization phase are received ONLY when a connection is restored, # and the session must be resumed InjectorController.logger.warning( "Session resumed with engine %s" % formatipport(addr)) # If the ack msg contains an error, it means all previously running tasks have been lost if not self._suppressOutput: self._writers[addr].write_entry( MessageBuilder.status_connection(time(), restored=True)) if MessageBuilder.FIELD_ERR in msg: self._pendingTasks[addr] = set() if not self._suppressOutput: self._writers[addr].write_entry( MessageBuilder.status_reset( msg[MessageBuilder.FIELD_TIME])) elif msg_type == MessageBuilder.ACK_NO: InjectorController.logger.warning( "Session cannot be resumed with engine %s" % formatipport(addr)) self._client.remove_host(addr)