/** * Clears away any URNs for files that do not exist anymore. * @param shouldClearURNSetMap true if you want to clear TIME_TO_URNSET_MAP * too */ private void pruneTimes(boolean shouldClearURNSetMap) { // if i'm using FM, always grab that lock first and then me. be quick // about it though :) synchronized (RouterService.getFileManager()) { synchronized (this) { Iterator iter = URN_TO_TIME_MAP.entrySet().iterator(); while (iter.hasNext()) { Map.Entry currEntry = (Map.Entry) iter.next(); if(!(currEntry.getKey() instanceof URN) || !(currEntry.getValue() instanceof Long)) { iter.remove(); dirty = true; continue; } URN currURN = (URN) currEntry.getKey(); Long cTime = (Long) currEntry.getValue(); // check to see if file still exists // NOTE: technically a URN can map to multiple FDs, but I only want // to know about one. getFileDescForUrn prefers FDs over iFDs. FileDesc fd = RouterService.getFileManager().getFileDescForUrn(currURN); if ((fd == null) || (fd.getFile() == null) || !fd.getFile().exists()) { dirty = true; iter.remove(); if (shouldClearURNSetMap) removeURNFromURNSet(currURN, cTime); } } } } }
/** * Returns an List of URNs, from 'youngest' to 'oldest'. * @param max the maximum number of URNs you want returned. if you * want all, give Integer.MAX_VALUE. * @param request in case the query has meta-flags, you can give it to * me. null is fine though. * @return a List ordered by younger URNs. */ public List getFiles(final QueryRequest request, final int max) throws IllegalArgumentException { // if i'm using FM, always grab that lock first and then me. be quick // about it though :) synchronized (RouterService.getFileManager()) { synchronized (this) { if (max < 1) throw new IllegalArgumentException("bad max = " + max); List urnList = new ArrayList(); Iterator iter = TIME_TO_URNSET_MAP.entrySet().iterator(); final MediaType.Aggregator filter = (request == null ? null : MediaType.getAggregator(request)); // may be non-null at loop end List toRemove = null; // we bank on the fact that the TIME_TO_URNSET_MAP iterator returns the // entries in descending order.... while (iter.hasNext() && (urnList.size() < max)) { Map.Entry currEntry = (Map.Entry) iter.next(); Set urns = (Set) currEntry.getValue(); // only put as many as desired, and possibly filter results based // on what the query desires Iterator innerIter = urns.iterator(); while ((urnList.size() < max) && innerIter.hasNext()) { URN currURN = (URN) innerIter.next(); FileDesc fd = RouterService.getFileManager().getFileDescForUrn(currURN); // unfortunately fds can turn into ifds so ignore if ((fd == null) || (fd instanceof IncompleteFileDesc)) { if (toRemove == null) toRemove = new ArrayList(); toRemove.add(currURN); continue; } if (filter == null) urnList.add(currURN); else if (filter.allow(fd.getFileName())) urnList.add(currURN); } } // clear any ifd's or unshared files that may have snuck into structures if (toRemove != null) { Iterator removees = toRemove.iterator(); while (removees.hasNext()) { URN currURN = (URN) removees.next(); removeTime(currURN); } } return urnList; } } }
/** * Constructs a new <tt>Response</tt> instance from the data in the specified <tt>FileDesc</tt>. * * @param fd the <tt>FileDesc</tt> containing the data to construct this <tt>Response</tt> -- must * not be <tt>null</tt> */ public Response(FileDesc fd) { this( fd.getIndex(), fd.getFileSize(), fd.getFileName(), fd.getUrns(), null, new GGEPContainer( getAsEndpoints(RouterService.getAltlocManager().getDirect(fd.getSHA1Urn())), CreationTimeCache.instance().getCreationTimeAsLong(fd.getSHA1Urn())), null); }
/** * Constructs the TIME_TO_URNSET_MAP, which is based off the entries in the * URN_TO_TIME_MAP. * IMPORTANT NOTE: currently this method is not synchronized, and does not * need to be since it is only called from the constructor (which auto- * magically disallows concurrent acess to the instance. If this method * is ever made public, called from multiple entrypoints, etc., * synchronization may be needed. */ private void constructURNMap() { Set entries = URN_TO_TIME_MAP.entrySet(); Iterator iter = entries.iterator(); while (iter.hasNext()) { // for each entry, get the creation time and the urn.... Map.Entry currEntry = (Map.Entry) iter.next(); Long cTime = (Long) currEntry.getValue(); URN urn = (URN) currEntry.getKey(); // don't ever add IFDs if (RouterService.getFileManager().getFileDescForUrn(urn) instanceof IncompleteFileDesc) continue; // put the urn in a set of urns that have that creation time.... Set urnSet = (Set) TIME_TO_URNSET_MAP.get(cTime); if (urnSet == null) { urnSet = new HashSet(); // populate the reverse mapping TIME_TO_URNSET_MAP.put(cTime, urnSet); } urnSet.add(urn); } }
/** @return whether this rfd points to myself. */ public boolean isMe() { return needsPush() ? Arrays.equals(_clientGUID, RouterService.getMyGUID()) : NetworkUtils.isMe(getHost(), getPort()); }
// MUST RUN THIS TEST FIRST public void testMixedProtocol() throws Exception { DatagramPacket pack = null; UDP_ACCESS = new DatagramSocket(); for (int i = 0; i < testUP.length; i++) { assertTrue("not open", testUP[i].isOpen()); assertTrue("not up->leaf", testUP[i].isSupernodeClientConnection()); drain(testUP[i], 500); if ((i == 2)) { // i'll send 0 later.... testUP[i].send(MessagesSupportedVendorMessage.instance()); testUP[i].flush(); } } testUP[0].send(MessagesSupportedVendorMessage.instance()); testUP[0].flush(); // first we need to set up GUESS capability UDP_ACCESS.setSoTimeout(TIMEOUT * 2); // ---------------------------------------- // set up solicited UDP support PrivilegedAccessor.setValue(rs.getUdpService(), "_acceptedSolicitedIncoming", Boolean.TRUE); // set up unsolicited UDP support PrivilegedAccessor.setValue(rs.getUdpService(), "_acceptedUnsolicitedIncoming", Boolean.TRUE); // you also have to set up TCP incoming.... { Socket sock = null; OutputStream os = null; try { sock = Sockets.connect(InetAddress.getLocalHost().getHostAddress(), SERVER_PORT, 12); os = sock.getOutputStream(); os.write("\n\n".getBytes()); } catch (IOException ignored) { } catch (SecurityException ignored) { } catch (Throwable t) { ErrorService.error(t); } finally { if (sock != null) try { sock.close(); } catch (IOException ignored) { } if (os != null) try { os.close(); } catch (IOException ignored) { } } } // ---------------------------------------- Thread.sleep(250); // we should now be guess capable and tcp incoming capable.... assertTrue(RouterService.isGUESSCapable()); assertTrue(RouterService.acceptedIncomingConnection()); // get rid of any messages that are stored up. drainAll(); // first of all, we should confirm that we are sending out a OOB query. GUID queryGuid = new GUID(RouterService.newQueryGUID()); assertTrue( GUID.addressesMatch( queryGuid.bytes(), RouterService.getAddress(), RouterService.getPort())); RouterService.query(queryGuid.bytes(), "susheel"); Thread.sleep(250); // some connected UPs should get a OOB query for (int i = 0; i < testUP.length; i++) { QueryRequest qr = getFirstQueryRequest(testUP[i], TIMEOUT); assertNotNull("up " + i + " didn't get query", qr); assertEquals(new GUID(qr.getGUID()), queryGuid); if ((i == 0) || (i == 2)) assertTrue(qr.desiresOutOfBandReplies()); else assertTrue(!qr.desiresOutOfBandReplies()); } // now confirm that we leaf guide the 'even' guys but not the others. Message m = null; // ensure that we'll get a QueryStatusResponse from the Responses // we're sending. for (int i = 0; i < testUP.length; i++) { Response[] res = new Response[7]; res[0] = new Response(10, 10, "susheel" + i); res[1] = new Response(10, 10, "susheel smells good" + i); res[2] = new Response(10, 10, "anita is sweet" + i); res[3] = new Response(10, 10, "anita is prety" + i); res[4] = new Response(10, 10, "susheel smells bad" + i); res[5] = new Response(10, 10, "renu is sweet " + i); res[6] = new Response(10, 10, "prety is spelled pretty " + i); m = new QueryReply( queryGuid.bytes(), (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(); } // all UPs should get a QueryStatusResponse for (int i = 0; i < testUP.length; i++) { QueryStatusResponse stat = getFirstQueryStatus(testUP[i]); if ((i == 0) || (i == 2)) { assertNotNull(stat); assertEquals(new GUID(stat.getGUID()), queryGuid); assertEquals(5, stat.getNumResults()); } else assertNull(stat); } // shut off the query.... RouterService.stopQuery(queryGuid); // all UPs should get a QueryStatusResponse with 65535 for (int i = 0; i < testUP.length; i++) { QueryStatusResponse stat = getFirstQueryStatus(testUP[i]); if ((i == 0) || (i == 2)) { assertNotNull(stat); assertEquals(new GUID(stat.getGUID()), queryGuid); assertEquals(65535, stat.getNumResults()); } else assertNull(stat); } }