/** * Helper method that creates an array of bytes for the specified <tt>Set</tt> of <tt>URN</tt> * instances. The bytes are written as specified in HUGE v 0.94. * * @param urns the <tt>Set</tt> of <tt>URN</tt> instances to use in constructing the byte array */ private static byte[] createExtBytes(Set urns, GGEPContainer ggep) { try { if (isEmpty(urns) && ggep.isEmpty()) return DataUtils.EMPTY_BYTE_ARRAY; ByteArrayOutputStream baos = new ByteArrayOutputStream(); if (!isEmpty(urns)) { // Add the extension for URNs, if any. Iterator iter = urns.iterator(); while (iter.hasNext()) { URN urn = (URN) iter.next(); Assert.that(urn != null, "Null URN"); baos.write(urn.toString().getBytes()); // If there's another URN, add the separator. if (iter.hasNext()) { baos.write(EXT_SEPARATOR); } } // If there's ggep data, write the separator. if (!ggep.isEmpty()) baos.write(EXT_SEPARATOR); } // It is imperitive that GGEP is added LAST. // That is because GGEP can contain 0x1c (EXT_SEPARATOR) // within it, which would cause parsing problems // otherwise. if (!ggep.isEmpty()) GGEPUtil.addGGEP(baos, ggep); return baos.toByteArray(); } catch (IOException impossible) { ErrorService.error(impossible); return DataUtils.EMPTY_BYTE_ARRAY; } }
protected boolean addInternal(URN o) { if (o.isSHA1() && sha1 == null) { sha1 = o; return true; } else if (o.isTTRoot() && ttroot == null) { ttroot = o; return true; } return false; }
public static URN getSha1(Set<? extends URN> urns) { if (urns instanceof UrnSet) { return ((UrnSet) urns).sha1; } else { for (URN urn : urns) { if (urn.isSHA1()) { return urn; } } return null; } }
/** * Accessor for the SHA1 URN for this <tt>RemoteFileDesc</tt>. * * @return the SHA1 <tt>URN</tt> for this <tt>RemoteFileDesc</tt>, or <tt>null</tt> if there is * none */ public final URN getSHA1Urn() { Iterator iter = _urns.iterator(); while (iter.hasNext()) { URN urn = (URN) iter.next(); // defensively check against null values added. if (urn == null) continue; if (urn.isSHA1()) { return urn; } } return null; }
/** * Returns an <tt>URL</tt> instance for this <tt>RemoteFileDesc</tt>. * * @return an <tt>URL</tt> instance for this <tt>RemoteFileDesc</tt> */ public URL getUrl() { try { String fileName = ""; URN urn = getSHA1Urn(); if (urn == null) { fileName = "/get/" + _index + "/" + _filename; } else { fileName = HTTPConstants.URI_RES_N2R + urn.httpStringValue(); } return new URL("http", _host, _port, fileName); } catch (MalformedURLException e) { return null; } }
/** Returns the hashcode for this UrnSet. */ @Override public int hashCode() { return sha1 == null ? 0 : sha1.hashCode(); }
private RemoteFileDesc makeRFD(String sha1) throws Exception { URN urn = URN.createSHA1Urn("urn:sha1:" + sha1); return makeRFD(urn); }
public void testUsesCachedQueryKeys() throws Exception { BlockingConnectionUtils.keepAllAlive(testUP, pingReplyFactory); // clear up any messages before we begin the test. drainAll(); DatagramPacket pack = null; Message m = null; byte[] guid = searchServices.newQueryGUID(); searchServices.query(guid, "whatever"); // i need to pretend that the UI is showing the user the query still callback.setGUID(new GUID(guid)); QueryRequest qr = BlockingConnectionUtils.getFirstInstanceOfMessageType(testUP[0], QueryRequest.class); assertNotNull(qr); assertTrue(qr.desiresOutOfBandReplies()); // ok, the leaf is sending OOB queries - good stuff, now we should send // a lot of results back and make sure it buffers the bypassed OOB ones for (int i = 0; i < testUP.length; i++) { Response[] res = new Response[200]; for (int j = 0; j < res.length; j++) res[j] = responseFactory.createResponse( 10 + j + i, 10 + j + i, "whatever " + j + i, UrnHelper.SHA1); m = queryReplyFactory.createQueryReply( qr.getGUID(), (byte) 1, 6355, myIP(), 0, res, GUID.makeGuid(), new byte[0], false, false, true, true, false, false, null); testUP[i].send(m); testUP[i].flush(); } // create a test uploader and send back that response TestUploader uploader = new TestUploader(networkManagerStub); uploader.start("whatever", UPLOADER_PORT, false); uploader.setBusy(true); URN urn = URN.createSHA1Urn("urn:sha1:GLIQY64M7FSXBSQEZY37FIM5QQSA2OUJ"); RemoteFileDesc rfd = makeRFD(urn); // wait for processing Thread.sleep(1500); // send back ReplyNumberVMs that should be bypassed for (int i = 0; i < UDP_ACCESS.length; i++) { ReplyNumberVendorMessage vm = replyNumberVendorMessageFactory.createV3ReplyNumberVendorMessage( new GUID(qr.getGUID()), i + 1); ByteArrayOutputStream baos = new ByteArrayOutputStream(); vm.write(baos); pack = new DatagramPacket( baos.toByteArray(), baos.toByteArray().length, testUP[0].getInetAddress(), SERVER_PORT); UDP_ACCESS[i].send(pack); } // wait for processing Thread.sleep(500); { // all the UDP ReplyNumberVMs should have been bypassed assertByPassedResultsCacheHasSize(qr.getGUID(), UDP_ACCESS.length); } // Prepopulate Query Keys AddressSecurityToken qk = new AddressSecurityToken(InetAddress.getLocalHost(), SERVER_PORT, macManager); for (int i = 0; i < UDP_ACCESS.length; i++) { byte[] ip = new byte[] {(byte) 127, (byte) 0, (byte) 0, (byte) 1}; PingReply pr = pingReplyFactory.createQueryKeyReply( GUID.makeGuid(), (byte) 1, UDP_ACCESS[i].getLocalPort(), ip, 10, 10, false, qk); pr.hop(); onDemandUnicaster.handleQueryKeyPong(pr); } // confirm download will try to GUESS long currTime = System.currentTimeMillis(); Downloader downloader = downloadServices.download(new RemoteFileDesc[] {rfd}, false, new GUID(guid)); final int MAX_TRIES = 60; for (int i = 0; i <= MAX_TRIES; i++) { Thread.sleep(500); if (downloader.getState() == DownloadState.ITERATIVE_GUESSING) break; if (i == MAX_TRIES) fail("didn't GUESS!!"); } // we should start getting guess queries on all UDP ports for (int i = 0; i < UDP_ACCESS.length; i++) { boolean gotQuery = false; while (!gotQuery) { try { byte[] datagramBytes = new byte[1000]; pack = new DatagramPacket(datagramBytes, 1000); UDP_ACCESS[i].setSoTimeout(10000); // may need to wait UDP_ACCESS[i].receive(pack); InputStream in = new ByteArrayInputStream(pack.getData()); m = messageFactory.read(in, Network.TCP); if (m instanceof QueryRequest) { QueryRequest qReq = (QueryRequest) m; Set queryURNs = qReq.getQueryUrns(); gotQuery = queryURNs.contains(urn); if (gotQuery) gotQuery = qReq.getQueryKey().isFor(InetAddress.getLocalHost(), SERVER_PORT); } } catch (InterruptedIOException iioe) { assertTrue("was successful for " + i, false); } } } Thread.sleep((UDP_ACCESS.length * 1500) - (System.currentTimeMillis() - currTime)); assertEquals(DownloadState.BUSY, downloader.getState()); callback.clearGUID(); downloader.stop(); Thread.sleep(1000); { // now we should make sure MessageRouter clears the map assertByPassedResultsCacheHasSize(qr.getGUID(), 0); } uploader.stopThread(); }