Ejemplo n.º 1
0
def user_list():
    page =request.args.get('page', type=int)
    if not page:
        page = 1
    inbounds = Inbound.query.order_by(Inbound.id.asc()).paginate(page=page, per_page=8)
    hosts = Host.query.all()
    server_form = ServerForm()
    user_form = UserForm()
    user_form.host.choices = get_host_name()
    # 增加服务器
    if server_form.validate_on_submit():
        host = Host(host=server_form.host.data, addr=server_form.addr.data, port=server_form.port.data,
                    manager=server_form.manager.data, password=server_form.password.data)
        host.user_num = get_count(host)
        if verify_host(host):
            db.session.add(host)
            db.session.commit()
        return redirect(url_for('v2ms_bp.user_list'))
    # 增加用户
    if user_form.validate_on_submit():
        inbound = Inbound(port=user_form.port.data, listen=config['listen'], protocol=config['protocol']
                          , settings=get_settings(), stream_settings=config['stream_settings'],
                          sniffing=config['sniffing'], remark=user_form.remark.data)
        inbound.host = user_form.host.choices[0][1]
        inbound.lease_month = user_form.lease_month.data
        db.session.add(inbound)
        db.session.commit()
        server_changed = Host.query.filter_by(host=inbound.host).first()
        host_sync(server_changed)
        info_remote_server(server_changed)
        return redirect(url_for('v2ms_bp.user_list'))
    return render_template('user_list.html', inbounds=inbounds, hosts=hosts, server_form=server_form, user_form=user_form)
Ejemplo n.º 2
0
    def send_unicast(self, host: Host, method: str, message):
        if not host:
            return

        header = self._get_base_header(method)

        if method != "ACK":
            host.message_seq = host.message_seq + 1
            header['seq'] = host.message_seq

        encoded_message = self._to_message(header, message)

        if method != "ACK":
            if host.open_ack:
                print("Resent Message Unicast")
                self.unicast_socket.sendto(
                    host.last_message_sent,
                    (host.address, int(host.unicast_port)))

        if DEBUG and not method == 'ACK':
            if method != "HB" or HEARTBEAT:
                print(
                    f"[UNICAST:SENT:{method}] {header} {message} to {host.address}:{host.unicast_port} ({host.id})"
                )

        host.last_message_sent = encoded_message
        self.unicast_socket.sendto(encoded_message,
                                   (host.address, int(host.unicast_port)))
Ejemplo n.º 3
0
    def test_ordering(self):
        own_node = Host("0000000", 0000)
        node_one = Host("1111111", 1111)
        node_two = Host("2222222", 2222)
        ring = Ring(own_node)

        ring.add_node(node_one)
        ring.add_node(node_two)

        assert ring.nodes[0].id == own_node.id
        assert ring.nodes[1].id == node_one.id
        assert ring.nodes[2].id == node_two.id
Ejemplo n.º 4
0
    def test_ordering_delete(self):
        own_node = Host("0000000", 0000)
        node_one = Host("1111111", 1111)
        node_two = Host("2222222", 2222)
        ring = Ring(own_node)

        ring.add_node(node_one)
        ring.remove_node(node_one)
        ring.add_node(node_two)

        assert len(ring.nodes) == 2
        assert ring.nodes[0].id == own_node.id
        assert ring.nodes[1].id == node_two.id
Ejemplo n.º 5
0
    def test_multiple_add(self):
        own_node = Host("0000000", 0000)
        node_one = Host("1111111", 1111)
        node_two = Host("2222222", 2222)
        ring = Ring(own_node)

        ring.add_node(node_one)
        ring.add_node(node_two)
        ring.add_node(node_two)
        ring.add_node(node_two)
        ring.add_node(node_two)

        assert len(ring.nodes) == 3
Ejemplo n.º 6
0
    def test_get_right_neighbour(self):
        own_node = Host("0000000", 0000)
        node_one = Host("1111111", 1111)
        node_two = Host("2222222", 2222)
        ring = Ring(own_node)

        ring.add_node(node_one)
        ring.remove_node(node_one)
        ring.add_node(node_two)

        neighbour = ring.get_right_neighbour()

        assert neighbour.id == node_two.id
