Пример #1
0
 private boolean handleAnnounceRequest(Message m, PeerNode source) {
   long uid = m.getLong(DMT.UID);
   OpennetManager om = node.getOpennet();
   if (om == null || !source.canAcceptAnnouncements()) {
     Message msg = DMT.createFNPOpennetDisabled(uid);
     try {
       source.sendAsync(msg, null, node.nodeStats.announceByteCounter);
     } catch (NotConnectedException e) {
       // Ok
     }
     return true;
   }
   if (node.recentlyCompleted(uid)) {
     Message msg = DMT.createFNPRejectedLoop(uid);
     try {
       source.sendAsync(msg, null, node.nodeStats.announceByteCounter);
     } catch (NotConnectedException e) {
       // Ok
     }
     return true;
   }
   boolean success = false;
   // No way to check whether it's actually running atm, so lets report it to the completed list
   // immediately.
   // FIXME we should probably keep a list!
   node.completed(uid);
   try {
     if (!source.shouldAcceptAnnounce(uid)) {
       Message msg = DMT.createFNPRejectedOverload(uid, true);
       try {
         source.sendAsync(msg, null, node.nodeStats.announceByteCounter);
       } catch (NotConnectedException e) {
         // Ok
       }
       return true;
     }
     AnnounceSender sender = new AnnounceSender(m, uid, source, om, node);
     node.executor.execute(sender, "Announcement sender for " + uid);
     success = true;
     return true;
   } finally {
     if (!success) source.completedAnnounce(uid);
   }
 }
Пример #2
0
 private boolean handleProbeRequest(Message m, PeerNode source) {
   long id = m.getLong(DMT.UID);
   if (node.recentlyCompleted(id)) {
     Message rejected = DMT.createFNPRejectedLoop(id);
     try {
       source.sendAsync(rejected, null, node.nodeStats.probeRequestCtr);
     } catch (NotConnectedException e) {
       Logger.normal(this, "Rejecting probe request from " + source.getPeer() + ": " + e);
     }
     return true;
   }
   // Lets not bother with full lockUID, just add it to the recently completed list.
   node.completed(id);
   // SSKs don't fix bwlimitDelayTime so shouldn't be accepted when overloaded.
   if (source.shouldRejectProbeRequest()) {
     Logger.normal(this, "Rejecting probe request from " + source.getPeer());
     Message rejected = DMT.createFNPRejectedOverload(id, true);
     try {
       source.sendAsync(rejected, null, node.nodeStats.probeRequestCtr);
     } catch (NotConnectedException e) {
       Logger.normal(
           this, "Rejecting (overload) insert request from " + source.getPeer() + ": " + e);
     }
     return true;
   }
   double target = m.getDouble(DMT.TARGET_LOCATION);
   if (target > 1.0 || target < 0.0) {
     Logger.normal(
         this, "Rejecting invalid (target=" + target + ") probe request from " + source.getPeer());
     Message rejected = DMT.createFNPRejectedOverload(id, true);
     try {
       source.sendAsync(rejected, null, node.nodeStats.probeRequestCtr);
     } catch (NotConnectedException e) {
       Logger.normal(
           this, "Rejecting (invalid) insert request from " + source.getPeer() + ": " + e);
     }
     return true;
   }
   ProbeRequestHandler.start(m, source, node, target);
   return true;
 }
Пример #3
0
 private boolean handleInsertRequest(Message m, PeerNode source, boolean isSSK) {
   ByteCounter ctr = isSSK ? node.nodeStats.sskInsertCtr : node.nodeStats.chkInsertCtr;
   long id = m.getLong(DMT.UID);
   if (node.recentlyCompleted(id)) {
     Message rejected = DMT.createFNPRejectedLoop(id);
     try {
       source.sendAsync(rejected, null, ctr);
     } catch (NotConnectedException e) {
       Logger.normal(this, "Rejecting insert request from " + source.getPeer() + ": " + e);
     }
     return true;
   }
   InsertTag tag = new InsertTag(isSSK, InsertTag.START.REMOTE);
   if (!node.lockUID(id, isSSK, true, false, false, tag)) {
     if (logMINOR)
       Logger.minor(this, "Could not lock ID " + id + " -> rejecting (already running)");
     Message rejected = DMT.createFNPRejectedLoop(id);
     try {
       source.sendAsync(rejected, null, ctr);
     } catch (NotConnectedException e) {
       Logger.normal(this, "Rejecting insert request from " + source.getPeer() + ": " + e);
     }
     return true;
   }
   // SSKs don't fix bwlimitDelayTime so shouldn't be accepted when overloaded.
   String rejectReason =
       nodeStats.shouldRejectRequest(!isSSK, true, isSSK, false, false, source, false);
   if (rejectReason != null) {
     Logger.normal(
         this,
         "Rejecting insert from " + source.getPeer() + " preemptively because " + rejectReason);
     Message rejected = DMT.createFNPRejectedOverload(id, true);
     try {
       source.sendAsync(rejected, null, ctr);
     } catch (NotConnectedException e) {
       Logger.normal(
           this, "Rejecting (overload) insert request from " + source.getPeer() + ": " + e);
     }
     node.unlockUID(id, isSSK, true, false, false, false, tag);
     return true;
   }
   boolean forkOnCacheable = Node.FORK_ON_CACHEABLE_DEFAULT;
   Message forkControl = m.getSubMessage(DMT.FNPSubInsertForkControl);
   if (forkControl != null)
     forkOnCacheable = forkControl.getBoolean(DMT.ENABLE_INSERT_FORK_WHEN_CACHEABLE);
   long now = System.currentTimeMillis();
   if (m.getSpec().equals(DMT.FNPSSKInsertRequest)) {
     NodeSSK key = (NodeSSK) m.getObject(DMT.FREENET_ROUTING_KEY);
     byte[] data = ((ShortBuffer) m.getObject(DMT.DATA)).getData();
     byte[] headers = ((ShortBuffer) m.getObject(DMT.BLOCK_HEADERS)).getData();
     short htl = m.getShort(DMT.HTL);
     SSKInsertHandler rh =
         new SSKInsertHandler(
             key,
             data,
             headers,
             htl,
             source,
             id,
             node,
             now,
             tag,
             node.canWriteDatastoreInsert(htl),
             forkOnCacheable);
     rh.receivedBytes(m.receivedByteCount());
     node.executor.execute(
         rh, "SSKInsertHandler for " + id + " on " + node.getDarknetPortNumber());
   } else if (m.getSpec().equals(DMT.FNPSSKInsertRequestNew)) {
     NodeSSK key = (NodeSSK) m.getObject(DMT.FREENET_ROUTING_KEY);
     short htl = m.getShort(DMT.HTL);
     SSKInsertHandler rh =
         new SSKInsertHandler(
             key,
             null,
             null,
             htl,
             source,
             id,
             node,
             now,
             tag,
             node.canWriteDatastoreInsert(htl),
             forkOnCacheable);
     rh.receivedBytes(m.receivedByteCount());
     node.executor.execute(
         rh, "SSKInsertHandler for " + id + " on " + node.getDarknetPortNumber());
   } else {
     CHKInsertHandler rh = new CHKInsertHandler(m, source, id, node, now, tag, forkOnCacheable);
     node.executor.execute(
         rh, "CHKInsertHandler for " + id + " on " + node.getDarknetPortNumber());
   }
   if (logMINOR) Logger.minor(this, "Started InsertHandler for " + id);
   return true;
 }
