Exemplo n.º 1
0
	def __create_socket(self) -> None:
		""" Create the passive socket

		:return: None
		"""
		try:
			# Create the socket
			self.ss = socket.socket(socket.AF_INET6, socket.SOCK_STREAM)
		except OSError as e:
			shell_colors.print_red(f'\nCan\'t create the socket: {e}\n')
			sys.exit(socket.error)

		try:
			# Set the SO_REUSEADDR flag in order to tell the kernel to reuse the socket even if it's in a TIME_WAIT state,
			# without waiting for its natural timeout to expire.
			# This is because sockets in a TIME_WAIT state can’t be immediately reused.
			self.ss.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
			self.ss.setsockopt(41, socket.IPV6_V6ONLY, 0)

			# Bind the local address (sockaddr) to the socket (ss)
			self.ss.bind(('', self.port))

			# Transform the socket in a passive socket and
			# define a queue of SOMAXCONN possible connection requests
			self.ss.listen(socket.SOMAXCONN)
		except OSError:
			shell_colors.print_red(f'\nCan\'t handle the socket: {OSError}\n')
			sys.exit(socket.error)
Exemplo n.º 2
0
    def show(self) -> None:
        """ Shows the menu that interacts with the user

		:return: None
		"""

        choice = ''
        while choice != 'q':
            print('\n- Main Menù ------------------------------')
            print('| <1> List files                         |')
            print('| <2> List peer\'s file parts             |')
            print('| <3> List logged peers                  |')
            print('------------------------------------------')
            choice = input('Select an option (q to exit): ')

            if choice in {'1', '2', '3'}:
                if choice == '1':
                    command = "LISTFILES"
                elif choice == '2':
                    command = "SHOWPARTS"
                elif choice == '3':
                    command = "LISTPEERS"

                self.handler.serve(command)
            elif choice != 'q':
                shell_colors.print_red(
                    'Input code is wrong. Choose one action!\n')

        shell_colors.print_blue('\nBye!\n')
Exemplo n.º 3
0
	def show(self) -> None:
		""" Shows the menu that interacts with the user

		:return: None
		"""

		choice = ''
		while choice != 'q':
			print('\n- Main Menù -----------------------')
			print('| <1> Search a file to download   |')
			print('| <2> Share a file                |')
			print('| <3> Delete a shared file        |')
			print('| <4> Show your superpeer         |')
			print('-----------------------------------')
			choice = input('Select an option (q to logout): ')

			if choice in {'1', '2', '3', '4'}:
				if choice == '1':
					command = 'FIND'
				elif choice == '2':
					command = 'ADFF'
				elif choice == '3':
					command = 'DEFF'
				elif choice == '4':
					command = 'SHOWSUPER'

				self.handler.serve(command)
			elif choice != 'q':
				shell_colors.print_red('Input code is wrong. Choose one action!\n')

		self.handler.serve('LOGO')
		shell_colors.print_blue('\nBye!\n')
Exemplo n.º 4
0
	def show(self) -> None:
		""" Shows the menu that interacts with the user

		:return: None
		"""

		choice = ''
		while choice != 'q':
			print('\n- Main Menù -----------------------')
			print('| <1> Search a file to download   |')
			print('| <2> Share a file                |')
			print('| <3> Files in sharing            |')
			print('| <4> Your tracker                |')
			print('-----------------------------------')
			choice = input('Select an option (q to logout): ')

			if choice in {'1', '2', '3', '4'}:
				if choice == '1':
					command = 'LOOK'
				elif choice == '2':
					command = 'ADDR'
				elif choice == '3':
					command = 'SHAR'
				elif choice == '4':
					command = 'TRAC'

				self.handler.serve(command)

			elif choice == 'q':

				self.handler.serve('LOGO')
				if LocalData.tracker_is_empty():
					break
				else:
					choice = ''
					continue

			elif choice != 'q':
				shell_colors.print_red('Input code is wrong. Choose one action!\n')

		# waiting 60s for any upload running
		spinner = SpinnerThread('Waiting for any upload in progress', '')
		spinner.start()

		timer = Timer(60, lambda: (self.server.stop(), spinner.stop()))
		timer.start()

		timer.join()
		spinner.join()
		LocalData.clear_shared_files()

		shell_colors.print_blue('\nYou leaved the Network\nBye!\n')
Exemplo n.º 5
0
def startup():

	while True:
		shell.print_blue('\nThis process will allow you to add a tracker.\n')
		tracker = net_utils.prompt_host_request('Insert a known host')
		LocalData.set_tracker(tracker)
		# LocalData.set_tracker(('172.16.1.', 'fc00::1:', 3000))

		# tenta login
		ip = net_utils.get_local_ip_for_response()
		port = str(net_utils.get_peer_port()).zfill(5)
		packet = "LOGI" + ip + port

		tracker_ip4 = LocalData.get_tracker_ip4()
		tracker_ip6 = LocalData.get_tracker_ip6()
		tracker_port = LocalData.get_tracker_port()

		try:
			sock = net_utils.send_packet(tracker_ip4, tracker_ip6, tracker_port, packet)
			response = sock.recv(50).decode()

			if len(response) != 20:
				shell.print_red(f'There was an error in the login process: unexpected: {response}.\nPlease retry.')
				continue

			session_id = response[4:20]

			if session_id == '0' * 16:
				shell.print_red(
					f'There was an error in the login process: unexpected session_id: {session_id}.\nPlease retry.')
				continue

			LocalData.session_id = session_id
			break

		except (socket.error, AttributeError):
			shell.print_yellow(f'Unable to contact {tracker_ip4}|{tracker_ip6} [{tracker_port}]')
			if sock is not None:
				sock.close()
			continue

	shell.print_green(f'Successfully logged to the tracker: {tracker_ip4}|{tracker_ip6} [{tracker_port}]\n')

	log = Logger.Logger('peer/peer.log')

	server = ServerThread(net_utils.get_peer_port(), UploadHandler.UploadHandler(log))
	server.daemon = True
	server.start()

	Menu(MenuHandler.MenuHandler(), server).show()
Exemplo n.º 6
0
	def __broadcast(self, packet: str) -> None:
		""" Send the packet to a pool of hosts

		:param packet: packet to be sent
		:return: None
		"""
		superfriends = LocalData.get_super_friends()

		for superfriend in superfriends:

			try:
				net_utils.send_packet_and_close(
					LocalData.get_super_friend_ip4(superfriend),
					LocalData.get_super_friend_ip6(superfriend),
					LocalData.get_super_friend_port(superfriend),
					packet)
			except socket.error as e:
				shell.print_red(f'\nUnable to send the packet on the socket: {e}')
				return
Exemplo n.º 7
0
def prompt_parameters_request() -> None:
    """ Guide the user to insert his local ip adresses and port in case there are not/they are wrong

	:return: None
	"""
    if '' in (config['ipv4'], config['ipv6']):
        shell_colors.print_blue(
            '\nYou need to add your own network configuration to get started.\n'
        )

    while True:
        if get_local_ipv4() == '':
            ip4 = input('Insert your local IPv4 address: ')
            try:
                ipaddress.IPv4Address(ip4)
            except ipaddress.AddressValueError:
                shell_colors.print_red(
                    f'\n{ip4} is not a valid IPv4 address, please retry.\n')
                continue
            set_local_ipv4(ip4)
            break
        else:
            try:
                ipaddress.IPv4Address(get_local_ipv4())
                break
            except ipaddress.AddressValueError:
                shell_colors.print_red(
                    f'\n{get_local_ipv4()} is not a valid IPv4 address, please reinsert it.\n'
                )
                set_local_ipv4('')
                continue

    while True:
        if get_local_ipv6() == '':
            ip6 = input('Insert your local IPv6 address: ')
            try:
                ipaddress.IPv6Address(ip6)
            except ipaddress.AddressValueError:
                shell_colors.print_red(
                    f'\n{ip6} is not a valid IPv6 address, please retry.\n')
                continue
            set_local_ipv6(ip6)
            break
        else:
            try:
                ipaddress.IPv6Address(get_local_ipv6())
                break
            except ipaddress.AddressValueError as e:
                shell_colors.print_red(
                    f'\n{get_local_ipv6()} is not a valid IPv6 address, please reinsert it.\n'
                )
                set_local_ipv6('')
                continue
Exemplo n.º 8
0
    def show(self) -> None:
        """ Shows the menu that interacts with the user

		:return: None
		"""

        choice = ''
        while choice != 'q':
            print('\n- Main Menù ----------------------------')
            print('| <1> Search a file to download          |')
            print('| <2> Search other superpeers around you |')
            print('| <3> Add a file                         |')
            print('| <4> Delete a file                      |')
            print('| <5> List your known superpeers         |')
            print('| <6> List your known peers              |')
            print('| <7> List all files                     |')
            print('------------------------------------------')
            choice = input('Select an option (q to exit): ')

            if choice in {'1', '2', '3', '4', '5', '6', '7'}:
                if choice == '1':
                    command = "QUER"
                elif choice == '2':
                    command = "SUPE"
                elif choice == '3':
                    command = "ADFF"
                elif choice == '4':
                    command = "DEFF"
                elif choice == '5':
                    command = "LISTSUPERPEERS"
                elif choice == '6':
                    command = "LISTPEERS"
                elif choice == '7':
                    command = "LISTFILES"

                self.handler.serve(command)
            elif choice != 'q':
                shell_colors.print_red(
                    'Input code is wrong. Choose one action!\n')

        shell_colors.print_blue('\nBye!\n')
