Ejemplo n.º 1
0
 def listen_to_the_team(self):
     Peer_DBS.listen_to_the_team(self)
     self.mcast_socket = socket(socket.AF_INET, socket.SOCK_DGRAM)
     self.mcast_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
     self.mcast_socket.bind(('', 1234))  # Listen any interface,
     # including 224.0.0.1
     self.lg.debug("{}: port 1234 bound to 0.0.0.0".format(self.ext_id))
Ejemplo n.º 2
0
    def disconnect_from_the_splitter(self):
        # {{{

        # Close the TCP socket
        Peer_DBS.disconnect_from_the_splitter(self)

        # Use UDP to create a working NAT entry
        self.say_hello(self.splitter)
        self.say_hello(self.splitter)
        self.say_hello(self.splitter)
Ejemplo n.º 3
0
    def disconnect_from_the_splitter(self):
        # {{{

        self.start_send_hello_thread()

        # Receive the generated ID for this peer from splitter
        self.receive_id()

        # There are currently no other peers in the team
        self.initial_peer_list = []

        # Close the TCP socket
        Peer_DBS.disconnect_from_the_splitter(self)
Ejemplo n.º 4
0
 def instance(self, args):
     Peer_DBS.peer_port = int(args.peer_port)
     Peer_DBS.splitter = (args.splitter_address, int(args.splitter_port))
     if args.set_of_rules == "DBS":
         self.peer = Peer_DBS("P", "Peer_DBS", args.loglevel)
     else:
         self.peer = Peer_IMS("P", "Peer_IMS", args.loglevel)
Ejemplo n.º 5
0
    def process_next_message(self):
        chunk_number = Peer_DBS.process_next_message(self)
        if chunk_number > 0 and self.current_sender != self.splitter:
            if self.counter == 0:
                self.send_chunk_hash(chunk_number)
                self.counter = self.calculate_next_sampled()
            else:
                self.counter -= 1

        return chunk_number
Ejemplo n.º 6
0
    def run_a_peer(self, splitter_id, type, id, first_monitor=False):
        total_peers = self.number_of_monitors + self.number_of_peers + self.number_of_malicious
        chunks_before_leave = np.random.weibull(2) * (
            total_peers * (self.number_of_rounds - self.current_round))
        if type == "monitor":
            if first_monitor is True:
                chunks_before_leave = 99999999
            if self.set_of_rules == "dbs":
                peer = Monitor_DBS(id)
            elif self.set_of_rules == "cis":
                self.lg.info("simulator: Monitors are TPs in CIS")
                peer = Monitor_STRPEDS(id)
            elif self.set_of_rules == "cis-sss":
                self.lg.info("simulator: Monitors are TPs in CIS")
                peer = Monitor_SSS(id)
        elif type == "malicious":
            if self.set_of_rules == "cis":
                peer = Peer_Malicious(id)
            elif self.set_of_rules == "cis-sss":
                peer = Peer_Malicious_SSS(id)
            else:
                self.lg.info(
                    "simulator: Malicious peers are only compatible with CIS")
        else:
            if self.set_of_rules == "dbs":
                peer = Peer_DBS(id)
            elif self.set_of_rules == "cis":
                peer = Peer_STRPEDS(id)
            elif self.set_of_rules == "cis-sss":
                peer = Peer_SSS(id)
        self.lg.info("simulator: {}: alive till consuming {} chunks".format(
            id, chunks_before_leave))

        peer.chunks_before_leave = chunks_before_leave
        peer.set_splitter(splitter_id)
        # peer.set_id()
        peer.connect_to_the_splitter()
        peer.receive_buffer_size()
        peer.receive_the_number_of_peers()
        peer.listen_to_the_team()
        peer.receive_the_list_of_peers()
        peer.send_ready_for_receiving_chunks()
        peer.send_peer_type()  #Only for simulation purpose
        # peer.buffer_data()
        # peer.start()
        peer.run()
        '''
        while not peer.ready_to_leave_the_team:
            if type != "malicious" and peer.number_of_chunks_consumed >= chunks_before_leave and peer.player_alive:
                self.lg.info("simulator:", id, "reached the number of chunks consumed before leave", peer.number_of_chunks_consumed)
                peer.player_alive = False
            time.sleep(1)
        '''
        self.lg.info("simulator: {}: left the team".format(id))
