private boolean addInternal(RemoteFileDesc host) { // initialize the sha1 if we don't have one if (sha1 == null) { if (host.getSHA1Urn() != null) sha1 = host.getSHA1Urn(); else // BUGFIX: We can't discard sources w/out a SHA1 when we dont' have // a SHA1 for the download, or else it won't be possible to download a // file from a query hit without a SHA1, if we can received UDP pings return testedLocations.add(host); // we can't do anything yet } // do not allow duplicate hosts if (running && knowsAboutHost(host)) return false; if (LOG.isDebugEnabled()) LOG.debug("adding new host " + host + " " + host.getPushAddr()); boolean ret = false; // don't bother ranking multicasts if (host.isReplyToMulticast()) ret = verifiedHosts.add(host); else ret = newHosts.add(host); // rank // make sure that if we were stopped, we return true ret = ret | !running; // initialize the guid if we don't have one if (myGUID == null && meshHandler != null) { myGUID = new GUID(GUID.makeGuid()); RouterService.getMessageRouter().registerMessageListener(myGUID.bytes(), this); } return ret; }
/* * Returns true if both rfd "have the same content". Currently * rfd1~=rfd2 iff either of the following conditions hold: * * <ul> * <li>Both files have the same hash, i.e., * rfd1.getSHA1Urn().equals(rfd2.getSHA1Urn(). Note that this (almost) * always means that rfd1.getSize()==rfd2.getSize(), though rfd1 and * rfd2 may have different names. * <li>Both files have the same name and size and don't have conflicting * hashes, i.e., rfd1.getName().equals(rfd2.getName()) && * rfd1.getSize()==rfd2.getSize() && (rfd1.getSHA1Urn()==null || * rfd2.getSHA1Urn()==null || * rfd1.getSHA1Urn().equals(rfd2.getSHA1Urn())). * </ul> * Note that the second condition allows risky resumes, i.e., resumes when * one (or both) of the files doesn't have a hash. * * @see getFile */ static boolean same(RemoteFileDesc rfd1, RemoteFileDesc rfd2) { return same( rfd1.getFileName(), rfd1.getSize(), rfd1.getSHA1Urn(), rfd2.getFileName(), rfd2.getSize(), rfd2.getSHA1Urn()); }
/** pings a bunch of hosts if necessary */ private void pingNewHosts() { // if we have reached our desired # of altlocs, don't ping if (isCancelled()) return; // if we don't have anybody to ping, don't ping if (!hasNonBusy()) return; // if we haven't found a single RFD with URN, don't ping anybody if (sha1 == null) return; // if its not time to ping yet, don't ping // use the same interval as workers for now long now = System.currentTimeMillis(); if (now - lastPingTime < DownloadSettings.WORKER_INTERVAL.getValue()) return; // create a ping for the non-firewalled hosts HeadPing ping = new HeadPing(myGUID, sha1, getPingFlags()); // prepare a batch of hosts to ping int batch = DownloadSettings.PING_BATCH.getValue(); List toSend = new ArrayList(batch); int sent = 0; for (Iterator iter = newHosts.iterator(); iter.hasNext() && sent < batch; ) { RemoteFileDesc rfd = (RemoteFileDesc) iter.next(); if (rfd.isBusy(now)) continue; iter.remove(); if (rfd.needsPush()) { if (rfd.getPushProxies().size() > 0 && rfd.getSHA1Urn() != null) pingProxies(rfd); } else { pingedHosts.put(rfd, rfd); toSend.add(rfd); } testedLocations.add(rfd); sent++; } if (LOG.isDebugEnabled()) { LOG.debug( "\nverified hosts " + verifiedHosts.size() + "\npingedHosts " + pingedHosts.values().size() + "\nnewHosts " + newHosts.size() + "\npinging hosts: " + sent); } pinger.rank(toSend, null, this, ping); lastPingTime = now; }
/** schedules a push ping to each proxy of the given host */ private void pingProxies(RemoteFileDesc rfd) { if (RouterService.acceptedIncomingConnection() || (RouterService.getUdpService().canDoFWT() && rfd.supportsFWTransfer())) { HeadPing pushPing = new HeadPing( myGUID, rfd.getSHA1Urn(), new GUID(rfd.getPushAddr().getClientGUID()), getPingFlags()); for (Iterator iter = rfd.getPushProxies().iterator(); iter.hasNext(); ) pingedHosts.put(iter.next(), rfd); if (LOG.isDebugEnabled()) LOG.debug("pinging push location " + rfd.getPushAddr()); pinger.rank(rfd.getPushProxies(), null, this, pushPing); } }
public URN getSHA1Urn() { return remoteFileDesc.getSHA1Urn(); }
/** * Same as getFile(String, urn, int), except taking the values from the RFD. getFile(rfd) == * getFile(rfd.getFileName(), rfd.getSHA1Urn(), rfd.getSize()); */ public synchronized File getFile(RemoteFileDesc rfd) throws IOException { return getFile(rfd.getFileName(), rfd.getSHA1Urn(), rfd.getSize()); }