Exemplo n.º 9
0
    def child(self, sd, clientaddr):
        (client, client_port) = socket.getnameinfo(clientaddr,
                                                   socket.NI_NUMERICHOST)
        self.ss.close()

        request = sd.recv(self.BUFF_SIZE)
        shell.print_green(f'{client} [{client_port}] -> ', end='')
        print(f'{request.decode()}', end='')

        response = handler.serve(request)
        sd.send(response.encode())
        shell.print_red(' -> ', end='')
        print(f'{response}')

        if response[0:4] == "ALGO":
            shell.print_blue(
                f'Client {client} [{client_port}] said goodbye! {int(response[4:])} files deleted.'
            )

        sd.close()
        os._exit(0)
Exemplo n.º 10
0
    def show(self) -> None:
        """ Shows the menu that interacts with the user

		:return: None
		"""

        choice = ''
        while choice != 'q':
            print('\n- Main Menù -----------------------')
            print('| <1> Search a file to download   |')
            print('| <2> Search all peers around you |')
            print('| <3> List peers                  |')
            print('| <4> Add a peer                  |')
            print('| <5> Remove a peer               |')
            print('-----------------------------------')
            choice = input('Select an option (q to exit): ')

            if choice in {'1', '2', '3', '4', '5'}:
                if len(AppData.get_neighbours()) == 0:
                    shell_colors.print_red(
                        '\n! You need to have at least one peer to get started !\n'
                    )
                    command = 'ADDPEER'
                elif choice == '1':
                    command = 'QUER'
                elif choice == '2':
                    command = 'NEAR'
                elif choice == '3':
                    command = 'LISTPEERS'
                elif choice == '4':
                    command = 'ADDPEER'
                elif choice == '5':
                    command = 'REMOVEPEER'

                self.handler.serve(command)
            elif choice != 'q':
                shell_colors.print_red(
                    'Input code is wrong. Choose one action!\n')

        shell_colors.print_blue('\nBye!\n')
Exemplo n.º 11
0
    def start(self) -> None:
        """ Start file download

		:return: None
		"""

        try:
            sock = self.__connect(self.host_ip4, self.host_ip6, self.host_port,
                                  self.packet)
        except socket.error as e:
            shell_colors.print_red(
                f'\nImpossible to send data to {self.host_ip4}|{self.host_ip6} [{self.host_port}]: {e}\n'
            )
            return

        ack = sock.recv(4).decode()
        if ack != "ARET":
            shell_colors.print_red(
                f'\nInvalid command received: {ack}. Expected: ARET\n')
            sock.close()
            return

        total_chunks = int(sock.recv(6).decode())
        shell_colors.print_blue(f'\n#chunk: {total_chunks}')

        try:
            f_obj = open('shared/' + self.file_name, 'wb')
        except OSError as e:
            shell_colors.print_red(f'\nSomething went wrong: {e}\n')
            raise e

        progress_bar.print_progress_bar(0,
                                        total_chunks,
                                        prefix='Downloading:',
                                        suffix='Complete',
                                        length=50)
        for i in range(total_chunks):
            chunk_size = sock.recv(5)
            # if not all the 5 expected bytes has been received
            while len(chunk_size) < 5:
                chunk_size += sock.recv(1)
            chunk_size = int(chunk_size)

            data = sock.recv(chunk_size)
            # if not all the expected bytes has been received
            while len(data) < chunk_size:
                data += sock.recv(1)
            f_obj.write(data)
            progress_bar.print_progress_bar(i + 1,
                                            total_chunks,
                                            prefix='Downloading:',
                                            suffix='Complete',
                                            length=50)

        f_obj.close()
Exemplo n.º 12
0
def prompt_host_request(message: str) -> tuple:
    """ Guide the user to manually insert peers in the data structure

	:param message: the message to be printed
	:return: tuple containing the added host
	"""

    while True:
        ip4 = input(f'{message} (IPv4): ')
        if ip4 == 'q':
            break

        try:
            ipaddress.IPv4Address(ip4)
        except ipaddress.AddressValueError:
            shell_colors.print_red(
                f'{ip4} is not a valid IPv4 address, please retry.')
            continue
        break

    while True:
        ip6 = input(f'{message} (IPv6): ')
        try:
            ipaddress.IPv6Address(ip6)
        except ipaddress.AddressValueError:
            shell_colors.print_red(
                f'{ip6} is not a valid IPv6 address, please retry.')
            continue
        break

    while True:
        port = input(f'{message} (port): ')
        try:
            port = int(port)
            if not 1024 < port < 65535:
                shell_colors.print_red(f'{port} must be in range 1025 - 65535')
                continue
        except ValueError:
            shell_colors.print_red(
                f'{port} is not a valid port number, please retry.')
            continue
        break

    return ip4, ip6, port
Exemplo n.º 13
0
def prompt_friend_request() -> tuple:
    """ Guide the user to manually insert peers in the data structure

	:return: None
	"""

    while True:
        ip4 = input('Insert a known peer (IPv4): ')
        if ip4 == 'q':
            break

        try:
            ipaddress.IPv4Address(ip4)
        except ipaddress.AddressValueError:
            shell_colors.print_red(
                f'{ip4} is not a valid IPv4 address, please retry.')
            continue
        break

    while True:
        ip6 = input('Insert a known peer (IPv6): ')
        try:
            ipaddress.IPv6Address(ip6)
        except ipaddress.AddressValueError:
            shell_colors.print_red(
                f'{ip6} is not a valid IPv6 address, please retry.')
            continue
        break

    while True:
        port = input('Insert a known peer (port): ')
        try:
            port = int(port)
            if not 1024 < port < 65535:
                shell_colors.print_red(f'{port} must be in range 1025 - 65535')
                continue
        except ValueError:
            shell_colors.print_red(
                f'{port} is not a valid port number, please retry.')
            continue
        break

    return ip4, ip6, port
Exemplo n.º 14
0
def prompt_neighbours_request() -> None:
	""" Guide the user to manually insert peers in the data structure

	:return: None
	"""

	while True:
		ip4 = input('Insert a known peer (IPv4): ')
		if ip4 == 'q':
			break

		try:
			ipaddress.IPv4Address(ip4)
		except ipaddress.AddressValueError:
			shell_colors.print_red(f'{ip4} is not a valid IPv4 address, please retry.')
			continue
		break

	while True:
		ip6 = input('Insert a known peer (IPv6): ')
		try:
			ipaddress.IPv6Address(ip6)
		except ipaddress.AddressValueError:
			shell_colors.print_red(f'{ip6} is not a valid IPv6 address, please retry.')
			continue
		break

	while True:
		port = input('Insert a known peer (port): ')
		try:
			port = int(port)
			if not 1024 < port < 65535:
				shell_colors.print_red(f'{port} must be in range 1025 - 65535')
				continue
		except ValueError:
			shell_colors.print_red(f'{port} is not a valid port number, please retry.')
			continue
		break

	AppData.add_neighbour(ip4, ip6, port)

	shell_colors.print_green(f'\nSuccessfully added the new peer: {ip4}|{ip6} [{port}]\n')