Ejemplo n.º 7
0
    def on_multicast_received(self, host, method, message):
        if method == "MAIN_GROUP/HOSTS":
            hosts = json.loads(message)
            list_of_hosts = [Host.from_json(h) for h in hosts]
            client_ids = [
                client.id for client in list_of_hosts
                if client.host_type == HostType.CLIENT
            ]
            for game in self.games:
                removed = False
                t_players = []
                for player in game.players:
                    if player.id in client_ids:
                        p = game.get_player(player.id)
                        t_players.append(p)
                    else:
                        posx, posy = game.get_player_position(player)
                        game.grid.cells[posy][posx].player = None
                        removed = True
                game.players = t_players

                if removed:
                    self.send_game(game)

        if method == "GS/OV":
            game = Game.from_pickle(message)
            if not game:
                return
            if game not in self.games:
                print("FOUND NEW GAME!")
                self.games.append(game)

            for i, _game in enumerate(self.games):
                if _game.id == game.id and _game.seq + 1 == game.seq:
                    self.games[i] = game
Ejemplo n.º 8
0
    def get_os_service_scan_details(self):
        """Runs scan to determine OS and running service of given host

        :return array of host data found in scan
        """
        self._scanned = True
        result = self._scanner.scan(self._ips, self._ports, arguments='-A')
        hosts = []
        if self._scanned:
            # for each host scanned
            for host in self._scanner.all_hosts():
                print("-----------------")
                print(result['scan'][host])
                print("-----------------")
                state = result['scan'][host]["status"]["state"]
                mac = self.get_mac_address(result, host)
                vendor = self.get_vendor(result, host, mac)
                val_arr = self.get_os_details(result, host)
                name = val_arr[0]
                os_gen = val_arr[1]
                os_family = val_arr[2]
                hosts.append(
                    Host(host, state, name, os_family, os_gen, vendor, mac))

        return hosts
Ejemplo n.º 9
0
def seed_hosts():
  hosts = [
    {
      "zip": "22333",
      "first_name": "Derk",
      "last_name": "Willows",
      "email": "*****@*****.**",
      "phone": "6662228888",
      "street": "841 Calypso Plaza",
      "city": "Golubinci",
      "state": "Texas",
      "hnt_wallet": "11sDK9KUao8SudAgzRzKHQT5JjvKdG7v9bUzpu6LEb85DyYuMrg",
      'payment_method': 'hnt'
    },
    {
      "zip": "11222",
      "first_name": "Jane",
      "last_name": "Austin",
      "email": "*****@*****.**",
      "phone": "3339991111",
      "street": "10 Pine",
      "city": "Boston",
      "state": "Wyoming",
      "hnt_wallet": "33sDK9KUao8SudAgzRzKHQT5JjvKdG7v9bUzpu6LEb85DyYuMrg",
      'payment_method': 'fiat'
    },
    {
      "zip": "11222",
      "first_name": "Bill",
      "last_name": "Collins",
      "email": "*****@*****.**",
      "phone": "1110002222",
      "street": "10 Pine",
      "city": "New York",
      "state": "Delaware",
      "hnt_wallet": "33sDK9KUao8SudAgzRzKHQT5JjvKdG7v9bUzpu6LEb85DyYuMrg",
      'payment_method': 'bank_account'
    },
  ]

  for host in hosts:
    existing = Host.query.filter_by(email=host['email']).first()

    if not existing:
      # noinspection PyArgumentList
      db.session.add(Host(
        email=host['email'],
        first_name=host['first_name'],
        last_name=host['last_name'],
        phone=host['phone'],
        street=host['street'],
        city=host['city'],
        state=host['state'],
        zip=host['zip'],
        hnt_wallet=host['hnt_wallet'],
        payment_method=host['payment_method']
      ))
      db.session.commit()
Ejemplo n.º 10
0
 def _on_broadcast_received(self, header, host: Host, method: str,
                            message: str):
     # Note: Broadcast is not dynamic
     if host.id != self.own_host.id:
         host.unicast_port = message
         if DEBUG:
             print(
                 f"[BROADCAST:REC:{method}] {message} from {host.address}:{host.unicast_port} ({host.id})"
             )
         self.on_broadcast_delivered(host, method, message)