Пример #4
0
  /** Handle an incoming FNPDataRequest. */
  private boolean handleDataRequest(Message m, PeerNode source, boolean isSSK) {
    long id = m.getLong(DMT.UID);
    ByteCounter ctr = isSSK ? node.nodeStats.sskRequestCtr : node.nodeStats.chkRequestCtr;
    if (node.recentlyCompleted(id)) {
      Message rejected = DMT.createFNPRejectedLoop(id);
      try {
        source.sendAsync(rejected, null, ctr);
      } catch (NotConnectedException e) {
        Logger.normal(this, "Rejecting data request (loop, finished): " + e);
      }
      return true;
    }
    short htl = m.getShort(DMT.HTL);
    Key key = (Key) m.getObject(DMT.FREENET_ROUTING_KEY);
    final RequestTag tag = new RequestTag(isSSK, RequestTag.START.REMOTE);
    if (!node.lockUID(id, isSSK, false, false, false, tag)) {
      if (logMINOR)
        Logger.minor(this, "Could not lock ID " + id + " -> rejecting (already running)");
      Message rejected = DMT.createFNPRejectedLoop(id);
      try {
        source.sendAsync(rejected, null, ctr);
      } catch (NotConnectedException e) {
        Logger.normal(this, "Rejecting request from " + source.getPeer() + ": " + e);
      }
      node.failureTable.onFinalFailure(key, null, htl, htl, -1, source);
      return true;
    } else {
      if (logMINOR) Logger.minor(this, "Locked " + id);
    }

    // There are at least 2 threads that call this function.
    // DO NOT reuse the meta object, unless on a per-thread basis.
    // Object allocation is pretty cheap in modern Java anyway...
    // If we do reuse it, call reset().
    BlockMetadata meta = new BlockMetadata();
    KeyBlock block = node.fetch(key, false, false, false, false, meta);

    String rejectReason =
        nodeStats.shouldRejectRequest(
            !isSSK, false, isSSK, false, false, source, block != null && !meta.isOldBlock());
    if (rejectReason != null) {
      // can accept 1 CHK request every so often, but not with SSKs because they aren't throttled so
      // won't sort out bwlimitDelayTime, which was the whole reason for accepting them when
      // overloaded...
      Logger.normal(
          this,
          "Rejecting "
              + (isSSK ? "SSK" : "CHK")
              + " request from "
              + source.getPeer()
              + " preemptively because "
              + rejectReason);
      Message rejected = DMT.createFNPRejectedOverload(id, true);
      try {
        source.sendAsync(rejected, null, ctr);
      } catch (NotConnectedException e) {
        Logger.normal(
            this, "Rejecting (overload) data request from " + source.getPeer() + ": " + e);
      }
      tag.setRejected();
      node.unlockUID(id, isSSK, false, false, false, false, tag);
      // Do not tell failure table.
      // Otherwise an attacker can flood us with requests very cheaply and purge our
      // failure table even though we didn't accept any of them.
      return true;
    }
    nodeStats.reportIncomingRequestLocation(key.toNormalizedDouble());
    // if(!node.lockUID(id)) return false;
    RequestHandler rh = new RequestHandler(m, source, id, node, htl, key, tag, block);
    node.executor.execute(
        rh, "RequestHandler for UID " + id + " on " + node.getDarknetPortNumber());
    return true;
  }