Exemplo n.º 15
0
    def serve(self, choice: str) -> None:
        """ Handle the peer packet

		:param choice: the choice to handle
		:return: None
		"""

        if choice == "QUER":

            # codice che manda il pkt sulla socket
            pktid = str(uuid.uuid4().hex[:16].upper())
            ip = net_utils.get_local_ip_for_response()
            port = net_utils.get_aque_port()
            ttl = '50'

            while True:
                search = input('\nEnter the file name: ')

                if not 0 <= len(search) <= 20:
                    shell_colors.print_red(
                        '\nFile name must be between 1 and 20 chars long.\n')
                    continue
                break

            packet = choice + pktid + ip + str(port).zfill(
                5) + ttl + search.ljust(20)
            AppData.set_sent_packet(pktid)

            # avvio il server di ricezione delle response, lo faccio prima del broadcast
            # per evitare che i primi client che rispondono non riescano a connettersi
            server = ServerThread(port, SelfHandler())
            server.daemon = True
            server.start()

            spinner = SpinnerThread('Searching files (ENTER to continue)',
                                    'Research done!')
            spinner.start()

            timer = Timer(300, lambda: (spinner.stop(), server.stop()))
            timer.start()

            self.__broadcast(packet)
            input()
            print('\033[1A', end='\r')

            if timer.is_alive():
                spinner.stop()
                spinner.join()
                timer.cancel()
                timer.join()
                server.stop()
                server.join()
            else:
                spinner.join()
                timer.join()
                server.join()

            files = AppData.get_peer_files()

            if len(files) < 1:
                shell_colors.print_red('\nNo matching results.\n')
                return

            # for count, file in enumerate(files, start=1):
            # 	print(f'{count}]', file)

            while True:
                index = input('\nPlease select a file to download: ')
                try:
                    index = int(index)
                    if 1 <= index <= len(files):
                        break
                    else:
                        shell_colors.print_red(
                            f'Index chosen must be in the correct range: 1 - {len(files)}.\n'
                        )
                except ValueError:
                    shell_colors.print_red(
                        f'Your choice must be a valid one: number in range 1 - {len(files)} expected.\n'
                    )

            host_ip4 = AppData.get_file_owner_ip4(files[index - 1])
            host_ip6 = AppData.get_file_owner_ip6(files[index - 1])
            host_port = AppData.get_file_owner_port(files[index - 1])
            file_md5 = AppData.get_file_md5(files[index - 1])
            file_name = AppData.get_file_name(files[index - 1])

            # preparo packet per retr, faccio partire server in attesa download, invio packet e attendo
            packet = 'RETR' + file_md5

            try:
                Downloader(host_ip4, host_ip6, host_port, packet,
                           file_name).start()

                shell_colors.print_green(
                    f'\nDownload of {file_name} completed.\n')
                AppData.clear_peer_files()
                AppData.add_shared_file(file_name, file_md5,
                                        os.stat('shared/' + file_name).st_size)
            except OSError:
                shell_colors.print_red(
                    f'\nError while downloading {file_name}\n')

        elif choice == "NEAR":
            # NEAR[4B].Packet_Id[16B].IP_Peer[55B].Port_Peer[5B].TTL[2B]
            pktid = str(uuid.uuid4().hex[:16].upper())
            ip = net_utils.get_local_ip_for_response()
            port = net_utils.get_anea_port()
            ttl = '03'

            packet = choice + pktid + ip + str(port).zfill(5) + ttl
            AppData.set_sent_packet(pktid)

            old_neighbours_len = len(AppData.get_neighbours())

            # avvio il server di ricezione delle response, lo faccio prima del broadcast
            # per evitare che i primi client che rispondono non riescano a connettersi
            server = ServerThread(port, SelfHandler())
            server.daemon = True
            server.start()

            spinner = SpinnerThread('Searching peers (ENTER to continue)',
                                    'Research done!')
            spinner.start()

            timer = Timer(300, lambda: (spinner.stop(), server.stop()))
            timer.start()

            self.__broadcast(packet)
            input()
            print('\033[1A', end='\r')

            if timer.is_alive():
                spinner.stop()
                spinner.join()
                timer.cancel()
                timer.join()
                server.stop()
                server.join()
            else:
                spinner.join()
                timer.join()
                server.join()

            if len(AppData.get_neighbours()) == old_neighbours_len:
                shell_colors.print_red('\nNo new peer found.\n')

        elif choice == 'ADDPEER':
            net_utils.prompt_neighbours_request()

        elif choice == 'LISTPEERS':
            shell_colors.print_green('\nList of known peers:')
            for count, neighbour in enumerate(AppData.get_neighbours(),
                                              start=1):
                shell_colors.print_blue(
                    f'{count}] {AppData.get_peer_ip4(neighbour)} {AppData.get_peer_ip6(neighbour)} {str(AppData.get_peer_port(neighbour))}'
                )

        elif choice == 'REMOVEPEER':
            neighbours = AppData.get_neighbours()
            shell_colors.print_green('\nList of known peers:')
            for count, neighbour in enumerate(neighbours, start=1):
                shell_colors.print_blue(
                    f'{count}] {AppData.get_peer_ip4(neighbour)} {AppData.get_peer_ip6(neighbour)} {str(AppData.get_peer_port(neighbour))}'
                )

            while True:
                index = input(
                    '\nPlease select a peer to delete (q to cancel): ')
                if index == 'q':
                    break

                try:
                    index = int(index)
                    if 1 <= index <= len(neighbours):
                        AppData.remove_neighbour(index - 1)
                        break
                    else:
                        shell_colors.print_red(
                            f'Index chosen must be in the correct range: 1 - {len(neighbours)}.\n'
                        )
                except ValueError:
                    shell_colors.print_red(
                        f'Your choice must be a valid one: number in range 1 - {len(neighbours)} expected.\n'
                    )

        else:
            pass
Exemplo n.º 16
0
    def serve(self, choice: str) -> None:
        """ Handle the peer packet

		:param choice: the choice to handle
		:return: None
		"""

        if choice == "LISTFILES":
            try:
                conn = database.get_connection(self.db_file)
                conn.row_factory = database.sqlite3.Row

            except database.Error as e:
                print(f'Error: {e}')
                print(
                    'The server has encountered an error while trying to serve the request.'
                )
                return

            try:
                files = file_repository.find_all(conn)

                shell.print_green('\nLogged peers files:')
                if not files:
                    shell.print_red('There are not logged peers files.')

                for count, shared_file in enumerate(files, 1):
                    print(f'{count}] {shared_file["file_name"]} ', end='')
                    shell.print_yellow(f'{shared_file["file_md5"]}\n')

            except database.Error as e:
                conn.rollback()
                conn.close()
                print(f'Error: {e}')
                print(
                    'The server has encountered an error while trying to serve the request.'
                )
                return

        elif choice == "SHOWPARTS":

            try:
                conn = database.get_connection(self.db_file)
                conn.row_factory = database.sqlite3.Row

            except database.Error as e:
                print(f'Error: {e}')
                print(
                    'The server has encountered an error while trying to serve the request.'
                )
                return

            peer_list = peer_repository.find_all(conn)

            if not peer_list:
                shell.print_red('There are no logged peers.')
                conn.close()
                return
            else:
                shell.print_green('\nList of known peers:')
                for count, peer_row in enumerate(peer_list, 1):
                    shell.print_blue(f'{count}]' + peer_row['ip'] +
                                     peer_row['port'] + '\n')

            while True:
                index = input('\nPlease select a peer(q to cancel): ')

                if index == 'q':
                    print('\n')
                    return

                try:
                    index = int(index) - 1
                except ValueError:
                    shell.print_red(
                        f'\nWrong index: number in range 1 - {len(peer_list)} expected.'
                    )
                    continue

                if 0 <= index <= len(peer_list):

                    chosen_peer = peer_list.pop(index)

                    peer_session_id = chosen_peer['session_id']

                    file_rows = file_repository.get_all_peer_files(
                        conn, peer_session_id)

                    if not file_rows:
                        shell.print_red('This peer has no file\'s parts')
                        conn.close()
                        return

                    for count, file_row in enumerate(file_rows, 1):
                        file_name = file_row['file_name']
                        file_md5 = file_row['file_md5']

                        part_list = bytearray(
                            file_repository.get_part_list_by_file_and_owner(
                                conn, file_md5, peer_session_id))

                        print(f'{count}] ', end='')
                        shell.print_blue(f'{file_name}|{file_md5} -> ', end='')

                        for byte_index in range(len(part_list)):
                            print(
                                f'{bin(part_list[byte_index])[2:].zfill(8)} ',
                                end='')
                        print('')
                    return ()
                else:
                    shell.print_red(
                        f'\nWrong index: number in range 1 - {len(peer_list)} expected.'
                    )
                    continue

        elif choice == "LISTPEERS":
            try:
                conn = database.get_connection(self.db_file)
                conn.row_factory = database.sqlite3.Row

            except database.Error as e:
                print(f'Error: {e}')
                print(
                    'The server has encountered an error while trying to serve the request.'
                )
                return

            try:
                peer_list = peer_repository.find_all(conn)

                if not peer_list:
                    shell.print_red('There are not logged peers.')
                    conn.close()
                    return

                else:
                    shell.print_green('\nList of known peers:')
                    for count, peer_row in enumerate(peer_list, 1):
                        shell.print_blue(f'{count}]' + peer_row['ip'] +
                                         peer_row['port'] + '\n')

            except database.Error as e:
                conn.rollback()
                conn.close()
                print(f'Error: {e}')
                print(
                    'The server has encountered an error while trying to serve the request.'
                )
                return

        else:
            pass
	def serve(self, sd: socket.socket) -> None:
		""" Handle the peer request

		:param sd: the socket descriptor used for read the request
		:return None
		"""

		try:
			response = sd.recv(300).decode()
		except socket.error as e:
			shell.print_red(f'Unable to read the response from the socket: {e}\n')
			sd.close()
			return
		sd.close()

		command = response[0:4]

		if command == "AQUE":

			if len(response) != 212:
				shell.print_red(f"Invalid response: : {command} -> {response}. Expected: AQUE<pkt_id><ip_peer><port_peer><file_md5><filename>")
				return

			pktid = response[4:20]
			ip_peer = response[20:75]
			ip4_peer, ip6_peer = net_utils.get_ip_pair(ip_peer)
			port_peer = int(response[75:80])
			file_md5 = response[80:112]
			filename = response[112:212].lstrip().rstrip()

			if pktid != LocalData.get_sent_menu_quer_packet():
				return

			if not LocalData.exist_menu_peer_file(ip4_peer, ip6_peer, port_peer, file_md5, filename):
				LocalData.add_menu_peer_file(ip4_peer, ip6_peer, port_peer, file_md5, filename)
				index = LocalData.menu_peer_file_index(ip4_peer, ip6_peer, port_peer, file_md5, filename)
				print(f'{index +1}] ', end='')
				print(f'{filename} ', end='')
				shell.print_yellow(f'md5={file_md5} ', end='')
				print(f'({ip4_peer}|{ip6_peer} [{port_peer}])')

		elif command == "ASUP":

			if len(response) != 80:
				shell.print_red(f"Invalid response: : {command} -> {response}. Expected: ASUP<pkt_id><ip_peer><port_peer>")
				return

			pktid = response[4:20]
			ip_peer = response[20:75]
			ip4_peer, ip6_peer = net_utils.get_ip_pair(ip_peer)
			port_peer = int(response[75:80])

			if pktid != LocalData.get_sent_supe_packet():
				return

			if not LocalData.is_super_friend(ip4_peer, ip6_peer, port_peer):
				LocalData.add_super_friend(ip4_peer, ip6_peer, port_peer)
				shell.print_green('New superfriend found: ', end='')
				print(f'{ip4_peer}|{ip6_peer} [{port_peer}]')

		else:
			shell.print_red(f"\nInvalid response: {command} -> {response}\n")

		return