Ejemplo n.º 7
0
    def process_message(self, message, sender):
        if sender in self.bad_peers:
            return -1

        if self.is_current_message_from_splitter() or self.check_message(message, sender):
            if self.is_control_message(message) and message == 'B':
                return self.handle_bad_peers_request()
            else:
                return Peer_DBS.process_message(self, message, sender)
        else:
            self.process_bad_message(message, sender)
            return -1
Ejemplo n.º 8
0
    def process_message(self, message, sender):
        if sender in self.bad_peers:
            return -1

        if self.is_current_message_from_splitter() or self.check_message(message, sender):
            if self.is_control_message(message) and message == 'B':
                return self.handle_bad_peers_request()
            else:
                return Peer_DBS.process_message(self, message, sender)
        else:
            self.process_bad_message(message, sender)
            return -1
Ejemplo n.º 9
0
 def receive_the_next_message(self):
     message, sender = Peer_DBS.receive_the_next_message(self)
     self.current_sender = sender
     return message, sender
Ejemplo n.º 10
0
    def process_message(self, message, sender):
        # {{{ Handle NTS messages; pass other messages to base class

        if sender == self.splitter and \
        len(message) == Common.PEER_ID_LENGTH + struct.calcsize("4sHHH"):
            # say [hello to (X)] received from splitter
            peer_id = message[:Common.PEER_ID_LENGTH].decode()
            IP_addr, source_port_to_splitter, port_diff, peer_number = \
                struct.unpack("4sHHH", message[Common.PEER_ID_LENGTH:])
            IP_addr = socket.inet_ntoa(IP_addr)
            source_port_to_splitter = socket.ntohs(source_port_to_splitter)
            port_diff = socket.ntohs(port_diff)
            peer_number = socket.ntohs(peer_number)

            peer = (IP_addr, source_port_to_splitter)  # Endpoint to splitter
            _p_("Received [send hello to %s %s]" % (peer_id, peer))
            _p_("port_diff = %s" % port_diff)
            _p_("peer_number = %s" % peer_number)
            # Here the port prediction happens:
            additional_ports = \
                self.get_probable_source_ports(source_port_to_splitter,
                                               port_diff, peer_number)
            self.say_hello(peer, additional_ports)
            # Directly start packet sending
            self.hello_messages_event.set()
        elif sender == self.splitter and \
        len(message) == Common.PEER_ID_LENGTH + struct.calcsize("4sHHHH"):
            # say [hello to (X)] received from splitter
            peer_id = message[:Common.PEER_ID_LENGTH].decode()
            IP_addr, source_port_to_splitter, port_diff, peer_number, \
                extra_splitter_port = struct.unpack( \
                "4sHHHH", message[Common.PEER_ID_LENGTH:]) # Ojo, !H ????
            IP_addr = socket.inet_ntoa(IP_addr)
            source_port_to_splitter = socket.ntohs(source_port_to_splitter)
            port_diff = socket.ntohs(port_diff)
            peer_number = socket.ntohs(peer_number)
            extra_splitter_port = socket.ntohs(extra_splitter_port)

            peer = (IP_addr, source_port_to_splitter)  # Endpoint to splitter
            _p_("Received [send hello to %s %s]" % (peer_id, peer))
            # Here the port prediction happens:
            additional_ports = \
                self.get_probable_source_ports(source_port_to_splitter,
                                               port_diff, peer_number)
            self.say_hello(peer, additional_ports)
            # Send to extra splitter port to determine currently allocated
            # source port
            self.say_hello((self.splitter[0], extra_splitter_port))
            # Directly start packet sending
            self.hello_messages_event.set()
        elif message == self.peer_id.encode() or (sender == self.splitter and \
        len(message) == Common.PEER_ID_LENGTH + struct.calcsize("H")) or \
        (sender == self.splitter and \
        len(message) == Common.PEER_ID_LENGTH+1 + struct.calcsize("H")) or \
        len(message) == Common.PEER_ID_LENGTH+1: # All sent message sizes
            # Acknowledge received; stop sending the message
            with self.hello_messages_lock:
                for hello_data in self.hello_messages:
                    if message == hello_data[0] \
                    and sender[0] == hello_data[1][0] \
                    and sender[1] in self.hello_messages_ports[hello_data]:
                        _p_("Received acknowledge from %s" % (sender, ))
                        self.hello_messages.remove(hello_data)
                        del self.hello_messages_times[hello_data]
                        del self.hello_messages_ports[hello_data]
                        # No chunk number, as no chunk was received
                        return -1
            _print_(Common.NTS_COLOR +
                    "NTS: Received acknowledge from unknown host %s" %
                    (sender, ) + Color.none)
        elif len(message) == Common.PEER_ID_LENGTH:
            peer_id = message.decode()
            _p_("Received [hello (ID %s)] from %s" % (message, sender))
            # Send acknowledge
            self.team_socket.sendto(message, sender)

            if sender not in self.peer_list:
                _p_("Appending peer %s %s to list" % (peer_id, sender))
                self.peer_list.append(sender)
                self.debt[sender] = 0
                # Send source port information to splitter
                message += struct.pack("H", socket.htons(sender[1]))
                message_data = (message, self.splitter)
                self.send_message(message_data)

                if peer_id in self.initial_peer_list:
                    self.initial_peer_list.remove(peer_id)
        elif message == b'H':
            _p_("Received [DBS hello] from %s" % str(sender))
            # Ignore hello messages that are sent by Peer_DBS instances in
            # receive_the_list_of_peers() before a Peer_NTS instance is created
            pass
        elif sender != self.splitter and sender not in self.peer_list:
            _p_("Ignoring message of length %d from unknown %s" \
                  % (len(message), sender))
        elif len(self.initial_peer_list) == 0:
            # Start receiving chunks when fully incorporated
            return Peer_DBS.process_message(self, message, sender)

        # No chunk number, as no chunk was received
        return -1
