def SendSingleCustomer(idurl, response_callback=None): dhnio.Dprint(6, "identitypropagate.SendSingleCustomer [%s]" % nameurl.GetName(idurl)) MyID = misc.getLocalID() packet = dhnpacket.dhnpacket(commands.Identity(), MyID, MyID, MyID, misc.getLocalIdentity().serialize(), idurl) transport_control.outboxNoAck(packet) if response_callback is not None: transport_control.RegisterInterest(response_callback, packet.RemoteID, packet.PacketID)
def RequestIdentity(request): dhnio.Dprint(6, "p2p_service.RequestIdentity starting") MyID = misc.getLocalID() RemoteID = request.OwnerID PacketID = request.PacketID identitystr = misc.getLocalIdentity().serialize() dhnio.Dprint(12, "p2p_service.RequestIdentity returning ") result = dhnpacket.dhnpacket(commands.Identity(), MyID, MyID, PacketID, identitystr, RemoteID) transport_control.outboxNoAck(result)
def RequestListFiles(supplierNumORidurl): if isinstance(supplierNumORidurl, str): RemoteID = supplierNumORidurl else: RemoteID = contacts.getSupplierID(supplierNumORidurl) if not RemoteID: dhnio.Dprint(4, "p2p_service.RequestListFiles WARNING RemoteID is empty supplierNumORidurl=%s" % str(supplierNumORidurl)) return dhnio.Dprint(8, "p2p_service.RequestListFiles [%s]" % nameurl.GetName(RemoteID)) MyID = misc.getLocalID() PacketID = packetid.UniqueID() Payload = settings.ListFilesFormat() result = dhnpacket.dhnpacket(commands.ListFiles(), MyID, MyID, PacketID, Payload, RemoteID) transport_control.outboxNoAck(result) return PacketID
def RunRequest(self): #dhnio.Dprint(6, 'io_throttle.RunRequest') packetsToRemove = set() for i in range(0, min(self.fileRequestMaxLength, len(self.fileRequestQueue))): packetID = self.fileRequestQueue[i] currentTime = time.time() if self.fileRequestDict[packetID].requestTime is not None: # the packet were requested if self.fileRequestDict[packetID].fileReceivedTime is None: # but no answer yet ... if currentTime - self.fileRequestDict[packetID].requestTime > self.fileRequestDict[packetID].requestTimeout: # and time is out!!! self.fileRequestDict[packetID].report = 'timeout' packetsToRemove.add(packetID) else: # the packet were received (why it is not removed from the queue yet ???) self.fileRequestDict[packetID].result = 'received' packetsToRemove.add(packetID) if self.fileRequestDict[packetID].requestTime is None: if not os.path.exists(os.path.join(settings.getLocalBackupsDir(), packetID)): fileRequest = self.fileRequestDict[packetID] dhnio.Dprint(10, "io_throttle.RunRequest for packetID " + fileRequest.packetID) transport_control.RegisterInterest( self.DataReceived, fileRequest.creatorID, fileRequest.packetID) newpacket = dhnpacket.dhnpacket( commands.Retrieve(), fileRequest.ownerID, fileRequest.creatorID, fileRequest.packetID, "", fileRequest.remoteID) transport_control.outboxNoAck(newpacket) fileRequest.requestTime = time.time() else: # we have the data file, no need to request it self.fileRequestDict[packetID].result = 'exist' packetsToRemove.add(packetID) # remember requests results result = len(packetsToRemove) # remove finished requests if len(packetsToRemove) > 0: for packetID in packetsToRemove: self.fileRequestQueue.remove(packetID) del packetsToRemove return result
def ListFiles(request): MyID = misc.getLocalID() RemoteID = request.OwnerID PacketID = request.PacketID Payload = request.Payload dhnio.Dprint(8, "p2p_service.ListFiles from [%s], format is %s" % (nameurl.GetName(request.OwnerID), Payload)) custdir = settings.getCustomersFilesDir() ownerdir = os.path.join(custdir, nameurl.UrlFilename(request.OwnerID)) if not os.path.isdir(ownerdir): dhnio.Dprint(8, "p2p_service.ListFiles did not find customer dir " + ownerdir) src = PackListFiles('', Payload) result = dhnpacket.dhnpacket(commands.Files(), MyID, MyID, PacketID, src, RemoteID) transport_control.outboxNoAck(result) return plaintext = TreeSummary(ownerdir) src = PackListFiles(plaintext, Payload) outpacket = dhnpacket.dhnpacket(commands.Files(), MyID, MyID, PacketID, src, RemoteID) transport_control.outboxNoAck(outpacket)
def SendToIDs(idlist, AckHandler=None, wide=False): dhnio.Dprint(8, "identitypropagate.SendToIDs to %d users" % len(idlist)) MyID = misc.getLocalID() PacketID = MyID LocalIdentity = misc.getLocalIdentity() Payload = LocalIdentity.serialize() Hash = dhncrypto.Hash(Payload) alreadysent = set() for contact in idlist: if not contact: continue if contact in alreadysent: # just want to send once even if both customer and supplier continue found_previous_packets = 0 for transfer_id in transport_control.transfers_by_idurl(contact): ti = transport_control.transfer_by_id(transfer_id) if ti and ti.description.count('Identity'): found_previous_packets += 1 break if found_previous_packets >= 3: dhnio.Dprint(8, ' skip sending to %s' % contact) continue packet = dhnpacket.dhnpacket( commands.Identity(), misc.getLocalID(), #MyID, misc.getLocalID(), #MyID, misc.getLocalID(), #PacketID, Payload, contact) dhnio.Dprint(8, " sending [Identity] to %s" % nameurl.GetName(contact)) if AckHandler is not None: transport_control.RegisterInterest(AckHandler, packet.RemoteID, packet.PacketID) transport_control.outboxNoAck(packet, wide) if wide: # this is a ping packet - need to clear old info transport_control.ErasePeerProtosStates(contact) transport_control.EraseMyProtosStates(contact) alreadysent.add(contact) del alreadysent
def Retrieve(request): filename = makeFilename(request.OwnerID, request.PacketID) if filename == '': dhnio.Dprint(4, "p2p_service.Retrieve WARNING had unknown customer " + request.OwnerID) transport_control.SendFail(request, 'empty filename, not a customer?') return if not os.path.exists(filename): dhnio.Dprint(4, "p2p_service.Retrieve WARNING did not find requested packet " + filename) # transport_control.outboxNoAck(dhnpacket.dhnpacket(commands.Fail(), request.OwnerID, misc.getLocalID(), request.PacketID, 'did not find requested packet', request.CreatorID)) transport_control.SendFail(request, 'did not find requested packet') return if not os.access(filename, os.R_OK): dhnio.Dprint(4, "p2p_service.Retrieve WARNING no read access to requested packet " + filename) # transport_control.outboxNoAck(dhnpacket.dhnpacket(commands.Fail(), request.OwnerID, misc.getLocalID(), request.PacketID, 'no read access to requested packet', request.CreatorID)) transport_control.SendFail(request, 'no read access to requested packet') return data = dhnio.ReadBinaryFile(filename) if not data: dhnio.Dprint(4, "p2p_service.Retrieve WARNING empty data on disk " + filename) # transport_control.outboxNoAck(dhnpacket.dhnpacket(commands.Fail(), request.OwnerID, misc.getLocalID(), request.PacketID, 'empty data on disk', request.CreatorID)) transport_control.SendFail(request, 'empty data on disk') return packet = dhnpacket.Unserialize(data) del data if packet is None: dhnio.Dprint(4, "p2p_service.Retrieve WARNING Unserialize fails, not Valid packet " + filename) # transport_control.outboxNoAck(dhnpacket.dhnpacket(commands.Fail(), request.OwnerID, misc.getLocalID(), request.PacketID, 'unserialize fails', request.CreatorID)) transport_control.SendFail(request, 'unserialize fails') return if not packet.Valid(): dhnio.Dprint(4, "p2p_service.Retrieve WARNING unserialized packet is not Valid " + filename) # transport_control.outboxNoAck(dhnpacket.dhnpacket(commands.Fail(), request.OwnerID, misc.getLocalID(), request.PacketID, 'unserialized packet is not Valid', request.CreatorID)) transport_control.SendFail(request, 'unserialized packet is not Valid') return dhnio.Dprint(6, "p2p_service.Retrieve sending [%s] back to %s" % (packet.PacketID, nameurl.GetName(packet.CreatorID))) transport_control.outboxNoAck(packet)
def RunSend(self): if self._runSend: return self._runSend = True #dhnio.Dprint(6, 'io_throttle.RunSend') packetsFialed = {} packetsToRemove = set() packetsSent = 0 # let's check all packets in the queue for i in xrange(len(self.fileSendQueue)): packetID = self.fileSendQueue[i] fileToSend = self.fileSendDict[packetID] # we got notify that this packet was failed to send if packetID in self.sendFailedPacketIDs: self.sendFailedPacketIDs.remove(packetID) packetsFialed[packetID] = 'failed' continue # we already sent the file if fileToSend.sendTime is not None: packetsSent += 1 # and we got ack if fileToSend.ackTime is not None: # deltaTime = fileToSend.ackTime - fileToSend.sendTime # so remove it from queue packetsToRemove.add(packetID) # if we do not get an ack ... else: # ... we do not want to wait to long if time.time() - fileToSend.sendTime > fileToSend.sendTimeout: # so this packet is failed because no response on it packetsFialed[packetID] = 'timeout' # we sent this packet already - check next one continue # the data file to send no longer exists - it is failed situation if not os.path.exists(fileToSend.fileName): dhnio.Dprint(4, "io_throttle.RunSend WARNING file %s not exist" % (fileToSend.fileName)) packetsFialed[packetID] = 'not exist' continue # do not send too many packets, need to wait for ack # hold other packets in the queue and may be send next time if packetsSent > self.fileSendMaxLength: # if we sending big file - we want to wait # other packets must go without waiting in the queue # 10K seems fine, because we need to filter only Data and Parity packets here try: if os.path.getsize(fileToSend.fileName) > 1024 * 10: continue except: dhnio.DprintException() continue # prepare the packet dt = time.time() Payload = str(dhnio.ReadBinaryFile(fileToSend.fileName)) newpacket = dhnpacket.dhnpacket( commands.Data(), fileToSend.ownerID, self.creatorID, fileToSend.packetID, Payload, fileToSend.remoteID) # outbox will not resend, because no ACK, just data, # need to handle resends on own transport_control.outboxNoAck(newpacket) transport_control.RegisterInterest( self.FileSendAck, fileToSend.remoteID, fileToSend.packetID) dhnio.Dprint(12, 'io_throttle.RunSend %s to %s, dt=%s' % ( str(newpacket), nameurl.GetName(fileToSend.remoteID), str(time.time()-dt))) # mark file as been sent fileToSend.sendTime = time.time() packetsSent += 1 # process failed packets for packetID, why in packetsFialed.items(): self.FileSendFailed(self.fileSendDict[packetID].remoteID, packetID, why) packetsToRemove.add(packetID) # remove finished packets for packetID in packetsToRemove: self.fileSendQueue.remove(packetID) del self.fileSendDict[packetID] # if sending queue is empty - remove all records about packets failed to send if len(self.fileSendQueue) == 0: del self.sendFailedPacketIDs[:] # remember results result = max(len(packetsToRemove), packetsSent) # erase temp lists del packetsFialed del packetsToRemove self._runSend = False return result