class logout: def __init__(self, config): self.t_ipv4 = config.trackerV4 self.t_ipv6 = config.trackerV6 self.t_port = config.trackerP self.sid = Util.sessionId self.con = Conn(self.t_ipv4, self.t_ipv6, self.t_port) def send_logout(self): if(self.con.connection()): db = dataBase() self.log_pkt = "LOGO"+self.sid self.con.s.send(self.log_pkt.encode()) self.ack_log = self.con.s.recv(14) self.bytes_read = len(self.ack_log) while(self.bytes_read < 14): self.ack_log += self.con.s.recv(14 - self.bytes_read) self.bytes_read = len(self.ack_log) if(self.ack_log[0:4].decode() != "NLOG"): db.updateConfig('mode','normal') db.deleteAll() Util.mode = 'normal' del db else: Util.printLog("Logout failed: "+self.ack_log.decode()) self.con.deconnection() else: Util.printlog("Connection refused...")
def searchNeighborhood(self): db = dataBase() nears = db.retrieveNeighborhood(self.config) for near in nears: data = Util.ip_deformatting(near[0], near[1]) connRoot = Conn(data[0], data[1], data[2]) connRoot.connection() connRoot.s.send(self.pack.encode()) connRoot.deconnection()
class Add: def __init__(self, config, sid): db = dataBase() self.t_ipv4 = config.trackerV4 self.t_ipv6 = config.trackerV6 self.t_port = config.trackerP self.sid = sid self.lenpart = db.retrieveConfig(('lenPart',)).zfill(6) self.con = Conn(self.t_ipv4, self.t_ipv6, self.t_port) def add_file(self, file): print('Files/'+file) self.check_file = Path('Files/'+file) db = dataBase() if (self.check_file.is_file()): self.f = open('Files/'+file, 'rb') self.contenuto = self.f.read() self.filename = file self.size = str(os.stat('Files/'+file).st_size).zfill(10) self.FileHash = hashlib.md5() self.FileHash.update(self.contenuto) self.FileHash.hexdigest() if (len(self.filename) < 100): self.f_name = self.filename.ljust(100, ' ') if(self.con.connection()): self.data_add_file = 'ADDR' + self.sid + self.size + str(self.lenpart).zfill(6) + self.f_name + self.FileHash.hexdigest() self.con.s.send(self.data_add_file.encode()) self.ack_aadr = self.con.s.recv(12) self.bytes_read = len(self.ack_aadr) while(self.bytes_read < 12): print(self.bytes_read) self.ack_aadr += self.con.s.recv(12 - self.bytes_read) self.bytes_read = len(self.ack_aadr) if(self.ack_aadr[0:4].decode() == "AADR"): npart = db.insert_file(self.sid, self.FileHash.hexdigest(), self.filename, int(self.size), int(self.lenpart)) self.con.deconnection() else: print("Connection refused...") else: print("There isn't any file with this name in your directory") sleep(4)
def searchNeighborhood(self): db = dataBase() nears = db.retrieveNeighborhood(self.config) for near in nears: Util.printLog("NEAR ------") Util.printLog(str(near)) Util.printLog(self.pack) Util.printLog("-----------") data = Util.ip_deformatting(near[0], near[1], None) connRoot = Conn(data[0], data[1], data[2]) connRoot.connection() connRoot.s.send(self.pack.encode()) connRoot.deconnection()
class Login: def __init__(self, ipp2p_dir_v4, ipp2p_dir_v6, my_ipv4, my_ipv6, pp2p_bf, config): self.ip_dir_4 = ipp2p_dir_v4 self.ip_dir_6 = ipp2p_dir_v6 self.dir_port = config.selfP self.my_ipv4 = my_ipv4 self.my_ipv6 = my_ipv6 self.pp2p_bf = pp2p_bf self.con = Conn(self.ip_dir_4, self.ip_dir_6, self.dir_port) def login(self): print("\n--- LOGIN ---\n") try: self.con.connection() except IOError as expt: print("Errore di connessione") print(expt) sys.exit(0) self.ipp2p = Util.ip_formatting(self.ip_dir_4, self.ip_dir_6, self.dir_port) data_login = "******" + self.ipp2p self.con.s.send(data_login.encode()) self.con.deconnection() return self.sid def logout(self, sid): print("\n--- LOGOUT ---\n") self.con.connection() data_logout = "LOGO" + sid.decode() self.con.s.send(data_logout.encode()) self.con.deconnection()
class Ricerca: def __init__(self, ipv4, ipv6, port, ttl, time_res, search, lock): self.lock = lock self.ipv4 = ipv4 self.ipv6 = ipv6 self.port = port self.ttl = ttl self.time_res = time_res self.search = search def query(self, config): db = dataBase() pktid = ''.join(random.choice(string.ascii_uppercase+string.digits) for _ in range(16)) ipp2p_pp2p = Util.ip_formatting(self.ipv4, self.ipv6, self.port) # richiesta vicini near = Vicini(config, self.port) # thread per ascolto di riposta dei vicini #th_near_stop = th.Event() th_near = Vicini_res(self.port, self.lock) th_near.start() # partenza richiesta dei vicini near.searchNeighborhood() #th_near_stop.set() Util.printLog("PRE JOIN POSSIBILE INVIO DI CAZZATE") th_near.join() db.insertRequest(pktid, ipp2p_pp2p[:55], time.time()) self.research = "QUER" + pktid + ipp2p_pp2p + str(self.ttl).zfill(2) + (self.search+(' '*(20-len(self.search)))) # retrieve neighbors from database self.neighbors = db.retrieveNeighborhood(config) Util.printLog("SONO NELLA RICERCA PRIMA DI RETR") #thread in ascolto per ogni ricerca retr = Retr(self.port, config, self.lock) #th_quer_stop = th.Event() retr.start() Util.printLog("SONO NELLA RICERCA DOPO RETR") #sending query to roots and neighbors for n in self.neighbors: addr = Util.ip_deformatting(n[0], n[1], self.ttl) #ip4 = ipad.ip_address(n[0][:15]) ip6 = ipad.ip_address(n[0][16:]) self.con = Conn(addr[0], str(ip6), addr[2]) try: Util.printLog("QUER --------------------------------") Util.printLog(self.research) Util.printLog(str(len(self.research))) Util.printLog(addr[0]) Util.printLog("-------------------------------------") self.con.connection() self.con.s.send(self.research.encode()) self.con.deconnection() except IOError as expt: print("Errore di connessione") print(expt) sys.exit(0) del db return pktid
def run(self): Util.printLog('\n\nApertura thread SUPE\n\n') db = dataBase() Util.lock.acquire() res = db.retrieveCounterRequest(self.pid, self.pack[20:75]) if (res == 0): # Richiesta già conosciuta Util.printLog("Eseguo SUPE per: " + self.ipRequest) db.insertRequest(self.pid, self.pack[20:75], time.time()) Util.globalLock.acquire() mode = Util.mode # Prelevo la modalità attuale Util.globalLock.release() if self.ttl > 1: # Inoltro richiesta ai vicini if mode in ['update', 'updateS']: Util.printLog('Update. Prendo vicini da lista') neighborhood = Util.listPeers if mode == 'normal': Util.printLog('Invio SUPE da modalità ::: ' + mode) neighborhood = db.retrievePeers() else: Util.printLog('Invio SUPE da modalità ::: ' + mode) neighborhood = db.retrieveSuperPeers() Util.lock.release() self.ttl = str(self.ttl - 1).zfill(2) self.pack = ''.join((self.pack[:80], self.ttl)) for neighbor in neighborhood: ipv4, ipv6, port = Util.ip_deformatting( neighbor[0], neighbor[1]) if ipv4 != self.ipRequest and ipv6 != self.ipRequest and ipv4 != self.ipv4: con = Conn(ipv4, ipv6, port) if con.connection(): con.s.send(self.pack.encode()) Util.printLog("Inoltro SUPE a vicino ::: " + ipv4) con.deconnection() else: Util.printLog("Inoltro SUPE fallita per ::: " + ipv4) else: Util.lock.release( ) # Non devo inoltrare, ma devo comunque rilasciare la lock if mode in ['updateS', 'super']: # Sono superpeer e rispondo self.pack = 'ASUP' + self.pid + self.myIPP Util.printLog('ASUP pacchetto ::: ' + str(self.pack)) Util.printLog('ASUP verso ::: ' + self.ipv4 + self.ipv6 + str(self.port)) con = Conn(self.ipv4, self.ipv6, self.port) if con.connection(): con.s.send(self.pack.encode()) Util.printLog('Risposta ASUP a ::: ' + self.ipv4) con.deconnection() else: Util.printLog('Risposta ASUP fallita per ::: ' + self.ipv4) else: Util.lock.release() Util.printLog("SUPE per: " + self.ipRequest + ". Già eseguita") Util.printLog('\n\nChiusura thread SUPE\n\n')
class AddRm: def __init__(self, ipp2p_4, ipp2p_6, pp2p, dict_filesystem, sid): self.ipp2p_4 = ipp2p_4 self.ipp2p_6 = ipp2p_6 self.pp2p = pp2p self.sid = sid self.dict_filesystem = dict_filesystem self.con = Conn(self.ipp2p_4, self.ipp2p_6, self.pp2p) def aggiunta(self, file): print("\n--- AGGIUNTA ---\n") # verifico l'esistenza del file self.check_file = Path(file) if (self.check_file.is_file()): self.f = open(file, 'rb') self.contenuto = self.f.read() self.filename = self.f.name self.FileHash = hashlib.md5() self.FileHash.update(self.contenuto) self.FileHash.hexdigest() if (len(self.filename) < 100): f_name = self.filename.ljust(100, ' ') self.con.connection() self.dict_filesystem[self.FileHash.hexdigest()] = self.filename data_add_file = "ADDF" + str(self.sid.decode()) + self.FileHash.hexdigest() + f_name self.con.s.send(data_add_file.encode()) print("Ip peer ---> " + str(self.ipp2p_4)) print("Ip peer ---> " + str(self.ipp2p_6)) print("Port peer ---> " + str(self.pp2p)) print(data_add_file) self.ack_add = self.con.s.recv(7) # 4B di AADD + 3B di copia del file self.bytes_read = len(self.ack_add) while(self.bytes_read < 7): self.ack_add += self.con.s.recv(7 - self.bytes_read) self.bytes_read = len(self.ack_add) if (self.ack_add[:4].decode() == "AADD"): print(str(self.ack_add[0:7].decode()), "\n") else: print("Errore del pacchetto, stringa 'AADD' non trovata") exit() self.con.deconnection() file_write = File_system(self.FileHash.hexdigest(), self.filename) file_write.write() else: print("Controllare l'esistenza del file o il percorso indicato in fase di input") return self.dict_filesystem def rimuovi(self): print("\n--- RIMUOVI FILE ---\n") self.rm_file = input("Inserisci il nome del file che desideri eliminare dalla directory:\n") self.check_file = Path(self.rm_file) if (self.check_file.is_file()): self.f = open(self.rm_file, 'rb') self.contenuto = self.f.read() self.FileHash = hashlib.md5() self.FileHash.update(self.contenuto) self.FileHash.hexdigest() self.con.connection() data_remove_file = "DELF" + str(self.sid.decode()) + self.FileHash.hexdigest() print(data_remove_file) self.con.s.send(data_remove_file.encode()) self.ack_rm = self.con.s.recv(7) # 4B di DELF + 3B di copia del file self.bytes_read = len(self.ack_rm) while(self.bytes_read < 7): self.ack_rm += self.s.recv(7 - self.bytes_read) self.bytes_read = len(self.ack_rm) if (self.ack_rm[:4].decode() == "ADEL"): print(str(self.ack_rm.decode()), "\n") else: print("Errore del pacchetto, stringa 'ADEL' non trovata") exit() if(self.ack_rm[4:].decode() != "999"): del self.dict_filesystem[self.FileHash.hexdigest()] file_delete = File_system(self.FileHash.hexdigest(), self.rm_file) self.dict_filesystem = file_delete.over(self.dict_filesystem) self.con.deconnection() return self.dict_filesystem self.con.deconnection() else: print("Controllare l'esistenza del file o che il percorso indicato in fase di input sia corretto")
def updatePeers(): globalLock.acquire() mode = Util.mode if mode == 'normal': Util.mode = 'update' else: Util.mode = 'updateS' globalLock.release() lock.acquire() db = dataBase() listNormal = db.retrievePeers() listSuper = db.retrieveSuperPeers() #db.deletePeers() db.deleteSuperPeers() config = db.retrieveConfig(('selfV4', 'selfV6', 'selfP', 'ttl')) idPacket = ip_packet16() ip = ip_formatting(config.selfV4, config.selfV6, config.selfP) db.insertRequest(idPacket, ip[:55], time.time()) lock.release() pack = 'SUPE' + idPacket + ip + config.ttl.zfill(2) listPeers = listSuper + list(set(listNormal) - set(listSuper)) globalLock.acquire() statusRequest[idPacket] = True globalLock.release() count = 0 for peer in listPeers: ipv4, ipv6, port = Util.ip_deformatting(peer[0], peer[1]) con = Conn(ipv4, ipv6, port) if con.connection(): count += 1 con.s.send(pack.encode()) printLog("Richiesta SUPE a vicino ::: " + ipv4) con.deconnection() else: printLog("Richiesta SUPE fallita per ::: " + ipv4) if count == 0: print( " .-. " ) print( " ( o)-. " ) print( " ) )\|\) " ) print( " _./ (,_ " ) print( " ( '**\" ) " ) print( " \\\\\ /// " ) print( " \\\\\|/// " ) print( " _______//|\\\\____________ . " ) print( " ,'______///|\\\\\________,'| \ : / " ) print( " _ _ | ____________________|,' ' _ ' " ) print( " ' Y ' _ _ | || | -= ( (_) )=- " ) print( " _ _ ' Y ' | || | . . " ) print( " ' Y '_ _ | || | / : \ " ) print( " ( Y ) | || 8 ' " ) print( " | || 8 " ) print( " | || /\/\ 8 " ) print( " | || .' ``/| " ) print( " | || | x ``| " ) print( " | || | /. `/` " ) print( " | || '_/| /``` .-. " ) print( " | || (_,' ```` |.| " ) print( " |J | || | \ /)|`|(\ " ) print( " L| | || ,' \ (.(|'|)`) " ) print( " | | || ,','| .' \ `\`'./' " ) print( "~~~~~~~~~~~~~~~~~~~| ||~~~~~||~~||. \~~~~~~~~~~~~|.|~~~~~~~~~~~ " ) print( " | || || || \ \ ,|`|. " ) print( " ~~ | || \"\" \"\" \ \ \"'\" ~~ " ) print( " | || ) . ) " ) print( " | || / , ),'| ~~ " ) print( " ~~ | || ___/ / ,' | (_) " ) print( " ((__)) | || ~~ I____/ ,' | /\"/ " ) print( " ( 0 0) | || I____,' * ^~^ " ) print( " `\_\\\\ | || ~~ " ) print( " \"'\"' | || " ) print( " ~~ | || ~~ ~~ " ) print( " |_|/ " ) print( " " ) print('\nNobody found after update. Sorry, you\'re on your own\n') exit() cond = Condition() cond.acquire() cond.wait(20) cond.release() globalLock.acquire() statusRequest[idPacket] = False globalLock.release() globalLock.acquire() Util.mode = mode globalLock.release()
class Download: def __init__(self, sid, ipp2p_B_4, ipp2p_B_6, pp2p_B, md5, filename, ipp2p_dir_4, ipp2p_dir_6): #ip other peer self.ipp2p_B_4 = ipp2p_B_4 self.ipp2p_B_6 = ipp2p_B_6 self.pp2p_B = pp2p_B #ip directory self.ipp2p_dir_4 = ipp2p_dir_4 self.ipp2p_dir_6 = ipp2p_dir_6 self.pp2p_dir = 3000 #file self.file_signature = md5 self.filename = filename #chunk veriables self.data_recv = [] #var for bytes controller self.bytes_read_f = 0 self.bytes_read_l = 0 self.bytes_read = 0 self.bytes_read_i = 0 #sessionID for download number self.sid = sid def download(self): print("\n--- DOWNLOAD ---\n") self.con = Conn(self.ipp2p_B_4, self.ipp2p_B_6, int(self.pp2p_B)) self.con.connection() self.md5 = self.file_signature print(self.md5) to_peer = "RETR" + self.md5 self.con.s.send(to_peer.encode('ascii')) self.first_packet = self.con.s.recv(10) self.bytes_read_f = len(self.first_packet) while (self.bytes_read_f < 10): self.first_packet += self.con.s.recv(10 - self.bytes_read_f) self.bytes_read_f = len(self.first_packet) if (self.first_packet[:4].decode() == "ARET"): i = self.first_packet[4:10].decode( ) # n di chunk o indice del ciclo for for j in range(int(i)): self.chunk_length = self.con.s.recv( 5) # lunghezza del primo chunk self.bytes_read_l = len(self.chunk_length) while ( self.bytes_read_l < 5 ): # controllo che siano stati realmente letti i bytes richiesti self.chunk_length += self.con.s.recv(5 - self.bytes_read_l) self.bytes_read_l = len(self.chunk_length) self.chunk = self.con.s.recv(int(self.chunk_length)) # dati #self.data_recv.append(self.chunk) self.bytes_read = len(self.chunk) while ( self.bytes_read < int(self.chunk_length) ): # controllo che siano stati realmente letti i bytes richiesti self.chunk += self.con.s.recv( int(self.chunk_length) - self.bytes_read) self.bytes_read = len(self.chunk) #self.data_recv.append(buffer) self.data_recv.append(self.chunk) self.con.deconnection() check_file = Path(self.filename) print(check_file) if (check_file.is_file()): choice = input( "\nIl file esiste già nel tuo file system, vuoi sovrascriverlo? (Y,n): " ) if (choice == "Y"): os.remove(self.filename) file_recv = open(self.filename, "ab") for i in self.data_recv: file_recv.write(i) else: return else: file_recv = open(self.filename, "ab") for i in self.data_recv: file_recv.write(i) f = open(self.filename, "rb") r = f.read() print("\n--- FILE DOWNLOADED ---\n") self.con2 = Conn(self.ipp2p_dir_4, self.ipp2p_dir_6, int(self.pp2p_dir)) self.con2.connection() self.info_packet = "DREG" + self.sid + self.md5 self.con2.s.send(self.info_packet.encode('ascii')) self.info_recv = self.con2.s.recv(9) self.bytes_read_i = len(self.info_recv) while (self.bytes_read_i < 9): self.info_recv += self.con2.s.recv(9 - self.bytes_read_i) self.bytes_read_i = len(self.info_recv) if (self.info_recv[:4].decode() == "ADRE"): self.num_download = self.info_recv[4:9] print(self.num_download) self.con2.deconnection()
class Ricerca: def __init__(self, sessionid, ipp2p_dir_4, ipp2p_dir_6): self.ipp2p_dir_4 = ipp2p_dir_4 self.ipp2p_dir_6 = ipp2p_dir_6 self.sID = sessionid self.pack = 'FIND' + sessionid self.con = Conn(self.ipp2p_dir_4, self.ipp2p_dir_6, 3000) self.bytes_read = 0 def cerca(self): print('Inserisci una sequenza di caratteri per iniziare la ricerca! ') flag = True while flag: flag = False fileFind = input() # Stringa di ricerca lenFile = len(fileFind) if lenFile == 0: print('Errore, non è stato inserito alcun nominativo file!') flag = True elif lenFile > 20: print( 'Il nome da ricercare è troppo lungo, verranno mantenuti solo i primi 20 caratteri per effettuare la ricerca!' ) fileFind = fileFind[:20] elif lenFile < 20: fileFind += " " * (20 - lenFile) self.pack = self.pack + fileFind print('Ecco il pacchetto pronto da inviare al server: ', self.pack, 'lunghezza totale file: ', len(fileFind)) self.con.connection() self.con.s.send(self.pack.encode('ascii')) msg = self.con.s.recv( 7) # Ricevo identificativo pacchetto e numero di md5 msg = msg.decode() if msg[:4] == 'AFIN': nFile = int(msg[4:]) # Numero di md5 ottenuti if nFile == 0: print('File richiesto non trovato') sleep(3) #self.con.s.recv(1024) # Butto via i dati in eccesso return 0 else: print('errore codice pacchetto') self.con.deconnection() sys.exit(0) self.listPeers = [] for i in range(0, nFile): data = self.con.s.recv( 135) # Ricevo md5, descrizione e numero di copie self.bytes_read = len(data) while (self.bytes_read < 135): data += self.con.s.recv(135 - self.bytes_read) self.bytes_read = len(data) data = data.decode() print(data) self.listPeers.insert( i, [data[:32], data[32:132].strip(), int(data[132:]), []]) for j in range(0, self.listPeers[i] [2]): # Per ogni copia dello specifico file data = self.con.s.recv( 60) # Ricevo IP e porta del prossimo peer data = data.decode() IPv4, IPv6 = data[:55].split('|') self.listPeers[i][3].append([IPv4, IPv6, int(data[55:])]) return 1 def stampaRicerca(self): print('Risultati ricerca:') for index in range(0, len(self.listPeers)): print('\n', index + 1, '- descrizione: ', self.listPeers[index][1]) # Formato listPeers: # 0 1 2 3 # 0 1 2 # [ md5 | nome_file | n_copie [ peer_IPv4 | peer_IPv6 | peer_porta ] ] flag = True while flag: flag = False print('\nIndicare quale si desidera scaricare (0 per annullare):') choice = int(input()) if choice == 0: os.system('clear') flag = False elif not choice in range(1, len(self.listPeers) + 1): print('La risorsa non esiste, ritenta') flag = True else: self.index_md5 = choice for copy in range(len(self.listPeers[choice - 1][3])): print('\n', copy + 1, '- \n\tIPv4P2P: \t', self.listPeers[index][3][copy][0], '\n\tIPv6P2P: \t', self.listPeers[index][3][copy][1], '\n\tPP2P: \t\t', self.listPeers[index][3][copy][2]) #Formattazione IPv4 eliminando gli zeri non necessari self.split_ip = self.listPeers[index][3][copy][0].split(".") self.ipp2p = self.split_ip[0].lstrip( '0') + '.' + self.split_ip[1].lstrip( '0') + '.' + self.split_ip[2].lstrip( '0') + '.' + self.split_ip[3].lstrip('0') self.ipp2p_6 = str( ipaddr.ip_address(self.listPeers[index][3][copy][1])) print(self.ipp2p_6) flag = True while flag: flag = False print( 'Indicare da quale peer scaricare il file selezionato (0 per annullare):' ) choicePeer = int(input()) if choicePeer == 0: print('Abortito') flag = False os.system('clear') elif not choicePeer in range( 1, len(self.listPeers[choice - 1][3]) + 1): print('Il peer non esiste, ritenta') flag = True else: print( self.sID, self.ipp2p, self.ipp2p_6, self.listPeers[self.index_md5 - 1][3][choicePeer - 1][2], self.listPeers[self.index_md5 - 1][0], self.listPeers[self.index_md5 - 1][1], self.ipp2p_dir_4, self.ipp2p_dir_6) down = Download( self.sID, self.ipp2p, self.ipp2p_6, self.listPeers[self.index_md5 - 1][3][choicePeer - 1][2], self.listPeers[self.index_md5 - 1][0], self.listPeers[self.index_md5 - 1][1], self.ipp2p_dir_4, self.ipp2p_dir_6) down.download()
def run(self): Util.w.itemconfig(self.idRect, fill='#0000ff', width=1) jobDone = False for peers in self.listPeers: peer = Util.ip_deformatting(peers[:55],peers[55:]) Util.printLog(str(peer)) c = Conn(peer[0], peer[1], peer[2]) # ipv4 ipv6 port if c.connection(): packet = 'RETP' + self.md5 + str(self.part).zfill(8) # Preparo il pacchetto RETP c.s.send(packet.encode()) # Invio richiesta download # Lettura della risposta nChunk = c.s.recv(10) # 'AREP' + n° chunks readB = len(nChunk) while (readB < 10): nChunk += c.s.recv(10 - readB) readB = len(nChunk) nChunk = int(nChunk[4:].decode()) # Elaborazione dei chunk fileDescriptor = open('Files/' + self.fileName, 'r+b') fileDescriptor.seek(self.lenPart * (self.part - 1)) # Sposto il puntatore nell'area corretta for _ in range(nChunk): # Estrazione lunghezza chunk lenChunk = c.s.recv(5) readB = len(lenChunk) while (readB < 5): lenChunk += c.s.recv(5 - readB) readB = len(lenChunk) lenChunk = int(lenChunk.decode()) # Estrazione dati chunk dataChunk = c.s.recv(lenChunk) readB = len(dataChunk) while (readB < lenChunk): dataChunk += c.s.recv(lenChunk - readB) readB = len(dataChunk) fileDescriptor.write(dataChunk) # Scrivo il chunk su file c.deconnection() jobDone = True break else: Util.printLog('Connessione peer fallita...') if jobDone: # Job completato sleep(uniform(0.2,0.5)) self.wLock.acquire() self.data['downloadedParts'] += 1 self.wLock.release() db = dataBase() track = db.retrieveConfig(('trackerV4','trackerV6','trackerP', 'sessionId')) c = Conn(track.trackerV4, track.trackerV6, track.trackerP) maxNumTracker = 5 for count in range(maxNumTracker): if c.connection(): c.s.send(('RPAD' + track.sessionId + self.md5 + str(self.part).zfill(8)).encode()) apad = c.s.recv(8) readB = len(apad) while(readB < 8): apad += c.s.recv(8 - readB) readB = len(apad) else: Util.printLog('Connessione al tracker fallita...') percent, parts = Util.w.find_withtag(self.tag)[-3:-1] # Terzultimo e penultimo Util.w.itemconfig(percent, text='Progress: \t\t' + '{0:.2f}'.format(self.data['downloadedParts'] / self.data['totalParts'] * 100) + '%') Util.w.itemconfig(parts, text='Downloaded: \t' + str(self.data['downloadedParts'])) Util.w.itemconfig(self.idRect, fill='#00ff00', width=1) else: # Fallita connessione al peer per scaricare la parte Util.w.itemconfig(self.idRect, fill='#ff0000', width=1) self.wLock.acquire() self.missingParts.append(self.part - 1) Util.printLog('job failed for : ' + str(current_thread())) self.wLock.release() self.wLock.acquire() self.data['workers'] -= 1 self.wLock.release() Util.dSem.release()
class ThreadNEAR(th.Thread): def __init__(self, pack, ipv4, ipv6, port, ipRequest, lock, config): th.Thread.__init__(self) self.myIPP = Util.ip_formatting(ipv4, ipv6, port) info = Util.ip_deformatting(pack[20:75], pack[75:80], pack[80:]) self.pack = pack self.pid = pack[4:20] self.ipv4 = info[0] self.ipv6 = info[1] self.port = info[2] self.ttl = info[3] self.ipRequest = ipRequest self.lock = lock self.config = config def run(self): Util.printLog('\n\nApertura thread NEAR\n\n') db = dataBase() self.lock.acquire() res = db.retrivenSearch(self.pid, self.pack[20:75]) if (res == 0): # Richiesta già conosciuta Util.printLog("Eseguo NEAR per: " + self.ipRequest) db.insertRequest(self.pid, self.pack[20:75], time.time()) self.lock.release() if self.ttl > 1: # Inoltro richiesta ai vicini self.ttl = str(self.ttl - 1).zfill(2) self.pack = ''.join((self.pack[:80], self.ttl)) neighborhood = db.retrieveNeighborhood(self.config) for neighbor in neighborhood: params = Util.ip_deformatting(neighbor[0], neighbor[1], None) if params[0] != self.ipRequest and params[ 1] != self.ipRequest and params[0] != self.ipv4: self.con = Conn(params[0], params[1], params[2]) try: self.con.connection() self.con.s.send(self.pack.encode()) self.con.deconnection() Util.printLog("vicino inoltro NEAR: " + params[0]) except IOError as e: print("Inoltro vicino fallito") self.pack = 'ANEA' + self.pid + self.myIPP Util.printLog('ANEA a: ' + str(self.pack)) Util.printLog('ANEA CONN: ' + self.ipv4 + self.ipv6 + str(self.port)) self.con = Conn(self.ipv4, self.ipv6, self.port) #print('Con ANEA ', self.ipv4, self.ipv6, self.port) try: self.con.connection() self.con.s.send(self.pack.encode()) self.con.deconnection() except IOError as e: print("Risposta diretta fallita") else: self.lock.release() Util.printLog("NEAR per: " + self.ipRequest + ". Già eseguita") Util.printLog('\n\nChiusura thread NEAR\n\n')
def run(self): # LOOK ers = [] # Lista per il menù db = dataBase() sessionid = db.retrieveConfig(('sessionId', )) con = Conn(self.t_ipv4, self.t_ipv6, self.t_port) if con.connection(): pkt_look = 'LOOK' + sessionid + self.search.ljust(20) con.s.send(pkt_look.encode()) ack_look = con.s.recv(7) # Ricezione intestazione bytes_read = len(ack_look) while bytes_read < 7: ack_look += con.s.recv(7 - bytes_read) bytes_read = len(ack_look) nanswer = int(ack_look[4:7].decode()) list_answers = [] for _ in range(nanswer): # Per ogni md5 answer = con.s.recv(148) bytes_read = len(answer) while bytes_read < 148: answer += con.s.recv(148 - bytes_read) bytes_read = len(answer) md5_lfile_lpart = (answer[:32].decode(), answer[132:142].decode(), answer[142:148].decode(), answer[32:132].decode().strip()) list_answers.extend( (answer[32:132].decode().strip(), md5_lfile_lpart)) list_answers.extend(("Abort", None)) con.deconnection() Util.searchLock.acquire() Util.activeSearch += 1 Util.searchLock.release() Util.menuLock.acquire() # Menù md5 = curses.wrapper(Util.menu, list_answers, ['Select a file:']) # md5[0] -> md5, md5[1] -> lenFile, md5[2] -> lenPart if md5 != None: if Path('Files/' + md5[3]).is_file(): res = curses.wrapper( Util.menu, ['Yes', True, 'No', False], ['The file requested already exists. Override it?']) if not res: print('Overwrite? Nop') exit() pkt_fchu = "FCHU" + sessionid + md5[0] lenfile = int(md5[1]) lenpart = int(md5[2]) infoFile = md5[3] # Mi tengo solo il nome del file md5 = md5[0] nBit = int(math.ceil(lenfile / lenpart)) Util.printLog(str(len(infoFile))) else: Util.printLog("Download aborted...") Util.menuLock.release() Util.searchLock.acquire() Util.activeSearch -= 1 if Util.activeSearch == 0: Util.searchIncoming.acquire() Util.searchIncoming.notify() Util.searchIncoming.release() Util.searchLock.release() exit() else: Util.printLog("Error. Unable to connect to the tracker") exit() Util.menuLock.release() Util.searchLock.acquire() Util.activeSearch -= 1 if Util.activeSearch == 0: Util.searchIncoming.acquire() Util.searchIncoming.notify() Util.searchIncoming.release() Util.searchLock.release() #FINE LOOK queue = LifoQueue() #Coda LIFO controllerIsAlive = False # Stato del controller di download ######### CREO LA GRAFICA INIZIALE Util.lockGraphics.acquire() rowNumber = len(Util.rows) # Numero di file attualmente visualizzati descriptor = 'File' + str(Util.uniqueIdRow) Util.uniqueIdRow += 1 Util.rows.append( descriptor) # Salvo il tag che identifica il file in download y1 = Util.offsety + Util.nameFileHeight + (Util.heightRow * rowNumber) y2 = y1 + Util.heightPart for i in range(0, nBit): x1 = Util.offsetx + (Util.widthPart * i) x2 = Util.offsetx + (Util.widthPart * (i + 1)) idRec = Util.w.create_rectangle(x1, y1, x2, y2, fill="red", width=1, tags=(descriptor)) # Rettangoli # Ridefinizione delle coordinate basate su quelle precedenti y1 = y1 + Util.heightPart # Coordinata Y in alto y2 = y2 + Util.heightLine # Coordinata Y in basso for i in range(0, nBit, 10): x = Util.offsetx + Util.widthPart * i Util.w.create_line(x, y1, x, y2, tags=(descriptor)) Util.w.create_text(x + Util.LeftPaddingText, y2, anchor="sw", text=str(i + 1), tags=(descriptor)) # Labels Util.w.create_text(Util.offsetx, Util.offsety + (Util.heightRow * rowNumber), anchor="nw", text=infoFile, tags=(descriptor)) # Nome file dCond = Condition() # Condizione per fermare il download # Bottoni #image = Image.open("mazzini.jpeg").resize((20,20), Image.ANTIALIAS) b = Button(Util.master, height='10', width='10', image=Util.pause) #b.pack() b['command'] = lambda: pauseAndplay(b, dCond, queue) b.place(x=0, y=Util.offsety + (Util.heightRow * rowNumber)) b2 = Button(Util.master, height='10', width='10', image=Util.stop) #b2.pack(ipadx=20, ipady=Util.offsety + (Util.heightRow * rowNumber)) b2['command'] = lambda: stop(dCond, queue) b2.place(x=20, y=Util.offsety + (Util.heightRow * rowNumber)) Util.buttonsList.append([b, b2]) # Statistiche Util.w.create_text(Util.labelOffsetx, Util.labelDistance + Util.offsety + (Util.heightRow * rowNumber), anchor="nw", text='Progress: \t\t0%', tags=(descriptor)) # Nome file Util.w.create_text(Util.labelOffsetx, (Util.labelDistance * 2) + Util.offsety + (Util.heightRow * rowNumber), anchor="nw", text='Downloaded: \t0', tags=(descriptor)) # Nome file Util.w.create_text(Util.labelOffsetx, (Util.labelDistance * 3) + Util.offsety + (Util.heightRow * rowNumber), anchor="nw", text='Total: \t\t' + str(nBit), tags=(descriptor)) # Nome file Util.lockGraphics.release() ######### # Risposta di FCHU while True: c = Conn(self.t_ipv4, self.t_ipv6, self.t_port) if not c.connection(): Util.printLog('Connection Error...') else: c.s.send(pkt_fchu.encode()) hitPeers = c.s.recv(7) # Intestazione pacchetto AFCH readB = len(hitPeers) listPeers = [] # Tutti i peer listStatus = [] while (readB < 7): hitPeers += c.s.recv(7 - readB) readB = len(hitPeers) nBlock = math.ceil(nBit / 8) nPeers = int(hitPeers[4:7].decode()) toReadB = 60 + nBlock # Ip + stato if nPeers == 0: Util.printLog('No peer found...') exit() for peer in range(nPeers): # Per ogni peer infoPeer = c.s.recv(toReadB) readB = len(infoPeer) while (readB < toReadB): infoPeer += c.s.recv(toReadB - readB) readB = len(infoPeer) listPeers.append(infoPeer[:60].decode()) # Peer listStatus.append(list(infoPeer[60:])) # Stato c.deconnection() # Creazione di una lista di parti pesata statusParts = [] # Lista dello stato delle parti for i in range(nBit): statusParts.append([i, 0, []]) # Parte, peso, ip for peer in range(nPeers): for block in range(nBlock): bit8 = listStatus[peer][block] # Isolo il blocco while bit8 > 0: maxBit = 7 - int(log( bit8, 2)) # Indice del più alto bit impostato ad 1 offset = 8 * block statusParts[maxBit + offset][1] += 1 # Aumento il peso statusParts[maxBit + offset][2].append( listPeers[peer]) # Inserisco l'ip bit8 = bit8 ^ (1 << (7 - maxBit) ) # Elimino il bit utilizzato shuffle( statusParts ) # Mescolo la lista (scelta random delle parti col medesimo peso) statusParts = [ [part[0], part[2]] for part in sorted(statusParts, key=itemgetter(1)) ] # Riordino della lista dalla parte più rara (rarest first) if not controllerIsAlive: Util.printLog('DOWNLOAD ATTIVATO') controllerIsAlive = True idPartOne = idRec - (nBit - 1) # Id del primo rettagolo t = D(statusParts, queue, descriptor, idPartOne, infoFile, lenpart, md5, dCond, b, b2) t.start() else: if t.is_alive(): queue.put(statusParts) else: print('Terminato') exit() sleep(60)
class Peer: def __init__(self, ipp2p_dir_v4, ipp2p_dir_v6, my_ipv4, my_ipv6, pp2p_bf): self.ip_dir_4 = ipp2p_dir_v4 self.ip_dir_6 = ipp2p_dir_v6 self.dir_port = 3000 self.my_ipv4 = my_ipv4 self.my_ipv6 = my_ipv6 self.pp2p_bf = pp2p_bf self.con = Conn(self.ip_dir_4, self.ip_dir_6, self.dir_port) def login(self): print("\n--- LOGIN ---\n") try: self.con.connection() except IOError as expt: print("Errore di connessione") print(expt) sys.exit(0) # self.ipp2p_bf = self.s.getsockname()[0] #ip peer bad formatted # formattazione ipv4 self.split_ip_4 = self.my_ipv4.split(".") ip1_4 = self.split_ip_4[0].zfill(3) ip2_4 = self.split_ip_4[1].zfill(3) ip3_4 = self.split_ip_4[2].zfill(3) ip4_4 = self.split_ip_4[3].zfill(3) # formattazione ipv6 self.split_ip_6 = self.my_ipv6.split(":") ip1_6 = self.split_ip_6[0].zfill(4) ip2_6 = self.split_ip_6[1].zfill(4) ip3_6 = self.split_ip_6[2].zfill(4) ip4_6 = self.split_ip_6[3].zfill(4) ip5_6 = self.split_ip_6[4].zfill(4) ip6_6 = self.split_ip_6[5].zfill(4) ip7_6 = self.split_ip_6[6].zfill(4) ip8_6 = self.split_ip_6[7].zfill(4) self.ipp2p = ip1_4 + '.' + ip2_4 + '.' + ip3_4 + '.' + ip4_4 + '|' + ip1_6 + ':' + ip2_6 + ':' + ip3_6 + ':' + ip4_6 + ':' + ip5_6 + ':' + ip6_6 + ':' + ip7_6 + ':' + ip8_6 # formattazione porta self.pp2p = '%(#)05d' % {"#": int(self.pp2p_bf)} data_login = "******" + self.ipp2p + self.pp2p self.con.s.send(data_login.encode('ascii')) self.ack_login = self.con.s.recv(20) # 4B di ALGI + 16B di SID bytes_read = len(self.ack_login) while(bytes_read < 20): self.ack_login += self.s.recv(20 - self.bytes_read) self.bytes_read += len(self.ack_login) print("Ip peer ---> " + str(self.ipp2p)) print("Port peer ---> " + str(self.pp2p)) if (self.ack_login[:4].decode() == "ALGI"): self.sid = self.ack_login[4:20] if (self.sid == '0000000000000000'): print("Errore durante il login\n") exit() else: print("Session ID ---> " + str(self.sid.decode()) + "\n") else: print("Errore del pacchetto, string 'ALGI' non trovata") self.con.deconnection() exit() self.con.deconnection() return self.sid def logout(self, sid): print("\n--- LOGOUT ---\n") self.con.connection() data_logout = "LOGO" + sid.decode() self.con.s.send(data_logout.encode('ascii')) self.ack_logout = self.con.s.recv(7) self.bytes_read = len(self.ack_logout) while(self.bytes_read < 7): self.ack_logout += self.con.s.recv(7 - self.bytes_read) self.bytes_read = len(self.ack_logout) print("First 4 byte from dir----> " + str(self.ack_logout[:4].decode())) if (self.ack_logout[:4].decode() == "ALGO"): print("Numero di file eliminati ---> " + str(self.ack_logout[4:7].decode())) self.con.deconnection()
class Download: def __init__(self, ipp2p_B_4, ipp2p_B_6, pp2p_B, md5, filename): #ip other peer self.ipp2p_B_4 = ipp2p_B_4 self.ipp2p_B_6 = ipp2p_B_6 self.pp2p_B = pp2p_B #file self.md5 = md5 self.filename = filename #chunk veriables self.data_recv = [] #var for bytes controller self.bytes_read_f = 0 self.bytes_read_l = 0 self.bytes_read = 0 self.bytes_read_i = 0 def download(self): print("\n--- DOWNLOAD ---\n") self.con = Conn(self.ipp2p_B_4, self.ipp2p_B_6, int(self.pp2p_B)) self.con.connection() to_peer = "RETR" + self.md5 self.con.s.send(to_peer.encode('ascii')) self.first_packet = self.con.s.recv(10) self.bytes_read_f = len(self.first_packet) while (self.bytes_read_f < 10): self.first_packet += self.con.s.recv(10 - self.bytes_read_f) self.bytes_read_f = len(self.first_packet) if (self.first_packet[:4].decode() == "ARET"): i = self.first_packet[4:10].decode( ) # n di chunk o indice del ciclo for for j in range(int(i)): self.chunk_length = self.con.s.recv( 5) # lunghezza del primo chunk self.bytes_read_l = len(self.chunk_length) while ( self.bytes_read_l < 5 ): # controllo che siano stati realmente letti i bytes richiesti self.chunk_length += self.con.s.recv(5 - self.bytes_read_l) self.bytes_read_l = len(self.chunk_length) self.chunk = self.con.s.recv(int(self.chunk_length)) # dati #self.data_recv.append(self.chunk) self.bytes_read = len(self.chunk) while ( self.bytes_read < int(self.chunk_length) ): # controllo che siano stati realmente letti i bytes richiesti self.chunk += self.con.s.recv( int(self.chunk_length) - self.bytes_read) self.bytes_read = len(self.chunk) #self.data_recv.append(buffer) self.data_recv.append(self.chunk) self.con.deconnection() path_file = "img/" + self.filename check_file = Path(path_file) if (check_file.is_file()): res = wrapper(Util.menu, ['Yes', True, 'No', False], ['The file requested already exists. Override it?']) if res: os.remove(path_file) file_recv = open(path_file, "ab") for i in self.data_recv: file_recv.write(i) file_recv.close() else: return ''' choice_file = input("\nIl file esiste già nel tuo file system, vuoi sovrascriverlo? (Y,n): ") if(choice_file == "Y"): os.remove(path_file) file_recv = open(path_file, "ab") for i in self.data_recv: file_recv.write(i) file_recv.close() else: return ''' else: file_recv = open(path_file, "ab") for i in self.data_recv: file_recv.write(i) file_recv.close() Util.waitMenu.acquire() Util.waitMenu.notify() Util.waitMenu.release()
def run(self): db = dataBase() file_find = [] #ricavo i superpeer a cui sono collegato e inoltro la richiesta nella rete superpeers = db.retrieveSuperPeers() config = db.retrieveConfig(('selfV4', 'selfV6')) Util.globalLock.acquire() Util.statusRequest[self.packet[4:20]] = True Util.printLog("DIZIONARIO GLOBALE SETTATO ---> " + str(Util.statusRequest[self.packet[4:20]])) Util.globalLock.release() if (superpeers): for sp in superpeers: ipv4, ipv6, port = Util.ip_deformatting(sp[0], sp[1]) if (ipv4 != config.selfV4): conn = Conn(ipv4, ipv6, port) if (conn.connection()): conn.s.send(self.packet.encode()) conn.deconnection() Util.printLog("INVIO QUER VERSO " + str(ipv4) + " RIUSCITO") else: Util.printLog( "INVIO QUER FALLITO VERSO IL SUPER... PROBABILMENTE " + str(ipv4) + " E' OFFLINE") continue cond = th.Condition() cond.acquire() cond.wait(20) cond.release() Util.globalLock.acquire() Util.statusRequest[self.packet[4:20]] = False Util.printLog("PASSATI 20 SECONDI.. DIZIONARIO ---> " + str(Util.statusRequest[self.packet[4:20]])) Util.globalLock.release() #controllo tra i peer loggati a me prima di inoltrare la quer nella rete dbS = dataBaseSuper() localFile = dbS.findInLocalSP(self.packet[82:]) Util.printLog("LOCALFILE " + str(localFile)) #creazione pacchetto di AFIN passati i 20 secondi addrPeer = db.retrievePeerSid(self.sid) Util.printLog("ADDRPEER " + str(addrPeer)) resp = db.retrieveResponse(self.packet[4:20]) ipv4, ipv6, port = Util.ip_deformatting(addrPeer[0][0], addrPeer[0][1]) for f in resp: file_find.append(f[3]) for ff in localFile: file_find.append(ff[1]) seen = set() uniq = [] for x in file_find: if x not in seen: uniq.append(x) seen.add(x) toPeer = "AFIN" + str(len(seen)).zfill(3) connP = Conn(ipv4, ipv6, port) if (connP.connection()): connP.s.send(toPeer.encode()) buffer_md5 = '' for i in resp: count = 0 ll = [] md5 = i[3] if (md5 == buffer_md5): continue for j in resp: if (md5 in j): count = count + 1 add = j[1] + j[2] ll.append(add) if (count == 1): toPeer = md5 + i[4] + str(count).zfill(3) + i[1] + i[2] connP.s.send(toPeer.encode()) Util.printLog("PACCHETTO AFIN 1-----> " + str(toPeer)) elif (count > 1): buffer_md5 = md5 toPeer = md5 + i[4] + str(count) for l in ll: toPeer = toPeer + l connP.s.send(toPeer.encode()) Util.printLog("PACCHETTO AFIN 2+-----> " + str(toPeer)) buffer_md5_l = '' if (localFile): # se la lista non è vuota entro nel ciclo k = 0 for lf in localFile: count = 0 ll2 = [] md5 = lf[1] Util.printLog("localfile in for " + str(lf)) addrLocalPeer = db.retrievePeerSid(lf[0]) if (md5 == buffer_md5_l): continue for j in localFile: if (md5 in j): addrLocalPeer_dub = db.retrievePeerSid(j[0]) count = count + 1 add = addrLocalPeer_dub[0][0] + addrLocalPeer_dub[0][1] ll2.append(add) Util.printLog("addrLocalPeer " + str(addrLocalPeer)) if (count == 1): toPeer = lf[1] + lf[2] + str(1).zfill( 3) + addrLocalPeer[0][0] + addrLocalPeer[0][1] k = k + 1 connP.s.send(toPeer.encode()) Util.printLog("PACCHETTO AFIN 1 LOCAL-----> " + str(toPeer)) elif (count > 1): buffer_md5_l = md5 toPeer = lf[1] + lf[2] + str(count).zfill(3) for l2 in ll2: toPeer = toPeer + l2 connP.s.send(toPeer.encode()) Util.printLog("PACCHETTO AFIN 1+ LOCAL-----> " + str(toPeer)) connP.deconnection()
class ThreadQUER(th.Thread): def __init__(self, my_door, quer_pkt, ip_request, ipv4, ipv6, lock, config, up_port): th.Thread.__init__(self) self.my_door = int(my_door) self.bytes_read = 0 self.from_peer = quer_pkt self.ip_request = ip_request self.ipv4 = ipv4 self.ipv6 = ipv6 self.lock = lock self.config = config self.new_port = up_port #insersce un nuovo record nella lista dei packet id def remove_record(self, pktid_dict, key): del pktid_dict[str(key)] Util.printLog(pktid_dict[str(key)]) return pktid_dict #rimuove un record dalla lista dei packet id def insert_record(self, pktid_dict, key): pktid_dict[str(key)] = datetime.datetime.fromtimestamp(time.time()) Util.printLog(pktid_dict[str(key)]) return pktid_dict #calcolo l'md5 dei file della ricerca def convert_md5(self, file_list): dict_list = {} index = 0 for file in file_list: #index = ra.randint(50000, 59999) open_file = open('img/'+file, 'rb') contenuto = open_file.read() FileHash = hashlib.md5() FileHash.update(contenuto) dict_list[index] = FileHash.hexdigest()+file #il file File_System viene utilizzato come appoggio alla funzione di upload file_write = File_system(FileHash.hexdigest(), file) file_write.write() open_file.close() index = index +1 return dict_list #risponde al peer che ha effettuato una ricerca, incompleta def answer(self, file_list, pktid, ip, my_ipv4, my_ipv6, my_port, portB): dict_list = self.convert_md5(file_list) #stabilisco una connessione con il peer che ha iniziato addr = Util.ip_deformatting(ip, portB, None) ip6 = ipad.ip_address(ip[16:]) self.con = Conn(addr[0], str(ip6), addr[2]) my_ip_port = Util.ip_formatting(my_ipv4, my_ipv6, my_port) try: self.con.connection() for index in dict_list: md5_file_name = dict_list[index].ljust(132,' ') answer = "AQUE"+pktid+my_ip_port+md5_file_name #print(answer) self.con.s.send(answer.encode()) Util.printLog(answer) #print(str(answer.encode())+"\n") #print(str(len(answer.encode()))+"\n") self.con.deconnection() except IOError as expt: print("Errore di connessione") print(expt) sys.exit(0) Util.printLog('QUER:fine answer') #ricerca dei vicini def search_neighbors(self, db, ip_request, new_quer): self.neighbors = db.retrieveNeighborhood(self.config) #mi tiro giù i vicini Util.printLog("------------------------- Sono tornato nel threadQuer ------------------------") for n in self.neighbors: addr = Util.ip_deformatting(n[0], n[1], None) Util.printLog("------------- Dentro al for di threadQUER -----------------------") #ip4 = ipad.ip_address(n[0][:15]) ip6 = ipad.ip_address(n[0][16:]) self.con = Conn(addr[0], str(ip6), addr[2]) try: Util.printLog("-----------------Dentro alla connection threadQUER --------------") if((addr[0] != ip_request) and (str(ip6) != ip_request) and (new_quer[20:35] != addr[0])): self.con.connection() self.con.s.send(new_quer.encode()) Util.printLog('QUER: inoltro richiesta a : ' + str(addr[0])) self.con.deconnection() #Util.printLog(str(addr[0])) Util.printLog('QUER:deconection neighbors') except IOError as expt: print("Errore di connessione") print(expt) sys.exit(0) Util.printLog('QUER:fine neighbors') #vado a calcolare il nuovo ttl def new_ttl(self, ttl): new_ttl = ttl - 1 if(new_ttl>9): c = str(new_ttl) else: c = str(new_ttl).rjust(2, '0') return c #funzione principale def run(self): self.pktid = self.from_peer[4:20] self.ip = self.from_peer[20:75] self.door = self.from_peer[75:80] self.ttl = int(self.from_peer[80:82]) self.string = self.from_peer[82:].rstrip() db = dataBase() self.lock.acquire() res = db.retrivenSearch(self.pktid, self.ip) #self.my_ip = str(self.ipv4)+"|"+str(self.ipv6) Util.printLog('Avvio il thread QUER') if(res == 0): file_found = [] self.timestamp = time.time() db.insertSearch(self.pktid, self.ip, self.timestamp) self.lock.release() for file in os.listdir("img"): if re.search(self.string, file, re.IGNORECASE): file_found.append(file) if(len(file_found) != 0): #rispondo self.answer(file_found, self.pktid, self.ip, self.ipv4, self.ipv6, str(self.new_port), self.door) if(self.ttl>1): Util.printLog("QUER: eseguo l'inoltro ai vicini della richiesta\n") #vado a decrementare il ttl di uno e costruisco la nuova query da inviare ai vicini self.ttl_new = self.new_ttl(self.ttl) self.new_quer = "QUER"+self.pktid+self.ip+self.door+self.ttl_new+self.from_peer[82:] self.lock.acquire() self.search_neighbors(db, self.ip_request, self.new_quer) self.lock.release() del db else: Util.printLog("QUER: già presente un pacchetto con questo pktid\n") before = db.retriveSearch(self.pktid, self.ip) self.lock.release() now = time.time() if((now - before) < 20): Util.printLog('QUER: non faccio nulla perchè ho già elaborato la richiesta\n') del db else: file_found = [] self.timestamp = time.time() self.lock.acquire() db.updateTimestamp(self.pktid, self.ip) self.lock.release() for file in os.listdir("img"): if re.search(self.string, file, re.IGNORECASE): file_found.append(file) if(len(file_found) != 0): #rispondo e apro l'upload self.answer(file_found, self.pktid, self.ip, self.ipv4, self.ipv6, str(self.new_port), self.door) if(self.ttl>1): Util.printLog("QUER: eseguo l'inoltro ai vicini della richiesta 2\n") #vado a decrementare il ttl di uno e costruisco la nuova query da inviare ai vicini self.ttl_new = self.new_ttl(self.ttl) self.new_quer = "QUER"+self.pktid+self.ip+self.door+self.ttl_new+self.from_peer[82:] self.lock.acquire() self.search_neighbors(db, self.ip_request, self.new_quer) self.lock.release() del db Util.printLog('QUER: ultima riga\n')
class ThreadQUER(th.Thread): def __init__(self, quer_pkt, ip_request): th.Thread.__init__(self) self.from_peer = quer_pkt self.ip_request = ip_request #risponde al superpeer che ha effettuato una ricerca def answer(self, db, file_list, pktid, ip, portB): addr = Util.ip_deformatting(ip, portB) ip6 = ipad.ip_address(ip[16:]) Util.printLog("PARAMETRI VARI PER L'AQUE ========> " + str(addr[0]) + " " + str(str(ip6)) + " " + str(addr[2])) self.con = Conn(addr[0], str(ip6), addr[2]) if (self.con.connection()): for file in file_list: peer_info = db.retrieveLOGIN(file[0]) answer = "AQUE" + pktid + peer_info[0] + peer_info[1] + file[ 1] + file[2] Util.printLog("AQUE REINVIATO :::: " + str(answer)) self.con.s.send(answer.encode()) Util.printLog(answer) self.con.deconnection() else: Util.printLog("[AQUE] Errore invio risposta al peer " + addr[0]) #ricerca dei vicini def search_neighbors(self, db, ip_request, new_quer): self.neighbors = db.retrieveSuperPeers() #mi tiro giù i vicini super for n in self.neighbors: addr = Util.ip_deformatting(n[0], n[1]) ip6 = ipad.ip_address(n[0][16:]) self.con = Conn(addr[0], str(ip6), addr[2]) if ((addr[0] != ip_request) and (str(ip6) != ip_request) and (new_quer[20:35] != addr[0])): if (self.con.connection()): self.con.s.send(new_quer.encode()) Util.printLog(new_quer) self.con.deconnection() else: Util.printLog("[QUER] Errore inoltro al superpeer " + addr[0]) #vado a calcolare il nuovo ttl def new_ttl(self, ttl): new_ttl = ttl - 1 if (new_ttl > 9): c = str(new_ttl) else: c = str(new_ttl).rjust(2, '0') return c #funzione principale def do(self, db, pktid, ip, timestamp, lock, string, peer_port, ttl, last_part_pkt, ip_request): lock.acquire() file_found = db.searchFILEquer(string) lock.release() if (file_found): #rispondo Util.printLog("INVIO L'AQUE --------> " + str(file_found)) Util.printLog("ADDR INVIO AQUE ------> " + str(ip) + " " + str(peer_port)) self.answer(db, file_found, pktid, ip, peer_port) if (ttl > 1): Util.printLog("[QUER]: eseguo l'inoltro ai vicini della richiesta") #vado a decrementare il ttl di uno e costruisco la nuova query da inviare ai vicini self.ttl_new = self.new_ttl(ttl) self.new_quer = "QUER" + pktid + ip + peer_port + self.ttl_new + last_part_pkt lock.acquire() self.search_neighbors(db, ip_request, self.new_quer) lock.release() del db def run(self): self.pktid = self.from_peer[4:20] self.ip = self.from_peer[20:75] self.peer_port = self.from_peer[75:80] self.ttl = int(self.from_peer[80:82]) self.string = self.from_peer[82:].strip() db = dataBaseSuper() Util.lock.acquire() res = db.retrieveCounterRequest(self.pktid, self.ip) Util.printLog("THREADQUER DI RES ----------_> " + str(res)) if (res == 0): self.timestamp = time.time() db.insertRequest(self.pktid, self.ip, self.timestamp) Util.lock.release() self.do(db, self.pktid, self.ip, self.timestamp, Util.lock, self.string, self.peer_port, self.ttl, self.from_peer[82:], self.ip_request) else: before = db.retrieveRequestTimestamp(self.pktid, self.ip) Util.lock.release() now = time.time() if ((now - before) < 20): Util.printLog( '[QUER]: non faccio nulla perchè ho già elaborato la richiesta\n' ) del db else: self.timestamp = time.time() Util.lock.acquire() db.updateTimestamp(self.pktid, self.ip) Util.lock.release() self.do(db, self.pktid, self.ip, self.timestamp, Util.lock, self.string, self.peer_port, self.ttl, self.from_peer[82:], self.ip_request)