Exemplo n.º 18
0
    shell.print_blue('           ')
    shell.print_blue('    /  \  | | __ _', end='')
    shell.print_yellow('| \' / __ _ ______ _  __ _', end='')
    shell.print_blue(' _ __ ___ ')
    shell.print_blue('   / /\ \ | |/ _` ', end='')
    shell.print_yellow('|  < / _` |_  / _` |/ _` |', end='')
    shell.print_blue(' \'_ ` _ \ ')
    shell.print_blue('  / ____ \| | (_| ', end='')
    shell.print_yellow('| . \ (_| |/ / (_| | (_| |', end='')
    shell.print_blue(' | | | | | ')
    shell.print_blue(' /_/    \_\_|\__,_', end='')
    shell.print_yellow('|_|\_\__,_/___\__,_|\__,_|', end='')
    shell.print_blue('_| |_| |_| ')

    if not os.path.exists('shared'):
        os.mkdir('shared')

    net_utils.prompt_parameters_request()

    choice = ''
    while choice != 'q':
        choice = input('Are you a super peer? (y/n): ')
        if choice == 'y':
            superpeer.startup()
            break
        elif choice == 'n':
            peer.startup()
            break
        else:
            shell.print_red('Input code is wrong. Choose y or n!\n')
Exemplo n.º 19
0
	def run(self) -> None:
		""" Start file download

		:return: None
		"""

		try:
			packet = 'RETP' + self.file_md5 + str(self.part_num).zfill(8)

			sock = self.__connect(self.owner_ip4, self.owner_ip6, self.owner_port, packet)
		except socket.error as e:
			shell_colors.print_red(f'\nImpossible to send data to {self.owner_ip4}|{self.owner_ip6} [{self.owner_port}]: {e}\n')
			return

		ack = sock.recv(4).decode()
		if ack != "AREP":
			shell_colors.print_red(f'Invalid command received: {ack}. Expected: AREP')
			sock.close()
			return

		try:
			total_chunks = int(sock.recv(6).decode())
		except ValueError:
			shell_colors.print_red('Impossible to retrieve the part. Trying later.')
			return

		for i in range(total_chunks):
			chunk_size = sock.recv(5)
			# if not all the 5 expected bytes has been received
			while len(chunk_size) < 5:
				chunk_size += sock.recv(1)
			chunk_size = int(chunk_size)

			data = sock.recv(chunk_size)
			# if not all the expected bytes has been received
			while len(data) < chunk_size:
				data += sock.recv(1)
			self.f_obj.write(data)

		self.f_obj.close()

		try:
			packet = 'RPAD' + LocalData.session_id + self.file_md5 + str(self.part_num).zfill(8)

			sock = self.__connect(LocalData.get_tracker_ip4(), LocalData.get_tracker_ip6(), LocalData.get_tracker_port(), packet)
		except socket.error as e:
			shell_colors.print_red(f'\nImpossible to send data to {self.owner_ip4}|{self.owner_ip6} [{self.owner_port}]: {e}\n')
			return

		ack = sock.recv(4).decode()
		if ack != "APAD":
			shell_colors.print_red(f'\nInvalid command received: {ack}. Expected: APAD\n')
			sock.close()
			return

		try:
			num_parts_owned = int(sock.recv(8).decode())
		except ValueError:
			shell_colors.print_red('Error while retrieving the parts owned from the tracker.')
			return

		binary_utils.update_owned_parts(self.part_num)
		LocalData.set_num_parts_owned(num_parts_owned)
		progress_bar.print_progress_bar(num_parts_owned, self.total_file_parts, prefix='Downloading:', suffix='Complete', length=50)
Exemplo n.º 20
0
	def serve(self, choice: str) -> None:
		""" Handle the peer packet

		:param choice: the choice to handle
		:return: None
		"""

		if choice == "SUPE":
			# SUPE[4B].Packet_Id[16B].IP_Peer[55B].Port_Peer[5B].TTL[2B]
			pktid = str(uuid.uuid4().hex[:16].upper())
			ip = net_utils.get_local_ip_for_response()
			port = net_utils.get_asup_port()
			ttl = '04'

			packet = choice + pktid + ip + str(port).zfill(5) + ttl
			LocalData.set_sent_supe_packet(pktid)

			old_superfriends_len = len(LocalData.get_super_friends())

			server = ServerThread(port, MenuTimedResponseHandler())
			server.daemon = True
			server.start()

			spinner = SpinnerThread('Searching superpeers (ENTER to continue)', 'Research done! (ENTER to continue)')
			spinner.start()

			timer = Timer(20, lambda: (spinner.stop(), server.stop()))
			timer.start()

			self.__broadcast(packet)
			input()
			print('\033[1A', end='\r')

			if timer.is_alive():
				spinner.stop()
				spinner.join()
				timer.cancel()
				timer.join()
				server.stop()
				server.join()
			else:
				spinner.join()
				timer.join()
				server.join()

			if len(LocalData.get_super_friends()) == old_superfriends_len:
				shell.print_yellow('\nNo new superpeer found.\n')

		elif choice == "ADFF":

			if not os.path.exists('shared'):
				shell.print_red('\nCannot find the shared folder.')
				return

			dir_file = list()

			if not os.scandir('shared'):
				shell.print_yellow('\nNo file in the shared folder.')
				return

			for count, dir_entry in enumerate(os.scandir('shared'), 1):
				dir_file.append((dir_entry.name, hasher.get_md5(dir_entry.path), dir_entry.stat().st_size))
				print(f'\n{count}) {dir_entry.name}', end='')
				shell.print_yellow(f' {hasher.get_md5(dir_entry.path)}', end='')
				print(f' size: {dir_entry.stat().st_size}')

			while True:

				index = input('\nPlease select a file to share(pres q to exit): ')

				if index == 'q':
					print('\n')
					return

				try:
					index = int(index) - 1
				except ValueError:
					shell.print_red(f'\nWrong index: number in range 1 - {count} expected.')
					continue

				if 0 <= index <= count - 1:
					chosen_file = dir_file.pop(index)

					filename = LocalData.get_shared_filename(chosen_file)
					filemd5 = LocalData.get_shared_filemd5(chosen_file)
					filedim = LocalData.get_shared_dim(chosen_file)

					if not LocalData.exist_shared_file(filename, filemd5, filedim):
						LocalData.add_shared_file(filename, filemd5, filedim)
						shell.print_green('\nThe file is now shared.')
					else:
						shell.print_yellow('\nThe file is already shared.')

					break
				else:
					shell.print_red(f'\nWrong index: number in range 1 - {count} expected.')
				continue

		elif choice == "DEFF":

			if not LocalData.get_shared_files():
				shell.print_yellow('\nNo file in sharing.')
				return

			for count, file in enumerate(LocalData.get_shared_files(), 1):
				print(f'\n{count}) {LocalData.get_shared_filename(file)}', end='')
				shell.print_yellow(f' {LocalData.get_shared_filemd5(file)}', end='')
				print(f' size: {LocalData.get_shared_dim(file)}')

			while True:

				index = input('\nPlease select a file to delete from sharing(pres q to exit): ')

				if index == 'q':
					print('\n')
					return

				try:
					index = int(index) - 1
				except ValueError:
					shell.print_red(f'\nWrong index: number in range 1 - {count} expected.')
					continue

				if 0 <= index <= count - 1:

					deleted_file = LocalData.get_shared_file_by_index(index)

					shell.print_blue(f'\n{LocalData.get_shared_filename(deleted_file)}', end='')
					shell.print_yellow(f' {LocalData.get_shared_filemd5(deleted_file)}', end='')
					shell.print_blue(' removed from sharing.')

					break
				else:
					shell.print_red(f'\nWrong index: number in range 1 - {count} expected.')
				continue

		elif choice == "QUER":

			while True:
				search = input('\nEnter the file name: ')

				if search != '*':
					search = '%' + search + '%'

				if not 0 < len(search) <= 20:
					shell.print_red('\nFile name must be between 1 and 20 chars long.\n')
					continue

				break

			# Read matching files from DB
			try:
				conn = database.get_connection(db_file)
				conn.row_factory = database.sqlite3.Row

			except database.Error as e:
				shell.print_red(f'\nError while getting connection from database: {e}')
				return

			try:
				total_db_file = file_repository.get_files_count_by_querystring(conn, search)

				if total_db_file == 0:
					shell.print_yellow('\nNo matching results from your peers.\n')

				else:
					shell.print_green('\nFiles from your logged peers:\n')
					file_rows = file_repository.get_files_by_querystring(conn, search)

					# print('\nFile from peers: ')

					for file_row in file_rows:
						file_md5 = file_row['file_md5']
						file_name = file_row['file_name']

						owner_rows = peer_repository.get_peers_by_file(conn, file_md5)

						for owner_row in owner_rows:
							owner_ip = owner_row['ip']
							owner_port = int(owner_row['port'])

							ip4_peer, ip6_peer = net_utils.get_ip_pair(owner_ip)
							# stampa di debug
							# print(f'\n{LocalData.menu_peer_file_index(ip4_peer, ip6_peer, peer.port, file.file_md5, file.file_name)}', end='')
							# shell.print_yellow(f' {file.file_md5}', end='')
							# print(f' {file.file_name} from {ip4_peer|ip6_peer} on port {peer.port}')
							LocalData.add_menu_peer_file(ip4_peer, ip6_peer, owner_port, file_md5, file_name)
							index = LocalData.menu_peer_file_index(ip4_peer, ip6_peer, owner_port, file_md5, file_name)
							print(f'{index +1}] ', end='')
							print(f'{file_name} ', end='')
							shell.print_yellow(f'md5={file_md5} ', end='')
							print(f'({ip4_peer}|{ip6_peer} [{owner_port}])')

				conn.commit()
				conn.close()

			except database.Error as e:
				conn.rollback()
				conn.close()
				LocalData.clear_menu_peer_files()
				shell.print_red(f'\nError while retrieving data from database: {e}')

			# Send a search for a file on the superpeer network
			shell.print_green('\nFiles from the network:\n')

			pktid = str(uuid.uuid4().hex[:16].upper())
			ip = net_utils.get_local_ip_for_response()
			port = net_utils.get_aque_port()
			ttl = '05'

			packet = choice + pktid + ip + str(port).zfill(5) + ttl + search.ljust(20)
			LocalData.set_sent_menu_quer_packet(pktid)

			server = ServerThread(port, MenuTimedResponseHandler())
			server.daemon = True
			server.start()

			spinner = SpinnerThread('Searching files (ENTER to continue)', 'Research done! (ENTER to continue)')
			spinner.start()

			timer = Timer(20, lambda: (spinner.stop(), server.stop()))
			timer.start()

			self.__broadcast(packet)
			input()
			print('\033[1A', end='\r')

			if timer.is_alive():
				spinner.stop()
				spinner.join()
				timer.cancel()
				timer.join()
				server.stop()
				server.join()
			else:
				spinner.join()
				timer.join()
				server.join()

			# Retrieving the list of database's files and superpeer network's files
			peer_files = LocalData.get_menu_peer_files()

			if len(peer_files) == total_db_file:
				shell.print_yellow('\nNo matching results from the superpeer network.\n')

			if len(peer_files) < 1:
				shell.print_yellow('\nNo file matching the keyword.\n')
				return

			while True:
				index = input('\nPlease select a file to download: ')

				if index == 'q':
					print('\n')
					LocalData.clear_menu_peer_files()
					return

				try:
					index = int(index) - 1
				except ValueError:
					shell.print_red(f'\nWrong index: number in range 1 - {len(peer_files)} expected.')
					continue

				if 0 <= index <= len(peer_files):

					chosen_peer_file = LocalData.get_menu_peer_file_by_index(index)

					host_ip4 = LocalData.get_menu_file_owner_ip4(chosen_peer_file)
					host_ip6 = LocalData.get_menu_file_owner_ip6(chosen_peer_file)
					host_port = LocalData.get_menu_file_owner_port(chosen_peer_file)
					file_md5 = LocalData.get_menu_file_md5(chosen_peer_file)
					file_name = LocalData.get_menu_file_name(chosen_peer_file)

					# preparo packet per retr, faccio partire server in attesa download, invio packet e attendo
					packet = 'RETR' + file_md5

					try:
						Downloader(host_ip4, host_ip6, host_port, packet, file_name).start()

						shell.print_green(f'\nDownload of {file_name} completed.\n')
						LocalData.clear_menu_peer_files()
					except OSError:
						shell.print_red(f'\nError while downloading {file_name}\n')

					break
				else:
					shell.print_red(f'\nWrong index: number in range 1 - {len(peer_files)} expected.')
					continue

		elif choice == "LISTSUPERPEERS":

			shell.print_green('\nList of known superpeers:')

			if not LocalData.get_super_friends():
				shell.print_red('You do not know any superpeers.')
			else:
				for count, friend in enumerate(LocalData.get_super_friends(), 1):
					friend_ip4 = LocalData.get_super_friend_ip4(friend)
					friend_ip6 = LocalData.get_super_friend_ip6(friend)
					friend_port = LocalData.get_super_friend_port(friend)
					shell.print_blue(f'{count}] {friend_ip4} {friend_ip6} {str(friend_port)}')

		elif choice == "LISTPEERS":

			try:
				conn = database.get_connection(db_file)
				conn.row_factory = database.sqlite3.Row

			except database.Error as e:
				print(f'Error: {e}')
				print('The server has encountered an error while trying to serve the request.')
				return

			try:
				peer_list = peer_repository.find_all(conn)

				if not peer_list:
					shell.print_red('You do not know any peers.')
					conn.close()
					return

				else:
					shell.print_green('\nList of known peers:')
					for count, peer_row in enumerate(peer_list, 1):
						shell.print_blue(f'{count}]' + peer_row['ip'] + peer_row['port'] + '\n')

			except database.Error as e:
				conn.rollback()
				conn.close()
				print(f'Error: {e}')
				print('The server has encountered an error while trying to serve the request.')
				return

		elif choice == "LISTFILES":
			try:
				conn = database.get_connection(db_file)
				conn.row_factory = database.sqlite3.Row

			except database.Error as e:
				print(f'Error: {e}')
				print('The server has encountered an error while trying to serve the request.')
				return

			try:
				files = file_repository.find_all(conn)

				shell.print_green('\nYour shared files:')
				if not LocalData.get_shared_files():
					shell.print_red('You do not have shared files.')

				for count, shared_file in enumerate(LocalData.get_shared_files(), 1):
					print(f'{count}] {LocalData.get_shared_filename(shared_file)} ', end='')
					shell.print_yellow(f'{LocalData.get_shared_filemd5(shared_file)}\n')

				shell.print_green('\nLogged peers files:')
				if not files:
					shell.print_red('You do not have logged peers files.')
					conn.close()
					return

				for count, file_row in enumerate(files, 1):
					print(f'{count}] {file_row["file_name"]} ', end='')
					shell.print_yellow(f'{file_row["file_md5"]}')

			except database.Error as e:
				conn.rollback()
				conn.close()
				print(f'Error: {e}')
				print('The server has encountered an error while trying to serve the request.')
				return

		else:
			pass