Ejemplo n.º 11
0
    def on_unicast_received(self, host: Host, method: str, message: str):
        if method == "SERVER/WELCOME":
            print("Got other host, stop broadcasting")
            self.discovery_service.stop_broadcasting()
            data = json.loads(message)
            host = Host.from_json(data.get("host"))
            hosts = json.loads(data.get("hosts"))
            list_of_hosts = [Host.from_json(h) for h in hosts]
            for new_host in list_of_hosts:
                self.currently_initializing.append(new_host.id)
                self.socket_service.send_unicast(new_host, "SERVER/JOIN", "")
        if method == "SERVER/JOIN":
            self.all_host_group.add_participant(host)
            print("ANSWERED HOST!")
            current_leader = False
            if self.election_service.current_leader:
                current_leader = self.election_service.current_leader == self.own_host
            self.socket_service.send_unicast(host, "SERVER/JOINED",
                                             str(current_leader))
        if method == "SERVER/JOINED":
            print("Got answer from host!")
            self.all_host_group.add_participant(host)
            self.currently_initializing.remove(host.id)
            if message == "True":
                print("Got leader")
                self.election_service.set_leader(host.id)

            if len(self.currently_initializing) == 0:
                self.socket_service.add_group(self.all_host_group)

                self.all_host_group.announce_participants()

                self.socket_service.send_unicast(
                    self.election_service.current_leader, "GS/SYNC_GAMES", '')

                time.sleep(3)
                if not self.election_service.leader_elected():
                    self.election_service.start_election()

        elif method == "HB":
            self.heartbeat_service.on_heartbeat_received(host, message)
        self.election_service.on_message_received(host, method, message)
        self.game_service.on_unicast_received(host, method, message)
Ejemplo n.º 12
0
    def __init__(self):
        self.own_host = Host(str(uuid.uuid1()), get_local_address(),
                             get_random_unicast_port(), HostType.SERVER)

        print(
            f'############################################ \n'
            f'# SERVER                                     \n'
            f'# Id: {self.own_host.id} #\n'
            f'# Address: {self.own_host.address}:{self.own_host.unicast_port}       #\n'
            f'############################################ \n')

        self.socket_service = SocketService(self.own_host, self.on_host_failed)
        self.socket_service.set_on_broadcast_delivered(
            self.on_broadcast_received)
        self.socket_service.set_on_multicast_delivered(
            self.on_server_multicast_received)
        self.socket_service.set_on_unicast_delivered(self.on_unicast_received)

        self.currently_initializing = []
        self.in_init = False
        self.ring = Ring(self.own_host)
        self.server_ring = Ring(self.own_host)

        self.all_host_group = KnownHostGroup(self.own_host, self.ring,
                                             self.server_ring,
                                             self.socket_service)
        self.all_host_group.add_participant(self.own_host)

        self.election_service = LCRElection(self.socket_service, self.own_host,
                                            self.server_ring,
                                            self.all_host_group)

        self.discovery_service = DiscoveryService(self.own_host,
                                                  self.socket_service,
                                                  self.discovery_counter)

        self.game_service = GameService(self.socket_service,
                                        self.all_host_group)

        self.heartbeat_service = HeartbeatService(self.own_host, self.ring,
                                                  self.socket_service)
        self.heartbeat_service.set_on_heartbeat_missing(self.on_host_missing)

        self.discovery_service.daemon = True
        self.socket_service.daemon = True
        self.heartbeat_service.daemon = True

        self.discovery_service.start_broadcasting()
        self.heartbeat_service.start_heartbeat()

        self.socket_service.start()
        self.discovery_service.start()

        self.socket_service.join()
        self.discovery_service.join()
Ejemplo n.º 13
0
    def __init__(self):
        self.own_host = Host(str(uuid.uuid1()), get_local_address(),
                             get_random_unicast_port(), HostType.CLIENT)

        self.current_game = None
        self.currently_initializing = []
        self.leader = None

        print(
            f'############################################ \n'
            f'# CLIENT                                     \n'
            f'# Id: {self.own_host.id} #\n'
            f'# Address: {self.own_host.address}:{self.own_host.unicast_port}       #\n'
            f'############################################ \n')

        self.ring = Ring(self.own_host)
        self.server_ring = Ring(self.own_host)

        self.socket_service = SocketService(self.own_host, self.on_host_failed)
        self.socket_service.sockets.remove(
            self.socket_service.broadcast_socket)
        self.all_host_group = KnownHostGroup(self.own_host, self.ring,
                                             self.server_ring,
                                             self.socket_service)
        self.all_host_group.add_participant(self.own_host)

        self.socket_service.set_on_broadcast_delivered(
            self.on_broadcast_received)
        self.socket_service.set_on_multicast_delivered(
            self.on_server_multicast_received)
        self.socket_service.set_on_unicast_delivered(self.on_unicast_received)

        self.discovery_service = DiscoveryService(self.own_host,
                                                  self.socket_service, None)

        self.heartbeat_service = HeartbeatService(self.own_host, self.ring,
                                                  self.socket_service)
        self.heartbeat_service.set_on_heartbeat_missing(self.on_host_missing)
        self.keybord = KeyboardThread(self.take_input)

        self.discovery_service.daemon = True
        self.keybord.daemon = True
        self.socket_service.daemon = True

        self.discovery_service.start_broadcasting()
        self.heartbeat_service.start_heartbeat()

        self.socket_service.start()
        self.discovery_service.start()
        self.keybord.start()

        self.keybord.join()
        self.socket_service.join()
        self.discovery_service.join()