Ejemplo n.º 11
0
    def try_to_disconnect_from_the_splitter(self):
        # {{{

        self.start_send_hello_thread()

        # Receive the generated ID for this peer from splitter
        self.receive_id()

        # Note: This peer is *not* the monitor peer.

        # Send UDP packets to splitter and monitor peers
        # to create working NAT entries and to determine the
        # source port allocation type of the NAT of this peer
        for peer in self.peer_list[:self.number_of_monitors]:
            self.say_hello(peer)
        self.say_hello(self.splitter)
        # Directly start packet sending
        self.hello_messages_event.set()

        # A list of peer_ids that contains the peers that were in the team when
        # starting incorporation and that are not connected yet
        self.initial_peer_list = []
        # Receive the list of peers, except the monitor peer, with their peer
        # IDs and send hello messages
        self.receive_the_list_of_peers_2()

        # Wait for getting connected to all currently known peers
        incorporation_time = time.time()
        # A timeout < MAX_PEER_ARRIVING_TIME has to be set for self.team_socket
        # The monitor is not in initial_peer_list
        while len(self.initial_peer_list) > 0:
            if time.time(
            ) - incorporation_time > Common.MAX_PEER_ARRIVING_TIME:
                # Retry incorporation into the team
                _p_("Retrying incorporation with %d peers left: %s" \
                    % (len(self.initial_peer_list), self.initial_peer_list))
                incorporation_time = time.time()
                # Cleaning hello messages
                with self.hello_messages_lock:
                    self.hello_messages_times.clear()
                    self.hello_messages_ports.clear()
                    del self.hello_messages[:]
                # Resetting peer lists
                del self.initial_peer_list[:]
                del self.peer_list[self.number_of_monitors:]  # Leave monitors
                # Recreate the socket
                # Similar to Peer_DBS.listen_to_the_team, binds to a random port
                self.team_socket.close()
                self.create_team_socket()
                try:
                    self.team_socket.setsockopt(socket.SOL_SOCKET,
                                                socket.SO_REUSEADDR, 1)
                except Exception as e:
                    _print_(Common.NTS_COLOR + "NTS:" + Color.none, e)
                self.team_socket.bind(('', 0))
                self.team_socket.settimeout(1)
                # Say hello to splitter again, to retry incorporation
                # 'N' for 'not incorporated'
                self.send_message(
                    (self.peer_id.encode() + b'N', self.splitter))
                # Say hello to monitors again, to keep the NAT entry alive
                for peer in self.peer_list[:self.number_of_monitors]:
                    self.send_message((self.peer_id.encode() + b'N', peer))
                # Receive all peer endpoints and send hello messages
                self.receive_the_list_of_peers_2()

            # Process messages to establish connections to peers
            try:
                message, sender = self.team_socket.recvfrom( \
                    struct.calcsize(self.message_format))
                self.process_message(message, sender)
            except socket.timeout:
                pass

        # Close the TCP socket
        Peer_DBS.disconnect_from_the_splitter(self)
        # The peer is now successfully incorporated; inform the splitter
        self.send_message((self.peer_id.encode() + b'Y', self.splitter))
        _p_("Incorporation successful")