Exemplo n.º 21
0
def startup():

    while True:
        # verifico se ho superpeer e file in sharing nel json (ossia se il peer è crashato)
        if LocalData.superpeer_is_empty():
            while True:
                shell.print_blue(
                    '\nThis process will allow you to add your known peer.\n')
                superpeer = net_utils.prompt_friend_request()
                LocalData.set_superpeer(superpeer)

                # 1) Lancia una SUPE al nodo conosciuto
                pktid = str(uuid.uuid4().hex[:16].upper())
                ip = net_utils.get_local_ip_for_response()
                port = str(net_utils.get_network_port()).zfill(5)
                ttl = '04'
                packet = 'SUPE' + pktid + ip + port + ttl

                super_ip4 = LocalData.get_superpeer_ip4()
                super_ip6 = LocalData.get_superpeer_ip6()
                super_port = LocalData.get_superpeer_port()

                LocalData.set_sent_packet(pktid)

                server = ServerThread(
                    net_utils.get_network_port(),
                    TimedResponseHandler.TimedResponseHandler())
                server.start()

                spinner = SpinnerThread('Trying to login', '')
                spinner.start()

                try:
                    net_utils.send_packet_and_close(super_ip4, super_ip6,
                                                    super_port, packet)
                except socket.error as e:
                    shell.print_red(
                        f'There was an error in the login process: {e}')
                    continue

                # 2) Attende ASUP per 20 sec
                timer = Timer(20, lambda: (server.stop(), spinner.stop()))
                timer.start()

                timer.join()
                spinner.join()

                # 3) Se non è possibile agganciarsi ad un super, devo far reinserire il peer all'utente
                if len(LocalData.get_superpeer_candidates()) == 0:
                    shell.print_red(
                        'Cannot contact a superpeer from the peer you provide, please retry.'
                    )
                    continue

                # 3) Se il peer aggiunto era veramente un superpeer, allora non lo cambio
                elif LocalData.get_superpeer(
                ) in LocalData.get_superpeer_candidates():
                    break

                # 3) Se invece era un superpeer falso, pesco un super a random dalla lista dei candidati
                else:
                    index = random.randint(
                        0,
                        len(LocalData.get_superpeer_candidates()) - 1)
                    superpeer = LocalData.get_superpeer_candidate_by_index(
                        index)
                    LocalData.set_superpeer(superpeer)
                    break

        # Lancio una LOGI al superpeer scelto
        ip = net_utils.get_local_ip_for_response()
        port = str(net_utils.get_network_port()).zfill(5)
        packet = "LOGI" + ip + port

        super_ip4 = LocalData.get_superpeer_ip4()
        super_ip6 = LocalData.get_superpeer_ip6()
        super_port = LocalData.get_superpeer_port()

        try:
            sock = net_utils.send_packet(super_ip4, super_ip6, super_port,
                                         packet)
            response = sock.recv(100).decode()

            if len(response) != 20:
                shell.print_red(
                    f'There was an error in the login process: unexpected: {response}.\nPlease retry.'
                )
                LocalData.clear_backup_data()
                continue

            session_id = response[4:20]

            if session_id == '0' * 16:
                shell.print_red(
                    f'There was an error in the login process: unexpected session_id: {session_id}.\nPlease retry.'
                )
                LocalData.clear_backup_data()
                continue

            LocalData.session_id = response[4:20]
            break
        except (socket.error, AttributeError):
            shell.print_yellow(
                f'Unable to contact {super_ip4}|{super_ip6} [{super_port}]')
            # pulisco il file json da file in sharing e superpeer vecchio
            LocalData.clear_backup_data()
            if sock is not None:
                sock.close()
            continue

    shell.print_green(
        f'Successfully logged to the superpeer: {super_ip4}|{super_ip6} [{super_port}]\n'
    )

    log = Logger.Logger('peer/peer.log')

    server = ServerThread(net_utils.get_network_port(),
                          NetworkHandler.NetworkHandler(log))
    server.daemon = True
    server.start()

    Menu(MenuHandler.MenuHandler()).show()
Exemplo n.º 22
0
#!/usr/bin/env python

from service.ServerThread import ServerThread
from service.Menu import Menu
from handler.NeighboursHandler import NeighboursHandler
from handler.MenuHandler import MenuHandler
from utils import shell_colors as shell
import os
from utils import net_utils, Logger, hasher
from service.AppData import AppData