Ejemplo n.º 14
0
 def on_multicast_received(self, host, method: str, message, header):
     if method == "MAIN_GROUP/HOSTS":
         if 'resent' not in header:
             hosts = json.loads(message)
             list_of_hosts = [Host.from_json(h) for h in hosts]
             self.set_host_list(list_of_hosts)
     if method == "MAIN_GROUP/GET_HOSTS":
         self.socket_service.send_group_multicast(
             self,
             f"MAIN_GROUP/HOSTS",
             json.dumps([ob.to_json() for ob in self.participants]),
         )
Ejemplo n.º 15
0
def add_host():
    data = request.json
    new_host = Host.make_new(data)

    if 'w9_received' in data:
        new_host.w9_received = data['w9_received']

    db.session.add(new_host)
    db.session.commit()
    return Response('Host {} {} created'.format(new_host.first_name,
                                                new_host.last_name),
                    status=201,
                    mimetype='application/json')
Ejemplo n.º 16
0
    def on_server_multicast_received(self, host: Host, method: str,
                                     message: str, header):

        self.all_host_group.on_multicast_received(host, method, message,
                                                  header)
        self.election_service.on_message_received(host, method, message)
        if method == "MAIN_GROUP/HOSTS":
            hosts = json.loads(message)
            list_of_hosts_id = [Host.from_json(h).id for h in hosts]
            if self.election_service.current_leader and self.election_service.current_leader.id not in list_of_hosts_id:
                self.election_service.start_election()
            elif not self.election_service.current_leader:
                self.election_service.start_election()
        self.game_service.on_multicast_received(host, method, message)
Ejemplo n.º 17
0
    def run(self):
        print(
            f"[BROADCAST] Start listening {self.broadcast_socket.address}:{self.broadcast_socket.port}"
        )
        print(
            f"[UNICAST] Start listening {self.unicast_socket.address}:{self.unicast_socket.port}"
        )
        print(
            f"[MULTICAST] Start listening {self.multicast_socket.address}:{self.multicast_socket.port}"
        )
        while True:
            # Await an event on a readable socket descriptor
            (read, write, exception) = select.select(self.sockets, [], [])
            # Iterate through the tagged read descriptors
            for error in exception:
                print("GOT ERROR IN ", error)
            for wr in write:
                print("GOT WRITE IN ", wr)
            for receiver in read:
                try:
                    data, address = receiver.recvfrom(BUFFER_SIZE)

                    hostname = address[0]
                    port = address[1]

                    header, payload = self._from_message(data)

                    host = Host(header.get('id'), hostname, header.get('p'),
                                header.get('t'))

                    method = header.get('m')

                    if receiver == self.broadcast_socket:
                        self._on_broadcast_received(header, host, method,
                                                    payload)
                    elif receiver == self.unicast_socket:
                        self._on_unicast_received(header, host, method,
                                                  payload)
                    elif receiver == self.multicast_socket:
                        self._on_reliable_multicast_received(
                            header, host, method, payload)
                except Exception as e:
                    if e and hasattr(e, 'errno') and e.errno == 10054:
                        self.on_host_failed()
                        print("Host failed! We dont know which one :(")
                    else:
                        print("Exception", e)
                        traceback.print_exc()
                    continue