Ejemplo n.º 12
0
    parser.add_argument("-s", "--set-of-rules", help="set of rules")
    parser.add_argument("-a", "--splitter-address", help="Splitter address")
    parser.add_argument("-p",
                        "--splitter-port",
                        type=int,
                        help="Splitter port")
    parser.add_argument("-l",
                        "--chunks-before-leave",
                        type=int,
                        help="Number of chunk before leave the team")
    args = parser.parse_args()

    logging.basicConfig(
        format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')

    if args.set_of_rules == "dbs":
        peer = Peer_DBS("P")
    # elif self.set_of_rules == "ims":
    # splitter = Splitter_IMS()

    peer.chunks_before_leave = args.chunks_before_leave
    peer.set_splitter((args.splitter_address, args.splitter_port))
    peer.connect_to_the_splitter()
    peer.receive_buffer_size()
    peer.receive_the_number_of_peers()
    peer.listen_to_the_team()
    peer.receive_the_list_of_peers()
    peer.send_ready_for_receiving_chunks()
    peer.send_peer_type()  # Only for simulation purpose
    peer.run()
Ejemplo n.º 13
0
    def __init__(self):

        try:
            colorama.init()
        except Exception:
            pass

        _print_("Running in", end=' ')
        if __debug__:
            print("debug mode")
        else:
            print("release mode")

        # {{{ Args handling and object instantiation

        parser = argparse.ArgumentParser(
            description='This is the peer node of a P2PSP team.')

        parser.add_argument('--enable_chunk_loss',
                            help='Forces a lost of chunks')
        parser.add_argument(
            '--max_chunk_debt',
            help=
            'The maximun number of times that other peer can not send a chunk to this peer. Defaut = {}'
            .format(Peer_DBS.MAX_CHUNK_DEBT))
        parser.add_argument(
            '--player_port',
            help='Port to communicate with the player. Default = {}'.format(
                Peer_IMS.PLAYER_PORT))
        parser.add_argument(
            '--port_step',
            help=
            'Source port step forced when behind a sequentially port allocating NAT (conflicts with --chunk_loss_period). Default = {}'
            .format(Symsp_Peer.PORT_STEP))
        parser.add_argument(
            '--splitter_addr',
            help='IP address or hostname of the splitter. Default = {}.'.
            format(Peer_IMS.SPLITTER_ADDR))
        parser.add_argument(
            '--splitter_port',
            help='Listening port of the splitter. Default = {}.'.format(
                Peer_IMS.SPLITTER_PORT))
        parser.add_argument(
            '--port',
            help=
            'Port to communicate with the peers. Default {} (the OS will chose it).'
            .format(Peer_IMS.PORT))
        parser.add_argument(
            '--use_localhost',
            action="store_true",
            help=
            'Forces the peer to use localhost instead of the IP of the adapter to connect to the splitter. Notice that in this case, peers that run outside of the host will not be able to communicate with this peer.'
        )
        parser.add_argument('--malicious',
                            action="store_true",
                            help='Enables the malicious activity for peer.')
        parser.add_argument(
            '--persistent',
            action="store_true",
            help='Forces the peer to send poisoned chunks to other peers.')
        parser.add_argument(
            '--on_off_ratio',
            help=
            'Enables on-off attack and sets ratio for on off (from 1 to 100)')
        parser.add_argument(
            '--selective',
            nargs='+',
            type=str,
            help='Enables selective attack for given set of peers.')
        parser.add_argument(
            '--bad_mouth',
            nargs='+',
            type=str,
            help='Enables Bad Mouth attack for given set of peers.')
        parser.add_argument(
            '--trusted',
            action="store_true",
            help='Forces the peer to send hashes of chunks to splitter')
        parser.add_argument(
            '--checkall',
            action="store_true",
            help=
            'Forces the peer to send hashes of every chunks to splitter (works only with trusted option)'
        )
        parser.add_argument('--strpeds',
                            action="store_true",
                            help='Enables STrPe-DS')
        parser.add_argument(
            '--strpe_log',
            help='Logging STrPe & STrPe-DS specific data to file.')
        parser.add_argument('--show_buffer',
                            action="store_true",
                            help='Shows the status of the buffer of chunks.')

        try:
            argcomplete.autocomplete(parser)
        except Exception:
            pass

        #args = parser.parse_known_args()[0]
        args = parser.parse_args()

        if args.splitter_addr:
            Peer_IMS.SPLITTER_ADDR = socket.gethostbyname(args.splitter_addr)
        _print_('Splitter address =', Peer_IMS.SPLITTER_ADDR)

        if args.splitter_port:
            Peer_IMS.SPLITTER_PORT = int(args.splitter_port)
        _print_('Splitter port =', Peer_IMS.SPLITTER_PORT)

        if args.port:
            Peer_IMS.PORT = int(args.port)
        _print_('(Peer) PORT =', Peer_IMS.PORT)

        if args.player_port:
            Peer_IMS.PLAYER_PORT = int(args.player_port)
        _print_('Listening port (player) =', Peer_IMS.PLAYER_PORT)

        if args.max_chunk_debt:
            Peer_DBS.MAX_CHUNK_DEBT = int(args.max_chunk_debt)
        _print_('Maximun chunk debt =', Peer_DBS.MAX_CHUNK_DEBT)

        if args.use_localhost:
            Peer_IMS.USE_LOCALHOST = True
            _print_('Using localhost address')

        peer = Peer_IMS()
        peer.wait_for_the_player()
        peer.connect_to_the_splitter()
        peer.receive_the_mcast_endpoint()
        peer.receive_the_header_size()
        peer.receive_the_chunk_size()
        peer.receive_the_header()
        peer.receive_the_buffer_size()
        _print_("Using IP Multicast address =", peer.mcast_addr)

        if args.show_buffer:
            Peer_IMS.SHOW_BUFFER = True

        # A multicast address is always received, even for DBS peers.
        if peer.mcast_addr == "0.0.0.0":
            # {{{ IP unicast mode.

            peer = Peer_DBS(peer)
            peer.receive_my_endpoint()
            peer.receive_the_number_of_peers()
            _print_("Number of peers in the team (excluding me) =",
                    peer.number_of_peers)
            _print_("Am I a monitor peer? =", peer.am_i_a_monitor())
            peer.listen_to_the_team()
            peer.receive_the_list_of_peers()
            _print_("List of peers received")
            peer.receive_magic_flags()
            _print_("Magic flags =", peer.magic_flags)

            # After receiving the list of peers, the peer can check
            # whether is a monitor peer or not (only the first
            # arriving peers are monitors)
            if peer.am_i_a_monitor():
                from core.monitor_dbs import Monitor_DBS
                peer = Monitor_DBS(peer)
                _print_("Monitor DBS")

                # The peer is a monitor. Now it's time to know the sets of rules that control this team.

                if (peer.magic_flags & common.LRS):
                    from core.monitor_lrs import Monitor_LRS
                    peer = Monitor_LSR(peer)
                    _print_("Monitor LRS")
                if (peer.magic_flags & common.NTS):
                    from core.monitor_nts import Monitor_NTS
                    peer = Monitor_NTS(peer)
                    _print_("Monitor NTS")
            else:
                peer = Peer_DBS(peer)
                _print_("Peer DBS")

                # The peer is a normal peer. Let's know the sets of rules that control this team.

                if (peer.magic_flags & common.ACS):
                    peer = Peer_ACR(peer)
                    _print_("Peer ACS")
                if (peer.magic_flags & common.LRS):
                    peer = Peer_LSR(peer)
                    _print_("Peer LRS")
                if (peer.magic_flags & common.NTS):
                    from peer_nts import Peer_NTS
                    peer = Peeer_NTS(peer)
                    _print_("Peer NTS")

                if args.enable_chunk_loss:

                    if args.chunk_loss_period:
                        Lossy_Peer.CHUNK_LOSS_PERIOD = int(
                            args.chunk_loss_period)
                        print('CHUNK_LOSS_PERIOD =',
                              Lossy_Peer.CHUNK_LOSS_PERIOD)
                        if int(args.chunk_loss_period) != 0:
                            from lossy_peer import Lossy_Peer
                            peer = Lossy_Peer(peer)

            if args.port_step:
                Symsp_Peer.PORT_STEP = int(args.port_step)
                print('PORT_STEP =', Symsp_Peer.PORT_STEP)
                if int(args.port_step) != 0:
                    peer = Symsp_Peer(peer)

            if args.strpeds:
                from core.peer_strpeds import Peer_StrpeDs
                peer = Peer_StrpeDs(peer)
                peer.receive_dsa_key()

            if args.malicious and not args.strpeds:  # workaround for malicous strpeds peer
                from core.malicious_peer import MaliciousPeer
                peer = MaliciousPeer(peer)
                if args.persistent:
                    peer.setPersistentAttack(True)
                if args.on_off_ratio:
                    peer.setOnOffAttack(True, int(args.on_off_ratio))
                if args.selective:
                    peer.setSelectiveAttack(True, args.selective)

            if args.malicious and args.strpeds:
                from core.peer_strpeds_malicious import Peer_StrpeDsMalicious
                peer = Peer_StrpeDsMalicious(peer)
                if args.persistent:
                    peer.setPersistentAttack(True)
                if args.on_off_ratio:
                    peer.setOnOffAttack(True, int(args.on_off_ratio))
                if args.selective:
                    peer.setSelectiveAttack(True, args.selective)
                if args.bad_mouth:
                    peer.setBadMouthAttack(True, args.bad_mouth)

            if args.trusted:
                from core.trusted_peer import TrustedPeer
                peer = TrustedPeer(peer)
                if args.checkall:
                    peer.setCheckAll(True)

            if args.strpe_log != None:
                peer.LOGGING = True
                peer.LOG_FILE = open(args.strpe_log, 'w', 0)

            # }}}
        else:
            # {{{ IP multicast mode

            peer.listen_to_the_team()

            # }}}

        # }}}

        # {{{ Run!

        peer.disconnect_from_the_splitter()
        peer.buffer_data()
        peer.start()

        print("+-----------------------------------------------------+")
        print("| Received = Received kbps, including retransmissions |")
        print("|     Sent = Sent kbps                                |")
        print("|       (Expected values are between parenthesis)     |")
        print("------------------------------------------------------+")
        print()
        print(
            "    Time |     Received (Expected) |          Sent (Expected) | Team description"
        )
        print(
            "---------+-------------------------+--------------------------+-----------------..."
        )

        last_chunk_number = peer.played_chunk
        if hasattr(peer, 'sendto_counter'):
            last_sendto_counter = 0
        else:
            peer.sendto_counter = 0
            last_sendto_counter = 0
        if not hasattr(peer, 'peer_list'):
            peer.peer_list = []
        last_recvfrom_counter = peer.recvfrom_counter
        while peer.player_alive:
            time.sleep(1)
            kbps_expected_recv = ((peer.played_chunk - last_chunk_number) *
                                  peer.chunk_size * 8) / 1000
            last_chunk_number = peer.played_chunk
            kbps_recvfrom = ((peer.recvfrom_counter - last_recvfrom_counter) *
                             peer.chunk_size * 8) / 1000
            last_recvfrom_counter = peer.recvfrom_counter
            team_ratio = len(peer.peer_list) / (len(peer.peer_list) + 1.0)
            kbps_expected_sent = int(kbps_expected_recv * team_ratio)
            kbps_sendto = ((peer.sendto_counter - last_sendto_counter) *
                           peer.chunk_size * 8) / 1000
            last_sendto_counter = peer.sendto_counter
            try:
                if common.CONSOLE_MODE == False:
                    from gi.repository import GObject
                    try:
                        from adapter import speed_adapter
                    except ImportError as msg:
                        pass
                    GObject.idle_add(speed_adapter.update_widget,
                                     str(kbps_recvfrom) + ' kbps',
                                     str(kbps_sendto) + ' kbps',
                                     str(len(peer.peer_list) + 1))
            except Exception as msg:
                pass
            if kbps_recvfrom > 0 and kbps_expected_recv > 0:
                nice = 100.0 / float(
                    (float(kbps_expected_recv) / kbps_recvfrom) *
                    (len(peer.peer_list) + 1))
            else:
                nice = 0.0
            _print_('|', end=Color.none)
            if kbps_expected_recv < kbps_recvfrom:
                sys.stdout.write(Color.red)
            elif kbps_expected_recv > kbps_recvfrom:
                sys.stdout.write(Color.green)
            print(repr(kbps_expected_recv).rjust(12), end=Color.none)
            print(('(' + repr(kbps_recvfrom) + ')').rjust(12), end=' | ')
            #print(("{:.1f}".format(nice)).rjust(6), end=' | ')
            #sys.stdout.write(Color.none)
            if kbps_expected_sent > kbps_sendto:
                sys.stdout.write(Color.red)
            elif kbps_expected_sent < kbps_sendto:
                sys.stdout.write(Color.green)
            print(repr(kbps_sendto).rjust(12), end=Color.none)
            print(('(' + repr(kbps_expected_sent) + ')').rjust(12), end=' | ')
            #sys.stdout.write(Color.none)
            #print(repr(nice).ljust(1)[:6], end=' ')
            print(len(peer.peer_list), end=' ')
            counter = 0
            for p in peer.peer_list:
                if (counter < 5):
                    print(p, end=' ')
                    counter += 1
                else:
                    break
            print()
        try:
            if common.CONSOLE_MODE == False:
                GObject.idle_add(speed_adapter.update_widget,
                                 str(0) + ' kbps',
                                 str(0) + ' kbps', str(0))
        except Exception as msg:
            pass
Ejemplo n.º 14
0
    def process_message(self, message, sender):
        # {{{ Handle NTS messages; pass other messages to base class

        if sender == self.splitter and \
        len(message) == Common.PEER_ID_LENGTH + struct.calcsize("4sHHH"):
            # say [hello to (X)] received from splitter
            peer_id = message[:Common.PEER_ID_LENGTH].decode()
            IP_addr, source_port_to_splitter, port_diff, peer_number = \
                struct.unpack("4sHHH", message[Common.PEER_ID_LENGTH:])
            IP_addr = socket.inet_ntoa(IP_addr)
            source_port_to_splitter = socket.ntohs(source_port_to_splitter)
            port_diff = socket.ntohs(port_diff)
            peer_number = socket.ntohs(peer_number)

            peer = (IP_addr, source_port_to_splitter) # Endpoint to splitter
            _p_("Received [send hello to %s %s]" % (peer_id, peer))
            _p_("port_diff = %s" % port_diff)
            _p_("peer_number = %s" % peer_number)
            # Here the port prediction happens:
            additional_ports = \
                self.get_probable_source_ports(source_port_to_splitter,
                                               port_diff, peer_number)
            self.say_hello(peer, additional_ports)
            # Directly start packet sending
            self.hello_messages_event.set()
        elif sender == self.splitter and \
        len(message) == Common.PEER_ID_LENGTH + struct.calcsize("4sHHHH"):
            # say [hello to (X)] received from splitter
            peer_id = message[:Common.PEER_ID_LENGTH].decode()
            IP_addr, source_port_to_splitter, port_diff, peer_number, \
                extra_splitter_port = struct.unpack( \
                "4sHHHH", message[Common.PEER_ID_LENGTH:]) # Ojo, !H ????
            IP_addr = socket.inet_ntoa(IP_addr)
            source_port_to_splitter = socket.ntohs(source_port_to_splitter)
            port_diff = socket.ntohs(port_diff)
            peer_number = socket.ntohs(peer_number)
            extra_splitter_port = socket.ntohs(extra_splitter_port)

            peer = (IP_addr, source_port_to_splitter) # Endpoint to splitter
            _p_("Received [send hello to %s %s]" % (peer_id, peer))
            # Here the port prediction happens:
            additional_ports = \
                self.get_probable_source_ports(source_port_to_splitter,
                                               port_diff, peer_number)
            self.say_hello(peer, additional_ports)
            # Send to extra splitter port to determine currently allocated
            # source port
            self.say_hello((self.splitter[0], extra_splitter_port))
            # Directly start packet sending
            self.hello_messages_event.set()
        elif message == self.peer_id.encode() or (sender == self.splitter and \
        len(message) == Common.PEER_ID_LENGTH + struct.calcsize("H")) or \
        (sender == self.splitter and \
        len(message) == Common.PEER_ID_LENGTH+1 + struct.calcsize("H")) or \
        len(message) == Common.PEER_ID_LENGTH+1: # All sent message sizes
            # Acknowledge received; stop sending the message
            with self.hello_messages_lock:
                for hello_data in self.hello_messages:
                    if message == hello_data[0] \
                    and sender[0] == hello_data[1][0] \
                    and sender[1] in self.hello_messages_ports[hello_data]:
                        _p_("Received acknowledge from %s" % (sender,))
                        self.hello_messages.remove(hello_data)
                        del self.hello_messages_times[hello_data]
                        del self.hello_messages_ports[hello_data]
                        # No chunk number, as no chunk was received
                        return -1
            _print_(Common.NTS_COLOR + "NTS: Received acknowledge from unknown host %s" % (sender,) + Color.none)
        elif len(message) == Common.PEER_ID_LENGTH:
            peer_id = message.decode()
            _p_("Received [hello (ID %s)] from %s" % (message, sender))
            # Send acknowledge
            self.team_socket.sendto(message, sender)

            if sender not in self.peer_list:
                _p_("Appending peer %s %s to list" % (peer_id, sender))
                self.peer_list.append(sender)
                self.debt[sender] = 0
                # Send source port information to splitter
                message += struct.pack("H", socket.htons(sender[1]))
                message_data = (message, self.splitter)
                self.send_message(message_data)

                if peer_id in self.initial_peer_list:
                    self.initial_peer_list.remove(peer_id)
        elif message == b'H':
            _p_("Received [DBS hello] from %s" % str(sender))
            # Ignore hello messages that are sent by Peer_DBS instances in
            # receive_the_list_of_peers() before a Peer_NTS instance is created
            pass
        elif sender != self.splitter and sender not in self.peer_list:
            _p_("Ignoring message of length %d from unknown %s" \
                  % (len(message), sender))
        elif len(self.initial_peer_list) == 0:
            # Start receiving chunks when fully incorporated
            return Peer_DBS.process_message(self, message, sender)

        # No chunk number, as no chunk was received
        return -1
Ejemplo n.º 15
0
    def try_to_disconnect_from_the_splitter(self):
        # {{{

        self.start_send_hello_thread()

        # Receive the generated ID for this peer from splitter
        self.receive_id()

        # Note: This peer is *not* the monitor peer.

        # Send UDP packets to splitter and monitor peers
        # to create working NAT entries and to determine the
        # source port allocation type of the NAT of this peer
        for peer in self.peer_list[:self.number_of_monitors]:
            self.say_hello(peer)
        self.say_hello(self.splitter)
        # Directly start packet sending
        self.hello_messages_event.set()

        # A list of peer_ids that contains the peers that were in the team when
        # starting incorporation and that are not connected yet
        self.initial_peer_list = []
        # Receive the list of peers, except the monitor peer, with their peer
        # IDs and send hello messages
        self.receive_the_list_of_peers_2()

        # Wait for getting connected to all currently known peers
        incorporation_time = time.time()
        # A timeout < MAX_PEER_ARRIVING_TIME has to be set for self.team_socket
        # The monitor is not in initial_peer_list
        while len(self.initial_peer_list) > 0:
            if time.time() - incorporation_time > Common.MAX_PEER_ARRIVING_TIME:
                # Retry incorporation into the team
                _p_("Retrying incorporation with %d peers left: %s" \
                    % (len(self.initial_peer_list), self.initial_peer_list))
                incorporation_time = time.time()
                # Cleaning hello messages
                with self.hello_messages_lock:
                    self.hello_messages_times.clear()
                    self.hello_messages_ports.clear()
                    del self.hello_messages[:]
                # Resetting peer lists
                del self.initial_peer_list[:]
                del self.peer_list[self.number_of_monitors:] # Leave monitors
                # Recreate the socket
                # Similar to Peer_DBS.listen_to_the_team, binds to a random port
                self.team_socket.close()
                self.create_team_socket()
                try:
                    self.team_socket.setsockopt(socket.SOL_SOCKET,
                                                socket.SO_REUSEADDR, 1)
                except Exception as e:
                    _print_(Common.NTS_COLOR + "NTS:" + Color.none, e)
                self.team_socket.bind(('', 0))
                self.team_socket.settimeout(1)
                # Say hello to splitter again, to retry incorporation
                # 'N' for 'not incorporated'
                self.send_message((self.peer_id.encode() + b'N', self.splitter))
                # Say hello to monitors again, to keep the NAT entry alive
                for peer in self.peer_list[:self.number_of_monitors]:
                    self.send_message((self.peer_id.encode() + b'N', peer))
                # Receive all peer endpoints and send hello messages
                self.receive_the_list_of_peers_2()

            # Process messages to establish connections to peers
            try:
                message, sender = self.team_socket.recvfrom( \
                    struct.calcsize(self.message_format))
                self.process_message(message, sender)
            except socket.timeout:
                pass

        # Close the TCP socket
        Peer_DBS.disconnect_from_the_splitter(self)
        # The peer is now successfully incorporated; inform the splitter
        self.send_message((self.peer_id.encode() + b'Y', self.splitter))
        _p_("Incorporation successful")