if __name__ == '__main__':

    shell.print_red(' ____   ___   ___  _   ', end='')
    shell.print_yellow('    _ _       ')
    shell.print_red('|  _ \ / _ \ / _ \| |_ ', end='')
    shell.print_yellow('___| | | __ _ ')
    shell.print_red('| |_) | | | | | | | __/', end='')
    shell.print_yellow(' _ \ | |/ _` |')
    shell.print_red('|  _ <| |_| | |_| | |', end='')
    shell.print_yellow('|  __/ | | (_| |')
    shell.print_red('|_| \__\\___/ \___/ \__', end='')
    shell.print_yellow('\___|_|_|\__,_|')

    if not os.path.exists('shared'):
        os.mkdir('shared')

    for dir_entry in os.scandir('shared'):
        AppData.add_shared_file(dir_entry.name, hasher.get_md5(dir_entry.path),
                                dir_entry.stat().st_size)
Exemplo n.º 23
0
	def serve(self, sd: socket.socket) -> None:
		""" Handle a network packet

		:param sd: the socket descriptor used for read the packet
		:return: None
		"""

		try:
			packet = sd.recv(200).decode()
		except socket.error as e:
			self.log.write_red(f'Unable to read the packet from the socket: {e}')
			sd.close()
			return

		# log the packet received
		socket_ip_sender = sd.getpeername()[0]

		if ipaddress.IPv6Address(socket_ip_sender).ipv4_mapped is None:
			socket_ip_sender = ipaddress.IPv6Address(socket_ip_sender).compressed
		else:
			socket_ip_sender = ipaddress.IPv6Address(socket_ip_sender).ipv4_mapped.compressed

		socket_port_sender = sd.getpeername()[1]

		self.log.write_green(f'{socket_ip_sender} [{socket_port_sender}] -> ', end='')
		self.log.write(f'{packet}')

		command = packet[:4]

		if command == "RETP":

			if len(packet) != 44:
				self.log.write_red(f'Invalid packet received: {packet}')
				return

			file_md5 = packet[4:36]

			try:
				num_part = int(packet[36:44])
			except ValueError:
				shell.print_red(f'Invalid packet received: Part-Num must be an integer -> {num_part}\n')
				return

			file_name = LocalData.get_shared_file_name_from_md5(file_md5)

			if file_name is None:
				error_packet = 'Sorry, the requested file is not available anymore.'
				self.send_packet(sd, socket_ip_sender, socket_port_sender, error_packet)
				sd.close()
				return

			try:
				f_obj = open('shared/' + file_name, 'rb')
			except OSError as e:
				self.log.write_red(f'Cannot open the file to upload: {e}')
				error_packet = 'Sorry, the peer encountered a problem while uploading the file.'
				self.send_packet(sd, socket_ip_sender, socket_port_sender, error_packet)
				sd.close()
				return

			try:
				Uploader(sd, f_obj, num_part, self.log).start()
				self.log.write_blue(f'Sent {socket_ip_sender} [{socket_port_sender}] -> ', end='')
				self.log.write(f'{file_name}')
				sd.close()

			except OSError as e:
				self.log.write_red(f'Error while sending the file: {e}')
				sd.close()
				return

		else:
			sd.close()
			self.log.write_red(f'Invalid packet received from {socket_ip_sender} [{socket_port_sender}]: ', end='')
			self.log.write(f'{packet}')
		return
Exemplo n.º 24
0
    def serve(self, sd: socket.socket) -> None:
        """ Handle the peer request

		:param sd: the socket descriptor used for read the request
		:return None
		"""
        try:
            command = sd.recv(4).decode()
        except OSError as e:
            shell_colors.print_red(
                f'\nUnable to read the command from the socket: {e}\n')
            sd.close()
            return

        if command == "AQUE":
            try:
                response = sd.recv(300).decode()
            except socket.error as e:
                shell_colors.print_red(
                    f'\nUnable to read the {command} response from the socket: {e}\n'
                )
                sd.close()
                return

            sd.close()

            if len(response) != 208:
                print(
                    f"\nInvalid response: {command} -> {response}. Expected: AQUE<pkt_id><ip_peer><port_peer><fileMD5><filename>\n"
                )
                return

            pktid = response[0:16]
            ip_peer = response[16:71]
            ip4_peer, ip6_peer = net_utils.get_ip_pair(ip_peer)
            port_peer = int(response[71:76])
            filemd5 = response[76:108]
            filename = response[108:208].lower().lstrip().rstrip()

            if pktid != AppData.get_sent_packet():
                sd.close()
                return

            if not AppData.exist_peer_files(ip4_peer, ip6_peer, port_peer,
                                            filemd5, filename):
                AppData.add_peer_files(ip4_peer, ip6_peer, port_peer, filemd5,
                                       filename)
                index = AppData.peer_file_index(ip4_peer, ip6_peer, port_peer,
                                                filemd5, filename)
                print(f'{index +1}] ', end='')
                shell_colors.print_blue(f'{filename} ', end='')
                shell_colors.print_yellow(f'md5={filemd5} ', end='')
                print(f'({ip4_peer}|{ip6_peer} [{port_peer}])')

        elif command == "ANEA":
            try:
                response = sd.recv(300).decode()
            except socket.error as e:
                shell_colors.print_red(
                    f'\nUnable to read the {command} response from the socket: {e}\n'
                )
                sd.close()
                return

            sd.close()

            if len(response) != 76:
                shell_colors.print_red(
                    f"\nInvalid response: : {command} -> {response}. Expected: ANEA<pkt_id><ip_peer><port_peer>"
                )
                return

            pktid = response[0:16]
            ip_peer = response[16:71]
            ip4_peer, ip6_peer = net_utils.get_ip_pair(ip_peer)
            port_peer = int(response[71:76])

            if pktid != AppData.get_sent_packet():
                return

            if len(AppData.get_neighbours()) >= 5:
                return

            if not AppData.is_neighbour(ip4_peer, ip6_peer, port_peer):
                AppData.add_neighbour(ip4_peer, ip6_peer, port_peer)
                shell_colors.print_green('New neighbour found: ', end='')
                print(f'{ip4_peer}|{ip6_peer} [{port_peer}]')

        else:
            wrong_response = sd.recv(300).decode()
            sd.close()
            shell_colors.print_red(
                f"\nInvalid response: {command} -> {wrong_response}\n")

        return