Ejemplo n.º 18
0
    def on_select_scan(id):
        query = "SELECT * FROM Hosts WHERE ScanID = ?"
        params = (id, )

        data = df.DBFunctions.get_all_where(query, params)
        test = df.DBFunctions.retrieve_scanID_data(id)
        print('\n\n\n\nGetting Data\n')
        print(data)
        print('\n')
        print(test)
        # these need to be set, but not sure if the cpes and vulns are differentiate
        # by scans like hosts are
        # todo: set cpes and vulns in DataShare
        print('\n\n\n\nCPES')
        #todo this changes depending on if a scan has been run
        print(DataShare.get_cpes())
        print('\n\nVULNS')
        #todo these are 2.2 cpes...
        print(DataShare.get_vulns())
        print('\n\n\n\n')

        curr_hosts = []
        # for each host scanned
        for host_raw in data:
            host_id = host_raw[0]

            ip = host_raw[1]
            state = "Old Host"
            mac = host_raw[2]
            os_gen = host_raw[3]
            os_family = host_raw[4]
            name = host_raw[5]
            vendor = host_raw[6]

            curr_hosts.append(
                Host(host_id, ip, state, name, os_family, os_gen, vendor, mac))

        set_host(curr_hosts)
Ejemplo n.º 19
0
 def on_unicast_received(self, host: Host, method: str, message: str):
     if method == "SERVER/WELCOME":
         print("Got other host, stop broadcasting")
         self.discovery_service.stop_broadcasting()
         data = json.loads(message)
         hosts = json.loads(data.get("hosts"))
         list_of_hosts = [Host.from_json(h) for h in hosts]
         for new_host in list_of_hosts:
             self.currently_initializing.append(new_host.id)
             self.socket_service.send_unicast(new_host, "SERVER/JOIN", "")
     elif method == "SERVER/JOINED":
         print("Got answer from host!")
         self.all_host_group.add_participant(host)
         self.currently_initializing.remove(host.id)
         if message == "True":
             print("Got leader")
             self.leader = host
         if len(self.currently_initializing) == 0:
             print("Announce new group")
             self.socket_service.add_group(self.all_host_group)
             self.all_host_group.announce_participants()
             self.run_game()
     if method == "SERVER/JOIN":
         self.all_host_group.add_participant(host)
         print("ANSWERED HOST!")
         current_leader = False
         self.socket_service.send_unicast(host, "SERVER/JOINED",
                                          str(current_leader))
     elif method == "GS/MS":
         print(message)
     elif method == "GS/ERROR":
         self.run_game()
         print(message)
     elif method == "GS/LS":
         self.run_game()
         print(message)
     elif method == "HB":
         self.heartbeat_service.on_heartbeat_received(host, message)
Ejemplo n.º 20
0
    def get_scan_details(self, scan_type):
        """Runs scan to determine OS and running service of given host

        :return array of host data found in scan
        """
        result = None
        # Check scan type
        if scan_type == System.ScanType.full_scan:
            result = self.full_scan()
        elif scan_type == System.ScanType.script_scan:
            result = self.script_scan()
        elif scan_type == System.ScanType.udp_scan:
            result = self.udp_scan()
        elif scan_type == System.ScanType.fast_scan:
            result = self.fast_scan()
        elif scan_type == System.ScanType.detect_os_service_scan:
            result = self.detect_os_service_scan()

        hosts = []
        if self._scanned:
            # for each host scanned
            for host in self._scanner.all_hosts():
                print("-----------------")
                print(result['scan'][host])
                print("-----------------")
                state = result['scan'][host]["status"]["state"]
                mac = self.get_mac_address(result, host)
                vendor = self.get_vendor(result, host, mac)
                val_arr = self.get_os_details(result, host)
                name = val_arr[0]
                os_gen = val_arr[1]
                os_family = val_arr[2]
                hosts.append(
                    Host(0, host, state, name, os_family, os_gen, vendor, mac))

        return hosts
Ejemplo n.º 21
0
    while True:
        (read, write, exception) = select.select([multicast_socket], [], [])
        # Iterate through the tagged read descriptors
        for receiver in read:
            try:
                data, address = receiver.recvfrom(BUFFER_SIZE)

                encoded_data = data.decode('utf-8')
                hostname = address[0]
                port = address[1]
                chunks = encoded_data.split(HEADER_DELIMITER)
                header = json.loads(chunks[0])
                method = header.get('m')
                message = ''
                if len(chunks) > 1:
                    message = chunks[1]
                message_chunks = message.split(PAYLOAD_DELIMITER)
                if method == "LCR/LEADER_CHANGED":
                    leader_id = message_chunks[0]
                    render()
                elif method == "MAIN_GROUP/HOSTS":
                    print("GOT HOST UPDATE")
                    if 'resent' not in header:
                        hosts = json.loads(message)
                        hosts = [Host.from_json(h) for h in hosts]
                        render()
            except Exception as e:
                print("Exception", e)
                traceback.print_exc()
                continue
