def login(self, tracker_ip, tracker_port = 80): try: login_sock = connect_socket(tracker_ip, tracker_port) login_sock.send("LOGI") login_sock.send(format_ip_address(get_local_ip(login_sock.getsockname()[0]))) login_sock.send(format_port_number(self.local_port)) response = read_from_socket(login_sock, 4) #read ALGI if response == "ALGI": my_session_id = read_from_socket(login_sock, 16) login_sock.close() UsersManager.set_my_session_id(my_session_id) klog("Done. My session id is: %s" % my_session_id) UsersManager.set_tracker(Peer(tracker_ip,tracker_port)) self.ui_handler.login_done(my_session_id) return True else: raise Exception("Response command error: %s" %response) except Exception, ex: klog(str(ex)) self.ui_handler.login_done(None)
def update_remote_file_data(self, file_id): my_tracker = UsersManager.get_tracker() try: sock = connect_socket(my_tracker.ip, my_tracker.port) local_ip = get_local_ip(sock.getsockname()[0]) sock.send("FCHU" + UsersManager.get_my_session_id()) sock.send(file_id) command = read_from_socket(sock, 4) if command == "AFCH": hitpeer = read_from_socket(sock, 3) for i in range(0, int(hitpeer)): peer_ip = read_from_socket(sock, 15) peer_port = read_from_socket(sock, 5) f = FilesManager.find_file_by_id(file_id) if not f: raise Exception("File %s not found in request emitter" % file_id) mask_length = int(math.ceil(f.parts_count / 8)) if f.parts_count % 8 != 0: mask_length += 1 klog("MASK_LENGTH = %s" % mask_length) partlist = read_from_socket(sock, mask_length) partlist_array = [] for b in partlist: byte = bin(int(binascii.b2a_hex(b),16)) byte = byte[2:] byte = format_byte(byte) for i in range(7,-1, -1): partlist_array.append(byte[i]) for j in range(len(partlist_array)): #klog("%s PARTE %s: %s" %(file_id,j,partlist_array[j])) FilesManager.update_remote_file_part(file_id, Peer(peer_ip, peer_port), j, bool(int(partlist_array[j]))) except Exception, ex: klog("Exception in updating file data to tracker: %s" % str(ex))
def search_for_files(self, query, ttl = TTL_FOR_FILES_SEARCH ): p_id = generate_packet_id(16) PacketsManager.add_new_generated_packet(p_id) if UsersManager.is_super_node(): # We need to search both locally and in the network PacketsManager.register_packet_id_as_local_search(p_id) # Perform a local search here. for file in FilesManager.find_files_by_query(query): owner = UsersManager.find_user_by_session_id(file.session_id) if owner: self.ui_handler.add_new_result_file(file.filename, owner.ip, owner.port, file.hash) # ...and send a QUER in the network, its results will be handled properly and should not interfere with # the ones of the local search for superpeer in PeersManager.find_known_peers(): sock = connect_socket(superpeer.ip, superpeer.port) local_ip = get_local_ip(sock.getsockname()[0]) sock.send("QUER" + p_id + format_ip_address(local_ip) + format_port_number(self.local_port) + format_ttl(ttl) + format_query(query)) sock.close() klog("Started query flooding for files: %s ttl: %s" %(query,ttl) ) else: my_superpeer = UsersManager.get_superpeer() if my_superpeer: sock = connect_socket(my_superpeer.ip, 80)#my_superpeer.port) sock.send("FIND" + UsersManager.get_my_session_id() + format_query(query)) klog("Started FIND for files: %s ttl: %s" %(query,ttl) ) # We need also some handling for those stupid peers that do not close the socket... #time.sleep(5) if read_from_socket(sock, 4) == 'AFIN': ServiceThread.afin_received(sock, self.ui_handler)
def _choose_random_superpeer(): superpeers = PeersManager.find_known_peers(True) if len(superpeers) > 0: my_superpeer = superpeers[random.randrange(0, len(superpeers),1)] UsersManager.set_superpeer(my_superpeer) klog("Choose this superpeer: %s:%s" %(my_superpeer.ip, str(my_superpeer.port))) klog("Login...") login_sock = connect_socket(my_superpeer.ip, 80)# int(my_superpeer.port)) login_sock.send("LOGI") login_sock.send(format_ip_address(get_local_ip(login_sock.getsockname()[0]))) login_sock.send(format_port_number(self.local_port)) try: read_from_socket(login_sock, 4) #read ALGI my_session_id = read_from_socket(login_sock, 16) login_sock.close() UsersManager.set_my_session_id(my_session_id) klog("Done. My session id is: %s" %my_session_id) self.ui_handler.superpeer_choosen(my_superpeer.ip, my_superpeer.port) self.ui_handler.login_done(my_session_id) except Exception, ex: klog(ex)
def unregister_file(self, file): my_superpeer = UsersManager.get_superpeer() sock = connect_socket(my_superpeer.ip, 80)#my_superpeer.port) local_ip = get_local_ip(sock.getsockname()[0]) sock.send("DEFF" + UsersManager.get_my_session_id()) sock.send(decode_md5(file.hash)) sock.close()
def logout_user(self, session_id): user = UsersManager.find_user_by_session_id(session_id) if user: numdeleted = FilesManager.delete_files_for_user(user) UsersManager.delete_user(user) return numdeleted else: return -1
def logout(self): my_superpeer = UsersManager.get_superpeer() sock = connect_socket(my_superpeer.ip, 80)#my_superpeer.port) sock.send("LOGO" + UsersManager.get_my_session_id()) response = read_from_socket(sock, 4) num_file_deleted = -1 if response == "ALGO": num_file_deleted = int(read_from_socket(sock, 3)) klog("LOGOUT Done. Deleted %d files" % num_file_deleted) else: klog("LOGOUT non eseguito") sock.close() return num_file_deleted
def _ask_for_peer_role(): msg_box = QMessageBox() msg_box.setText("Are you a super peer?") msg_box.addButton(QMessageBox.Yes) msg_box.addButton(QMessageBox.No) msg_box.show() msg_box.raise_() selection = msg_box.exec_() is_superpeer = (selection == QMessageBox.Yes) UsersManager.set_is_super_node(is_superpeer) return is_superpeer
def logout(self): my_tracker = UsersManager.get_tracker() sock = connect_socket(my_tracker.ip, 80) sock.send("LOGO" + UsersManager.get_my_session_id()) response = read_from_socket(sock, 4) num_file_deleted = -1 if response == "ALOG": num_file_deleted = int(read_from_socket(sock, 10)) klog("LOGOUT Done. Deleted %d files" % num_file_deleted) elif response == "NLOG": num_files = int(read_from_socket(sock, 10)) klog("LOGOUT refused from directory, you are the source for %d files" % num_files) else: klog("LOGOUT not working correctly in directory") sock.close() return num_file_deleted
def load_my_files(cls): for dirname, dirnames, filenames in os.walk(SHARED_PATH): for filename in filenames: path = dirname + "/" + filename md5 = hashing.encode_md5(hashing.calculate_md5_for_file_path(path)) file = None if UsersManager.is_super_node(): file = File(path, filename, md5, "0"*16) else: file = File(path, filename, md5, UsersManager.get_my_session_id) cls.shared_files().append(file)
def add_file_to_tracker(self, file): my_tracker = UsersManager.get_tracker() sock = connect_socket(my_tracker.ip, my_tracker.port) local_ip = get_local_ip(sock.getsockname()[0]) sock.send("ADDR" + UsersManager.get_my_session_id()) sock.send(file.id) sock.send(format_filesize(file.file_size)) sock.send(format_partsize(file.part_size)) sock.send(format_filename(file.filename)) try: response = read_from_socket(sock, 4) if response == "AADR": part_num = read_from_socket(sock, 8) if int(part_num) == int(file.parts_count): klog("File %s successfully added to directory service" % file.filename) else: klog("Wrong partnumber received from directory") else: klog("wrong ack received from directory service") except Exception, ex: klog("Exception in adding file to tracker: %s" % str(ex))
def register_part_to_tracker(self, file, part_num): my_tracker = UsersManager.get_tracker() sock = connect_socket(my_tracker.ip, my_tracker.port) local_ip = get_local_ip(sock.getsockname()[0]) sock.send("RPAD" + UsersManager.get_my_session_id()) sock.send(file.id) sock.send(format_partnum(part_num)) try: response = read_from_socket(sock,4) if response == "APAD": part_num = int(read_from_socket(sock, 8)) klog("Part num from tracker: %s" %str(part_num)) if part_num == FilesManager.get_completed_file_parts_nums_count(file.id): klog("Part succesfully registered") else: klog("Wrong partnumber from directory received %s but i have %s" %(str(part_num), str(FilesManager.get_completed_file_parts_nums_count(file.id)))) else: klog("Wrong ack received from directory service when trying to register a part") except Exception, ex: klog("Exception in registering a downloaded part on the tracker: %s" %str(ex))
def search_for_files(self, query): my_tracker = UsersManager.get_tracker() try: sock = connect_socket(my_tracker.ip, my_tracker.port) sock.send("LOOK" + UsersManager.get_my_session_id() + format_query(query)) klog("Started LOOK for file: %s" %query) if read_from_socket(sock, 4) == 'ALOO': files_count = int(read_from_socket(sock, 3)) for i in range(0, files_count): file_id = read_from_socket(sock, 16) file_name = read_from_socket(sock, 100).strip(' ') file_size = read_from_socket(sock, 10) part_size = read_from_socket(sock, 6) FilesManager.add_new_remote_file(file_name, file_id, file_size, part_size) self.ui_handler.add_new_result_file(file_name, file_id, file_size, part_size) else: raise Exception("Response command error: %s. Wanted LOOK" % response) except Exception, ex: klog(str(ex))
def run(self): try: self._socket.setblocking(1) # <-------- ?? command = str(self._socket.recv(4)) # # PEERS # # Received package asking for a file if command == "RETP": klog("RETP received") CHUNK_DIM = 128 file_id = self._socket.recv(16) part_num = int(self._socket.recv(8)) self._socket.send("AREP") #sending the ack command remote_ip = self._socket.getpeername()[0] my_session_id = UsersManager.get_my_session_id() # Get the file matching the file_id klog("finding file with id: %s, session_id %s, part %s" %(file_id, my_session_id, part_num)) file = FilesManager.find_file_by_id(file_id) if file: klog("i have found the file: %s stored in %s" % (file.filename, file.filepath)) # Chunks size = file.get_part_size(part_num)#file_size(file.filepath) bytes_sent = 0 chunks_num = int(size // CHUNK_DIM) leftover = size % CHUNK_DIM if leftover != 0.0: chunks_num += 1 self._socket.send(format_chunks_number(chunks_num)) #sending the chunks number part = file.get_part(part_num) part_size = file.get_part_size(part_num) index = 0 chunk = part[0:CHUNK_DIM] while True: self._socket.send(format_chunk_length(len(chunk))) #sending the chunk length bytes_sent += self._socket.send(chunk) #sending the chunk percent = bytes_sent*100/size self.ui_handler.upload_file_changed(file.filename, file.id, part_num, remote_ip, percent) index += 1 if ((index * CHUNK_DIM) <= part_size) and ((index + 1)* CHUNK_DIM <= part_size): chunk = part[index * CHUNK_DIM : (index + 1)* CHUNK_DIM] elif ((index * CHUNK_DIM) <= part_size) and ((index + 1)* CHUNK_DIM > part_size): chunk = part[index * CHUNK_DIM : ] else: break ''' #open the file file2send = file.get_part(part_num)#open(file.filepath, 'rb') chunk = file2send.read(CHUNK_DIM) while chunk != '': self._socket.send(format_chunk_length(len(chunk))) #sending the chunk length bytes_sent += self._socket.send(chunk) #sending the chunk percent = bytes_sent*100/size self.ui_handler.upload_file_changed(file.filename, file.id, part_num, remote_ip, percent) chunk = file2send.read(CHUNK_DIM) file2send.close() ''' klog("upload completed: %s" %file.filename) self.ui_handler.upload_file_changed(file.filename, file.id, part_num, remote_ip, 100) else: klog("I do not have this file!") else: klog("ERROR: received a %s command that service_thread does not have to handle:" %command) # Close the socket self._socket.close() except Exception, ex: print ex
def add_file(self, session_id, hash, file_name): user = UsersManager.find_user_by_session_id(session_id) if user: FilesManager.create_file(file_name, hash, user)
def run(self): try: self._socket.setblocking(1) # <-------- ?? command = str(self._socket.recv(4)) # # FILES # # Received package looking for a file if command == "QUER": if UsersManager.is_super_node(): pckt_id = str(self._socket.recv(16)) sender_ip = str(self._socket.recv(15)) sender_port = str(self._socket.recv(5)) ttl = int(self._socket.recv(2)) query = str(self._socket.recv(20)) klog("%s pid: %s %s:%s ttl: %s query: %s" % (command, pckt_id, sender_ip, sender_port, ttl, query)) if not PacketsManager.is_packet_id_known(pckt_id): PacketsManager.add_new_packet(pckt_id, sender_ip) if int(ttl) > 0: # look for the requested file for f in FilesManager.find_files_by_query(query): command = "AQUE" sock = connect_socket(sender_ip, sender_port) sock.send( command + pckt_id + format_ip_address(self.ip) + format_port_number(self.port) ) sock.send(decode_md5(f.hash)) sock.send(format_filename(f.filename)) klog( "command sent %s pkid:%s %s:%s md5: %s filename: %s" % (command, pckt_id, self.ip, self.port, f.hash, f.filename) ) sock.close() # decrease ttl propagate the message to the peers ttl = format_ttl(ttl - 1) if int(ttl) > 0: for superpeer in PeersManager.find_known_peers(superpeers=True): # query flooding to the known superpeers peers except for the sender if not PeersManager.are_same_peer(superpeer, Peer(sender_ip, sender_port)): sock = connect_socket(superpeer.ip, superpeer.port) sock.send(command + pckt_id + sender_ip + sender_port + str(ttl) + query) klog( "command sent to %s:%s: %s pkid:%s %s:%s ttl: %s query: %s" % ( superpeer.ip, superpeer.port, command, pckt_id, sender_ip, sender_port, ttl, query, ) ) sock.close() # Received package in reply to a file research elif command == "AQUE": klog("AQUE received") search_id = str(self._socket.recv(16)) sender_ip = str(self._socket.recv(15)) sender_port = str(self._socket.recv(5)) hash = encode_md5(self._socket.recv(16)) filename = str(self._socket.recv(100)).strip(" ") if PacketsManager.is_local_search(search_id): if PacketsManager.is_generated_packet_still_valid(search_id): klog("Found %s from %s:%s" % (filename, sender_ip, sender_port)) self.ui_handler.add_new_result_file(filename, sender_ip, sender_port, hash) else: ServiceThread.add_query_result(search_id, sender_ip, sender_port, hash, filename) elif command == "FIND": if UsersManager.is_super_node(): session_id = str(self._socket.recv(16)) query = str(self._socket.recv(20)) p_id = generate_packet_id(16) ttl = 3 # Launch a request to the other super peers with the query for superpeer in PeersManager.find_known_peers(True): sock = connect_socket(superpeer.ip, superpeer.port) local_ip = get_local_ip(sock.getsockname()[0]) sock.send( "QUER" + p_id + format_ip_address(local_ip) + format_port_number(self.port) + format_ttl(ttl) + format_query(query) ) sock.close() ServiceThread.initialize_for_pckt(p_id) # enable the receive of packets for this query time.sleep(20) # search_id is the packet id of QUER request, it identifies univocally the query superpeers_result = ServiceThread.get_query_results(p_id) my_directory_result = FilesManager.find_files_by_query(query) ServiceThread.clear_pending_query(p_id) result = {} # costruisco l array di risultati for r in superpeers_result: if result.has_key(r["hash"]): result[r["hash"]].peers.append([{"ip": r["ip"], "port": r["port"]}]) else: result[r["hash"]] = { "filemd5": r["hash"], "filename": r["filename"], "peers": [{"ip": r["ip"], "port": r["port"]}], } for f in my_directory_result: if f.is_my_file(): if result.has_key(f.hash): result[f.hash]["peers"].append({"ip": self.ip, "port": self.port}) else: result[f.hash] = { "filemd5": f.hash, "filename": f.filename, "peers": [{"ip": self.ip, "port": self.port}], } else: u = UsersManager.find_user_by_session_id(f.session_id) if result.has_key(f.hash): result[f.hash]["peers"].append({"ip": u.ip, "port": u.port}) else: result[f.hash] = { "filemd5": f.hash, "filename": f.filename, "peers": [{"ip": u.ip, "port": u.port}], } # must send AFIN # self._socket.close() peer = UsersManager.find_user_by_session_id(session_id) # sock = connect_socket(peer.ip, peer.port) sock = self._socket sock.send("AFIN" + format_deletenum(len(result))) for key, r in result.items(): sock.send(decode_md5(r["filemd5"])) sock.send(format_filename(r["filename"])) sock.send(format_deletenum(len(r["peers"]))) for peer in r["peers"]: sock.send(format_ip_address(peer["ip"])) sock.send(format_port_number(peer["port"])) # threading.Timer(20, self.search_finished, args=(p_id,)).start() #calls the fun function with p_id as argument klog("Sent AFIN") elif command == "AFIN": klog("AFIN received") ServiceThread.afin_received(self._socket, self.ui_handler) # # PEERS # elif command == "LOGI": if UsersManager.is_super_node(): peer_ip = str(read_from_socket(self._socket, 15)) peer_port = str(read_from_socket(self._socket, 5)) if UsersManager.find_user_by_ip(peer_ip) is not None: self._socket.send("ALGI" + "0" * 16) klog("Sent ALGI" + "0" * 16 + "to: %s" % (peer_ip)) else: session_id = self.login_user(peer_ip, peer_port) klog( "Received a LOGI, from: %s, port: %s. Session id created: %s" % (peer_ip, peer_port, session_id) ) self._socket.send("ALGI" + session_id) klog("Sent ALGI to: %s, port: %s" % (peer_ip, peer_port)) self.ui_handler.add_new_peer(peer_ip, peer_port) elif command == "ALGI": # Normally this is done in the RequestEmitter, but we have the same code here to # prevent crashes in case of closed and re-opened socket session_id = str(read_from_socket(self._socket, 16)) klog("ALGI received form super peer: %s", session_id) UsersManager.set_my_session_id(session_id) self.ui_handler.login_done(session_id) elif command == "LOGO": peer_session_id = str(read_from_socket(self._socket, 16)) peer = UsersManager.find_user_by_session_id(peer_session_id) peer_ip = peer.ip peer_port = peer.port klog("Received a LOGO, from session_id: %s. Peer: %s:%s" % (peer_session_id, peer_ip, peer_port)) delete_num = self.logout_user(peer_session_id) self._socket.send("ALGO" + format_deletenum(delete_num)) klog("Sent ALGO to session_id: %s deletenum: %d" % (peer_session_id, delete_num)) self.ui_handler.remove_peer(peer_ip, peer_port) elif command == "ALGO": delete_num = read_from_socket(self._socket, 3) klog("ALGO received. delete num: %s" % delete_num) UsersManager.set_my_session_id("") klog("TODO: destroy the listening client???") # Received package looking for super-peer elif command == "SUPE": klog("SUPE received") pckt_id = str(read_from_socket(self._socket, 16)) sender_ip = str(read_from_socket(self._socket, 15)) sender_port = str(read_from_socket(self._socket, 5)) ttl = int(read_from_socket(self._socket, 2)) if not PacketsManager.is_packet_id_known(pckt_id): PacketsManager.add_new_packet(pckt_id, sender_ip) if int(ttl) > 0: if UsersManager.is_super_node(): # Respond with an ASUP sock = connect_socket(sender_ip, sender_port) sock.send("ASUP" + pckt_id + self.ip + self.port + str(ttl)) klog( "command sent to %s:%s: ASUP pkid:%s %s:%s ttl: %s" % (sender_ip, sender_port, pckt_id, self.ip, self.port, ttl) ) sock.close() # decrease ttl and propagate the message to the peers/superpeers ttl = format_ttl(ttl - 1) if int(ttl) > 0: # propagate the SUPE for peer in PeersManager.find_known_peers(): if not PeersManager.are_same_peer(peer, Peer(sender_ip, sender_port)): sock = connect_socket(peer.ip, peer.port) sock.send("SUPE" + pckt_id + sender_ip + sender_port + str(ttl)) klog( "command sent to %s:%s: SUPE pkid:%s %s:%s ttl: %s" % (peer.ip, peer.port, pckt_id, sender_ip, sender_port, ttl) ) sock.close() # Received package in reply to a super-peer search elif command == "ASUP": pckt_id = str(self._socket.recv(16)) peer_ip = str(self._socket.recv(15)) peer_port = str(self._socket.recv(5)) klog("ASUP received from %s:%s" % (peer_ip, peer_port)) if PacketsManager.is_generated_packet_still_valid(pckt_id): # Check if the superpeer war already added as a normal peer if PeersManager.is_known_peer(Peer(peer_ip, peer_port)): PeersManager.become_superpeer(peer_ip, peer_port) self.ui_handler.add_new_superpeer(peer_ip, peer_port) else: if peer_ip != self.ip: PeersManager.add_new_peer(Peer(peer_ip, peer_port, True)) self.ui_handler.add_new_superpeer(peer_ip, peer_port) # Received package asking for a file elif command == "RETR": klog("RETR received") CHUNK_DIM = 128 md5 = encode_md5(self._socket.recv(16)) self._socket.send("ARET") # sending the ack command remote_ip = self._socket.getpeername()[0] my_session_id = UsersManager.get_my_session_id() # Get the file matching the md5 klog("finding file with md5: %s, session_id %s" % (md5, my_session_id)) file = FilesManager.find_file_by_hash(md5) if file: klog("i have found the file: %s stored in %s" % (file.filename, file.filepath)) # Chunks size = file_size(file.filepath) bytes_sent = 0 chunks_num = int(size // CHUNK_DIM) leftover = size % CHUNK_DIM if leftover != 0.0: chunks_num += 1 self._socket.send(format_chunks_number(chunks_num)) # sending the chunks number # open the file file2send = open(file.filepath, "rb") chunk = file2send.read(CHUNK_DIM) while chunk != "": self._socket.send(format_chunk_length(len(chunk))) # sending the chunk length bytes_sent += self._socket.send(chunk) # sending the chunk percent = bytes_sent * 100 / size self.ui_handler.upload_file_changed(file.filename, file.hash, remote_ip, percent) chunk = file2send.read(CHUNK_DIM) file2send.close() klog("upload completed: %s" % file.filename) self.ui_handler.upload_file_changed(file.filename, file.hash, remote_ip, 100) else: klog("I do not have this file!") elif command == "ADFF": peer_session_id = str(read_from_socket(self._socket, 16)) file_hash = encode_md5(read_from_socket(self._socket, 16)) file_name = str(read_from_socket(self._socket, 100)).strip(" ") klog("Received a ADFF, from: %s. Hash: %s. Filename: %s." % (peer_session_id, file_hash, file_name)) self.add_file(peer_session_id, file_hash, file_name) elif command == "DEFF": peer_session_id = str(read_from_socket(self._socket, 16)) file_hash = encode_md5(read_from_socket(self._socket, 16)) self.remove_file(peer_session_id, file_hash) klog("Received a DELF, from: %s. Hash: %s." % (peer_session_id, file_hash)) if command == "": condition = False # Close the socket self._socket.close() except Exception, ex: condition = False print ex
def login_user(self, ip, port): user = UsersManager.create_user(ip, port) return user.session_id