Exemplo n.º 25
0
    def serve(choice: str) -> None:
        """ Handle the peer packet

		:param choice: the choice to handle
		:return: None
		"""

        tracker_ip4 = LocalData.get_tracker_ip4()
        tracker_ip6 = LocalData.get_tracker_ip6()
        tracker_port = LocalData.get_tracker_port()
        ssid = LocalData.get_session_id()
        log = Logger.Logger('peer/peer.log')

        if choice == "LOOK":
            # Search a file
            while True:
                search = input('\nInsert file\'s name (q to cancel): ')

                if search == "q":
                    print('\n')
                    return

                if not 0 < len(search) <= 20:
                    shell.print_red(
                        '\nQuery string must be a valid value (1 - 20 chars).')
                    continue

                break

            packet = choice + ssid + search.ljust(20)

            sd = None
            try:
                sd = net_utils.send_packet(tracker_ip4, tracker_ip6,
                                           tracker_port, packet)
            except net_utils.socket.error as e:
                shell.print_red(
                    f'\nError while sending the request to the tracker: {tracker_ip4}|{tracker_ip6} [{tracker_port}].'
                )
                shell.print_red(f'Error: {e}')
                if sd is not None:
                    sd.close()
                return

            # Receiving the response list
            try:
                command = sd.recv(4).decode()
            except net_utils.socket.error as e:
                shell.print_red(
                    f'Unable to read the command from the socket: {e}\n')
                sd.close()
                return

            if command != 'ALOO':
                shell.print_red(
                    f'\nReceived a packet with a wrong command ({command}).')
                return

            try:
                num_files = int(sd.recv(3).decode())
            except net_utils.socket.error as e:
                shell.print_red(
                    f'Unable to read the command from the socket: {e}\n')
                sd.close()
                return

            if num_files == 0:
                shell.print_yellow(f'{search} not found.\n')
                sd.close()
                return

            downloadables = list()

            for i in range(num_files):
                try:
                    file_md5 = sd.recv(32).decode()
                    file_name = sd.recv(100).decode().lstrip().rstrip()
                    len_file = int(sd.recv(10))
                    len_part = int(sd.recv(6))
                except net_utils.socket.error as e:
                    shell.print_red(
                        f'\nError while receiving the response from the tracker: {e}\n'
                    )
                    continue
                except ValueError:
                    shell.print_red(f'\nInvalid packet from tracker: {e}\n')
                    continue

                downloadables.append((file_md5, file_name, len_file, len_part))

            sd.close()

            if not downloadables:
                shell.print_red(
                    f'\nSomething went wrong while retrieving {search}\n')
                return

            shell.print_green(f'\nFiles found:')
            for count, downloadable in enumerate(downloadables, 1):
                print(
                    f'{count}] {LocalData.get_downloadable_file_name(downloadable)} | ',
                    end='')
                shell.print_yellow(
                    f'{LocalData.get_downloadable_file_md5(downloadable)}')

            # Download choice
            while True:
                file_index = input(
                    '\nChoose a file to download (q to cancel): ')

                if file_index == "q":
                    return

                try:
                    file_index = int(file_index) - 1
                except ValueError:
                    shell.print_red(
                        f'\nWrong index: number in range 1 - {len(downloadables)} expected\n'
                    )
                    continue

                if not 0 <= file_index <= len(downloadables) - 1:
                    shell.print_red(
                        f'\nWrong index: number in range 1 - {len(downloadables)} expected\n'
                    )
                    continue
                else:
                    choosed_file_md5 = LocalData.get_downloadable_file_md5(
                        downloadables[file_index])
                    choosed_file_name = LocalData.get_downloadable_file_name(
                        downloadables[file_index])
                    if LocalData.is_shared_file(choosed_file_md5,
                                                choosed_file_name):
                        shell.print_green(
                            f'\nYou already have downloaded {choosed_file_name}.'
                        )
                        continue
                    choosed_file_lenght = LocalData.get_downloadable_file_length(
                        downloadables[file_index])
                    choosed_file_part_lenght = LocalData.get_downloadable_file_part_length(
                        downloadables[file_index])
                    break

            choosed_file_parts = int(
                math.ceil(choosed_file_lenght / choosed_file_part_lenght))
            choosed_file_part_list_length = int(
                math.ceil(choosed_file_parts / 8))

            # Download phase
            LocalData.create_downloading_part_list(
                choosed_file_part_list_length)

            # 1) Initiating the thread responsible for update of the part_list_table in background
            update_event = Event()
            updater_thread = UpdaterThread.UpdaterThread(
                choosed_file_md5, choosed_file_part_list_length, update_event,
                log)
            updater_thread.start()

            # 2) Create the new file
            f_obj = open(f'shared/{choosed_file_name}', 'wb')
            f_obj.close()
            LocalData.set_num_parts_owned(0)
            progress_bar.print_progress_bar(0,
                                            choosed_file_parts,
                                            prefix='Downloading:',
                                            suffix='Complete',
                                            length=50)
            # Adding the file to the shared file list
            LocalData.add_shared_file(choosed_file_md5, choosed_file_name)

            # Until all the parts hasn't been downloaded
            while choosed_file_parts != LocalData.get_num_parts_owned():
                update_event.wait(70)
                update_event.clear()
                # We can use a with statement to ensure threads are cleaned up promptly
                with ThreadPoolExecutor(max_workers=10) as executor:
                    # Get the file parts we don't have yet
                    downloadable_parts = LocalData.get_downloadable_parts()
                    for part_num in downloadable_parts:
                        try:
                            # Start the load operations
                            executor.submit(download_task.run,
                                            choosed_file_md5,
                                            choosed_file_name, part_num,
                                            choosed_file_part_lenght,
                                            choosed_file_parts, log)
                        except OSError as e:
                            log.write_red(
                                f'\nError while downloading {choosed_file_name}: {e}'
                            )
                    executor.shutdown()

            updater_thread.stop()
            shell.print_green('\nDownload completed.')

        elif choice == "ADDR":
            # check if shared directory exist
            if not os.path.exists('shared'):
                shell.print_red('\nCannot find the shared folder.')
                return

            # check for file available in shared directory
            if not os.listdir('shared'):
                shell.print_yellow(
                    'No file available for sharing.\nAdd files to shared dir to get started.\n'
                )
                return

            temp_files = []
            shell.print_blue('\nFiles available for sharing:')
            for count, file in enumerate(os.scandir('shared'), 1):
                # print scandir results
                file_md5 = hasher.get_md5(f'shared/{file.name}')
                print(f'{count}] {file.name} | {file_md5}')
                temp_files.append((file_md5, file.name))

            while True:
                file_index = input('\nChoose a file to share (q to cancel): ')

                if file_index == "q":
                    return

                try:
                    file_index = int(file_index) - 1
                except ValueError:
                    shell.print_red(
                        f'\nWrong index: number in range 1 - {len(temp_files)} expected\n'
                    )
                    continue

                if 0 <= file_index <= len(temp_files) - 1:
                    file_name = LocalData.get_shared_file_name(
                        temp_files[file_index])
                    file_md5 = LocalData.get_shared_file_md5(
                        temp_files[file_index])

                    # check if file is already in sharing
                    if not LocalData.is_shared_file(file_md5, file_name):

                        try:
                            f_obj = open('shared/' + file_name, 'rb')
                        except OSError as e:
                            shell.print_red(
                                f'Cannot open the file to upload: {e}')
                            return

                        try:
                            filesize = str(os.fstat(f_obj.fileno()).st_size)
                        except OSError as e:
                            shell.print_red(f'Something went wrong: {e}')
                            return
                        except ValueError as e:
                            shell.print_red(
                                f'\nUnable to convert filesize in string: {e}\n'
                            )
                            return

                        part_size = str(net_utils.get_part_size())

                        # build packet and sent to tracker
                        packet = choice + ssid + filesize.zfill(
                            10) + part_size.zfill(6) + file_name.ljust(
                                100) + file_md5

                        sd = None
                        try:
                            sd = net_utils.send_packet(tracker_ip4,
                                                       tracker_ip6,
                                                       tracker_port, packet)
                        except net_utils.socket.error as e:
                            shell.print_red(
                                f'\nError while sending the request to the tracker: {tracker_ip4}|{tracker_ip6} [{tracker_port}].'
                            )
                            shell.print_red(f'Error: {e}')
                            if sd is not None:
                                sd.close()
                            return

                        try:
                            response = sd.recv(200).decode()
                        except net_utils.socket.error as e:
                            shell.print_red(
                                f'Unable to read the response from the socket: {e}\n'
                            )
                            sd.close()
                            return
                        sd.close()

                        if len(response) != 12:
                            shell.print_red(
                                f"Invalid response: : {response}. Expected: AADR<num_part>"
                            )
                            return

                        command = response[0:4]

                        if command != 'AADR':
                            shell.print_red(
                                f'\nReceived a packet with a wrong command ({command}).'
                            )
                            return

                        num_part = response[4:12]

                        # add file to shared_files
                        LocalData.add_shared_file(file_md5, file_name)
                        shell.print_blue(
                            f'\nNew shared file added {file_name} | {file_md5}',
                            end='')
                        shell.print_green(f' #parts: {num_part}')
                        break
                    else:
                        # if not in sharing
                        shell.print_yellow(
                            f'\n{file_name} | {file_md5} already in sharing.\n'
                        )
                        break
                else:
                    shell.print_red(
                        f'\nWrong index: number in range 1 - {len(temp_files)} expected\n'
                    )
                    continue

        elif choice == "LOGO":
            packet = choice + ssid

            sd = None
            try:
                sd = net_utils.send_packet(tracker_ip4, tracker_ip6,
                                           tracker_port, packet)
            except net_utils.socket.error as e:
                shell.print_red(
                    f'\nError while sending the request to the tracker: {tracker_ip4}|{tracker_ip6} [{tracker_port}].'
                )
                shell.print_red(f'{e}')
                if sd is not None:
                    sd.close()
                return

            try:
                response = sd.recv(50).decode()
            except net_utils.socket.error as e:
                shell.print_red(
                    f'Unable to read the response from the socket: {e}\n')
                sd.close()
                return

            sd.close()

            if len(response) != 14:
                shell.print_red(
                    f"Invalid response form the socket: {response}.")
                return

            command = response[0:4]

            if command == "ALOG":
                part_own = int(response[4:14])
                shell.print_green('\nSuccessfully logged out')
                shell.print_blue(
                    f'{part_own} parts has been removed from sharing.\n')
                LocalData.clear_tracker()

            elif command == "NLOG":
                part_down = int(response[4:14])
                shell.print_yellow(
                    f'\nUnable to logout:\nYou have shared only {part_down} parts with other peer.\n'
                )

            else:
                shell.print_red(
                    f'\nReceived a packet with a wrong command from the socket: {command} -> {response}'
                )

        elif choice == 'SHAR':
            files = LocalData.get_shared_files()
            if not files:
                shell.print_red('\nYou currently have no files in sharing.')

            print('\nFiles actually in sharing:')
            for count, file in enumerate(files, 1):
                print(f'{count}] {LocalData.get_downloadable_file_name(file)}')

        elif choice == 'TRAC':
            shell.print_green(
                f'\nYour tracker is: {LocalData.get_tracker_ip4()}|{LocalData.get_tracker_ip6()} [{LocalData.get_tracker_port()}]'
            )

        else:
            shell.print_yellow(
                f'\nInvalid input code: "{choice}".\nPlease retry.\n')
            return