Ejemplo n.º 22
0
def get_host():
    return Host.show(request.args.get('host_id')).serialize()
Ejemplo n.º 23
0
def signup_host():
    new_host = Host.make_new(request.json)
    db.session.add(new_host)
    db.session.commit()
    return Response('submit success', status=201, mimetype='application/json')
Ejemplo n.º 24
0
def update_host():
    Host.update(request.json)
    return Response('host updated', status=200, mimetype='application/json')
Ejemplo n.º 25
0
    def scan_thread_completion():
        """Scan given inputs, update associated ui, and save scan data"""
        scan_start_date = datetime.datetime.now()
        update_left_header_label("Scan in process...")
        scan_button.config(state="disabled")
        waiting_scanner1 = STimer.do_after(
            update_left_header_label_random_waiting_msg, 15)
        waiting_scanner2 = STimer.do_after(
            update_left_header_label_random_waiting_msg, 30)
        waiting_scanner3 = STimer.do_after(
            update_left_header_label_random_waiting_msg, 45)

        ports = f'{port_start_entry_var.get()}-{port_end_entry_var.get()}'
        hosts = scan_host_entry_var.get()
        scanner = Scanner(hosts, ports)

        set_host(scanner.get_scan_details(System.Settings.get_scan_type()))
        set_cpes_vulns(scanner.get_cpes())

        scan_button.config(state="normal")
        scan_details_view.check_vulnerabilities_button.config(state="normal")

        scan_end_date = datetime.datetime.now()
        timedelta = scan_end_date - scan_start_date
        timedelta.total_seconds()

        last_row_id = df.DBFunctions.save_scan(scan_start_date,
                                               timedelta.total_seconds())

        for host in get_hosts():
            df.DBFunctions.save_host(host, last_row_id)

        query = "SELECT * FROM Hosts WHERE ScanID = ?"
        host_tuple = df.DBFunctions.get_all_where(query, (last_row_id, ))
        hosts_with_ID = []

        for id_host in host_tuple:
            temp = Host(id_host[0], id_host[1], "Old Host", id_host[5],
                        id_host[3], id_host[4], id_host[6], id_host[2])
            hosts_with_ID.append(temp)

        set_host(hosts_with_ID)

        ip_list = [*DataShare.get_cpes()]
        cpe_list = DataShare.get_cpes()

        for ip in ip_list:
            for item in hosts_with_ID:
                if item.get_ip() == ip:
                    cpe_list[item.get_id()] = cpe_list.pop(ip)

        DataShare.set_cpes(cpe_list)
        cves_with_host = df.DBFunctions.query_cves(cpe_list)

        for i in cves_with_host:
            for j in i:
                df.DBFunctions.save_cve_by_host(i, j)

        update_left_header_label(f"Scan finished in {timedelta} seconds")
        STimer.do_after(reset_left_header_label, 2)
        waiting_scanner1.cancel()
        waiting_scanner2.cancel()
        waiting_scanner3.cancel()
Ejemplo n.º 26
0
    def _on_unicast_received(self, header, host: Host, method: str,
                             message: str):
        if method == 'ACK':
            host.open_ack = False
        elif method == "SEQ/PROP":
            if DEBUG:
                print(
                    f"[UNICAST:REC:{method}] {message} from {host.address}:{host.unicast_port} ({host.id})"
                )

            message_payload = json.loads(message)
            message_id = message_payload.get("m_id")
            group_id = message_payload.get("g_id")
            suggested_sequence_number = message_payload.get("s_seq")
            group = self._find_group(group_id)

            hold_back_message = self._find_hold_back_message_by_id(
                group, message_id)

            if not hold_back_message:
                print("Multicast could not get message for proposal",
                      message_id)
                return
            if 'suggested_numbers' not in hold_back_message:
                hold_back_message['suggested_numbers'] = {}

            hold_back_message['suggested_numbers'][header.get(
                'id')] = suggested_sequence_number

            if DEBUG:
                print(
                    f"Proposal {message_id} with {group.participants} participants"
                )

            if len(hold_back_message['suggested_numbers'].keys()) >= len(group.participants) and self.own_host.id in \
                    hold_back_message['suggested_numbers'].keys():
                # choose smallest possible value for identity if there are multiple suggesting this sequence
                if DEBUG:
                    print(
                        f"Number of participants {hold_back_message['suggested_numbers']}"
                    )
                max_value = 0
                max_key = None
                for [k, v] in hold_back_message['suggested_numbers'].items():
                    if v > max_value:
                        max_value = v
                        if not max_key or max_key < k:
                            max_key = k

                self.send_group_multicast(
                    group, "SEQ/ANNOUNCEMENT",
                    json.dumps({
                        "m_id": message_id,
                        "max_suggested_seq": max_value,
                        "max_suggested_process_id": max_key
                    }))
        else:
            self.send_unicast(host, "ACK", header.get('seq'))
            host.last_message_seq = header.get('seq')
            if DEBUG and not method == 'ACK':
                if method != "HB" or HEARTBEAT:
                    print(
                        f"[UNICAST:REC:{method}] {message} from {host.address}:{host.unicast_port} ({host.id})"
                    )
            self.on_unicast_delivered(host, method, message)
Ejemplo n.º 27
0
    def _on_reliable_multicast_received(self, header, host, method, message):
        if 't' in header and header.get('t') == 'monitor':
            self.on_multicast_delivered(host, method, message, header)
            return

        group_identifier = header["g_ident"]
        group = self._find_group(group_identifier)

        if not group:
            print(f"Not in group {group_identifier}, discard")
            return

        if method == "REL_NACK":
            payload = json.loads(message)
            missing_sender_id = payload.get('s')
            missing_seq = payload.get('seq')
            if missing_sender_id in group.rel_message_history:
                process_messages = group.rel_message_history[missing_sender_id]
                if missing_seq in process_messages:
                    missed_message = group.rel_message_history[
                        missing_sender_id][missing_seq]
                    if missed_message:
                        self._resend_reliable_group_multicast(
                            group, missed_message.get("header"),
                            missed_message.get("message"))
        else:
            host = host
            if 'rel_orig_header' in header:
                original_header = header['rel_orig_header']
                host = Host(id=original_header['id'],
                            address=original_header['a'],
                            unicast_port=original_header['p'],
                            host_type=original_header['t'])

            acknowledgements = header.get('rel_delivered_seq')

            if host.id not in group.rel_delivered_seq:
                group.rel_delivered_seq[host.id] = int(header['rel_seq']) - 1

            last_delivered_from_process = group.rel_delivered_seq[host.id]

            self._add_rel_message_to_hold_back(host, group, header['rel_seq'],
                                               header, message)
            group.rel_hold_back_queue[host.id] = sorted(
                group.rel_hold_back_queue[host.id], key=lambda t: t.get("seq"))
            hold_back_copy = []
            for item in group.rel_hold_back_queue[host.id]:
                process_group_seq = item['seq']
                if int(process_group_seq) == last_delivered_from_process + 1:
                    if host.id not in group.rel_delivered_seq:
                        group.rel_delivered_seq[host] = -1
                    group.rel_delivered_seq[
                        host.id] = group.rel_delivered_seq[host.id] + 1
                    if host.id not in group.rel_message_history:
                        group.rel_message_history[host.id] = {}
                    group.rel_message_history[
                        host.id][process_group_seq] = item

                    self._on_multicast_received(host, group, item['header'],
                                                item['header']['m'],
                                                item['message'])
                elif int(process_group_seq) <= last_delivered_from_process:
                    if DEBUG:
                        pass
                        # print("already seen, drop", process_group_seq)
                else:
                    hold_back_copy.append(item)
                    missing_messages = {}
                    for ack_host, ack_seq in acknowledgements.items():
                        if ack_host not in group.rel_delivered_seq:
                            group.rel_delivered_seq[ack_host] = int(
                                ack_seq) - 1
                        if ack_seq > group.rel_delivered_seq[ack_host]:
                            missing_messages[ack_host] = ack_seq

                    if len(missing_messages.keys()) > 0:
                        for host_id, last_acK in sorted(
                                missing_messages.items(), key=lambda t: t[1]):
                            for sequence_number in range(
                                    group.rel_delivered_seq[host_id] + 1,
                                    last_acK + 1):
                                existing = [
                                    holdback for holdback in
                                    group.rel_hold_back_queue[host_id]
                                    if holdback.get("seq") == sequence_number
                                ]
                                if len(existing) == 0:
                                    self._send_rel_group_multicast_nack(
                                        group, host_id, sequence_number)

            group.rel_hold_back_queue[host.id] = hold_back_copy