Exemplo n.º 26
0
    def serve(choice: str) -> None:
        """ Handle the peer packet

		:param choice: the choice to handle
		:return: None
		"""
        sp_ip4 = LocalData.get_superpeer_ip4()
        sp_ip6 = LocalData.get_superpeer_ip6()
        sp_port = LocalData.get_superpeer_port()
        p_ssid = LocalData.session_id

        if choice == "ADFF":
            # check se shared dir esiste
            if not os.path.exists('shared'):
                shell.print_red('\nCannot find the shared folder.')
                return

            # se non ci sono file nella shared dir avvisa ed esce
            if not os.scandir('shared'):
                shell.print_yellow(
                    'No file available for sharing. Add files to shared dir to get started.\n'
                )
                return

            temp_files = []
            shell.print_blue('\nFiles available for sharing:')
            for count, file in enumerate(os.scandir('shared'), 1):
                # stampa i risultati della scandir
                file_md5 = hasher.get_md5(f'shared/{file.name}')
                print(f'{count}] {file.name} | {file_md5}')
                temp_files.append((file_md5, file.name))

            while True:
                index = input('Choose a file to share (q to cancel): ')

                if index == "q":
                    print('\n')
                    return

                try:
                    index = int(index) - 1
                except ValueError:
                    shell.print_red(
                        f'\nWrong index: number in range 1 - {len(temp_files)} expected\n'
                    )
                    continue

                if 0 <= index <= len(temp_files) - 1:
                    file_name = LocalData.get_shared_file_name(
                        temp_files[index])
                    file_md5 = LocalData.get_shared_file_md5(temp_files[index])

                    # controlla se il file è già in condivisione
                    if not LocalData.is_shared_file(temp_files[index]):

                        # crea il pacchetto e lo invia al super peer
                        packet = choice + p_ssid + file_md5 + file_name.ljust(
                            100)
                        try:
                            net_utils.send_packet_and_close(
                                sp_ip4, sp_ip6, sp_port, packet)
                            shell.print_green(
                                f'Packet sent to supernode: {sp_ip4}|{sp_ip6} [{sp_port}]'
                            )
                        except net_utils.socket.error:
                            shell.print_red(
                                f'\nError while sending packet to supernode: {sp_ip4}|{sp_ip6} [{sp_port}]\n'
                            )

                        # aggiunge il file alla struttura dati ed esce
                        LocalData.add_shared_file(file_md5, file_name)
                        shell.print_blue(
                            f'\nNew shared file added {file_name} | {file_md5}'
                        )
                        break
                    else:
                        # il file è già in condivisione
                        shell.print_yellow(
                            f'\n{file_name} | {file_md5} already in sharing.\n'
                        )
                        break
                else:
                    shell.print_red(
                        f'\nWrong index: number in range 1 - {len(temp_files)} expected\n'
                    )
                    continue

        elif choice == "DEFF":
            # recupera i files in sharing
            files = LocalData.get_shared_files()

            # check se ci sono file in sharing
            if not files:
                shell.print_yellow(
                    'No files currently in sharing. Add files choosing the command from the menu.\n'
                )
                return

            # scelta del file da rimuovere
            shell.print_blue('\nFile currently in sharing:')
            for count, file in enumerate(files, 1):
                print(
                    f'{count}] {LocalData.get_shared_file_name(file)} | {LocalData.get_shared_file_md5(file)}'
                )

            while True:
                index = input(
                    'Choose a file to remove from sharing (q to cancel): ')

                if index == "q":
                    print('\n')
                    return

                try:
                    index = int(index) - 1
                except ValueError:
                    shell.print_red(
                        f'\nWrong index: number in range 1 - {len(files)} expected\n'
                    )
                    continue

                if 0 <= index <= len(files) - 1:
                    # recupera il file dalla DS
                    file = LocalData.get_shared_file(index)

                    # crea ed invia il pacchetto al supernode
                    packet = choice + p_ssid + LocalData.get_shared_file_md5(
                        file)
                    try:
                        net_utils.send_packet_and_close(
                            sp_ip4, sp_ip6, sp_port, packet)
                    except net_utils.socket.error:
                        shell.print_red(
                            f'\nError while sending packet to supernode: {sp_ip4}|{sp_ip6} [{sp_port}]\n'
                        )

                    # rimuove il file dalla DS
                    LocalData.remove_shared_file(file)

                    shell.print_green(
                        f'\n{LocalData.get_shared_file_name(file)} | {LocalData.get_shared_file_md5(file)} removed successfully.'
                    )
                    break
                else:
                    shell.print_red(
                        f'\nWrong index: number in range 1 - {len(files)} expected\n'
                    )
                    continue

        elif choice == "FIND":
            while True:
                search = input('\nInsert file\'s name (q to cancel): ')

                if search == "q":
                    print('\n')
                    return

                if not 0 < len(search) <= 20:
                    shell.print_red(
                        '\nQuery string must be a valid value (1 - 20 chars).')
                    continue

                break

            packet = choice + p_ssid + search.ljust(20)

            try:
                socket = net_utils.send_packet(sp_ip4, sp_ip6, sp_port, packet)

            except (net_utils.socket.error, AttributeError):
                shell.print_red(
                    f'\nError while sending the request to the superpeer: {sp_ip4}|{sp_ip6} [{sp_port}].\n'
                )
                if socket is not None:
                    socket.close()
                return

            spinner = SpinnerThread('Searching files', 'Research done!')
            spinner.start()

            try:
                socket.settimeout(25)
                command = socket.recv(4).decode()

                spinner.stop()
                spinner.join()
                print('\033[1A', end='\r')

                if command != "AFIN":
                    shell.print_red(
                        f'\nReceived a packet with a wrong command ({command}).\n'
                    )
                    socket.close()
                    return

            except net_utils.socket.error:
                shell.print_red(
                    f'\nError while receiving the response from the superpeer: {sp_ip4}|{sp_ip6} [{sp_port}].\n'
                )
                return
            except ValueError:
                shell.print_red(
                    f'\nInvalid packet from superpeer: {sp_ip4}|{sp_ip6} [{sp_port}].\n'
                )
                return

            # ('file_name', 'file_md5', owners[])
            downloadables = list()

            try:
                num_downloadables = int(socket.recv(3))

                # check se ci sono file da scaricare
                if num_downloadables == 0:
                    shell.print_yellow(f'{search} not found.\n')
                    socket.close()
                    return
            except net_utils.socket.error:
                shell.print_red(
                    f'\nError while receiving the response from the superpeer: {sp_ip4}|{sp_ip6} [{sp_port}].\n'
                )
                return

            for i in range(num_downloadables):
                # ('owner_ip4', 'owner_ip6', 'owner_port')
                owners = list()

                try:
                    file_md5 = socket.recv(32).decode()
                    file_name = socket.recv(100).decode().lstrip().rstrip()
                    num_copies = int(socket.recv(3))
                except net_utils.socket.error:
                    shell.print_red(
                        f'\nError while receiving the response from the superpeer: {sp_ip4}|{sp_ip6} [{sp_port}].\n'
                    )
                    continue
                except ValueError:
                    shell.print_red(
                        f'\nInvalid packet from superpeer: {sp_ip4}|{sp_ip6} [{sp_port}].\n'
                    )
                    continue

                for j in range(num_copies):
                    try:
                        (owner_ip4, owner_ip6) = net_utils.get_ip_pair(
                            socket.recv(55).decode())
                        owner_port = int(socket.recv(5))
                        owners.append((owner_ip4, owner_ip6, owner_port))
                    except net_utils.socket.error:
                        shell.print_red(
                            f'\nError while receiving the response from the superpeer: {sp_ip4}|{sp_ip6} [{sp_port}].\n'
                        )
                        continue
                    except ValueError:
                        shell.print_red(
                            f'\nInvalid packet from superpeer: {sp_ip4}|{sp_ip6} [{sp_port}].\n'
                        )
                        continue

                if owners:
                    # prepara una lista con tutti i file che possono essere scaricati
                    downloadables.append((file_name, file_md5, owners))

            if not downloadables:
                shell.print_red(
                    f'\nSomething went wrong while retrieving {search}\n')
                socket.close()
                return

            shell.print_green(f'\nFiles found:')
            for count, downloadable in enumerate(downloadables, 1):
                print(f'{count}] {downloadable[0]} | {downloadable[1]}')

            while True:
                choosed_file_index = input(
                    'Choose a file to download (q to cancel): ')

                if choosed_file_index == "q":
                    print('\n')
                    socket.close()
                    return

                try:
                    choosed_file_index = int(choosed_file_index) - 1
                except ValueError:
                    shell.print_red(
                        f'\nWrong index: number in range 1 - {len(downloadables)} expected\n'
                    )
                    continue

                if not 0 <= choosed_file_index <= len(downloadables) - 1:
                    shell.print_red(
                        f'\nWrong index: number in range 1 - {len(downloadables)} expected\n'
                    )
                    continue
                else:
                    choosed_file_name = downloadables[choosed_file_index][0]
                    choosed_file_md5 = downloadables[choosed_file_index][1]
                    choosed_file_owners = downloadables[choosed_file_index][2]

                    shell.print_green(
                        f'\nAvailable sources for {choosed_file_name}:')
                    for count, choosed_file_owner in enumerate(
                            choosed_file_owners, 1):
                        print(
                            f'{count}] {choosed_file_owner[0]}|{choosed_file_owner[1]} [{choosed_file_owner[2]}]'
                        )

                    while True:
                        choosed_owner_index = input(
                            f'Choose a source for {choosed_file_name} (q to cancel): '
                        )

                        if choosed_owner_index == "q":
                            print('\n')
                            return

                        try:
                            choosed_owner_index = int(choosed_owner_index) - 1
                        except ValueError:
                            shell.print_red(
                                f'\nWrong index: number in range 1 - {len(choosed_file_owners)} expected\n'
                            )
                            continue

                        if 0 <= choosed_owner_index <= len(
                                choosed_file_owners) - 1:
                            packet = "RETR" + choosed_file_md5
                            try:
                                Downloader(
                                    choosed_file_owners[choosed_owner_index]
                                    [0],
                                    choosed_file_owners[choosed_owner_index]
                                    [1],
                                    choosed_file_owners[choosed_owner_index]
                                    [2], packet, choosed_file_name).start()
                                shell.print_green(
                                    f'\n{choosed_file_name} downloaded successfully.\n'
                                )
                            except OSError:
                                shell.print_red(
                                    f'\nError while downloading {choosed_file_name}.\n'
                                )
                            break
                        else:
                            shell.print_red(
                                f'\nWrong index: number in range 1 - {len(choosed_file_owners)} expected\n'
                            )
                            continue
                    break

        elif choice == "SHOWSUPER":
            print(
                f'\nYour current superpeer is: {sp_ip4}|{sp_ip6} [{sp_port}]\n'
            )

        elif choice == "LOGO":
            packet = choice + p_ssid
            sock = net_utils.send_packet(sp_ip4, sp_ip6, sp_port, packet)

            try:
                command = sock.recv(4).decode()
                if command != "ALGO":
                    shell.print_red(
                        f'\nWrong response code "{command}": "{choice}" expected.\n'
                    )

                num_files = int(sock.recv(3))
                shell.print_blue(
                    f'\n{num_files} files has been removed from sharing.\n')
            except (net_utils.socket.error, AttributeError):
                shell.print_red(
                    f'\nError while receiving the response for "{choice}".\n')

            LocalData.clear_backup_data()

        else:
            pass