예제 #1
0
 /** Handle an FNPRoutedRejected message. */
 private boolean handleRoutedRejected(Message m) {
   long id = m.getLong(DMT.UID);
   Long lid = Long.valueOf(id);
   RoutedContext rc = routedContexts.get(lid);
   if (rc == null) {
     // Gah
     Logger.error(this, "Unrecognized FNPRoutedRejected");
     return false; // locally originated??
   }
   short htl = rc.lastHtl;
   if (rc.source != null) htl = rc.source.decrementHTL(htl);
   short ohtl = m.getShort(DMT.HTL);
   if (ohtl < htl) htl = ohtl;
   if (htl == 0) {
     // Equivalent to DNF.
     // Relay.
     if (rc.source != null) {
       try {
         rc.source.sendAsync(
             DMT.createFNPRoutedRejected(id, (short) 0), null, nodeStats.routedMessageCtr);
       } catch (NotConnectedException e) {
         // Ouch.
         Logger.error(this, "Unable to relay probe DNF: peer disconnected: " + rc.source);
       }
     }
   } else {
     // Try routing to the next node
     forward(rc.msg, id, rc.source, htl, rc.msg.getDouble(DMT.TARGET_LOCATION), rc, rc.identity);
   }
   return true;
 }
예제 #2
0
  /**
   * Handle a routed-to-a-specific-node message.
   *
   * @param m
   * @return False if we want the message put back on the queue.
   */
  boolean handleRouted(Message m, PeerNode source) {
    if (logMINOR) Logger.minor(this, "handleRouted(" + m + ')');

    long id = m.getLong(DMT.UID);
    Long lid = Long.valueOf(id);
    short htl = m.getShort(DMT.HTL);
    byte[] identity = ((ShortBuffer) m.getObject(DMT.NODE_IDENTITY)).getData();
    if (source != null) htl = source.decrementHTL(htl);
    RoutedContext ctx;
    ctx = routedContexts.get(lid);
    if (ctx != null) {
      try {
        source.sendAsync(DMT.createFNPRoutedRejected(id, htl), null, nodeStats.routedMessageCtr);
      } catch (NotConnectedException e) {
        if (logMINOR) Logger.minor(this, "Lost connection rejecting " + m);
      }
      return true;
    }
    ctx = new RoutedContext(m, source, identity);
    synchronized (routedContexts) {
      routedContexts.put(lid, ctx);
    }
    // source == null => originated locally, keep full htl
    double target = m.getDouble(DMT.TARGET_LOCATION);
    if (logMINOR)
      Logger.minor(this, "id " + id + " from " + source + " htl " + htl + " target " + target);
    if (Math.abs(node.lm.getLocation() - target) <= Double.MIN_VALUE) {
      if (logMINOR)
        Logger.minor(this, "Dispatching " + m.getSpec() + " on " + node.getDarknetPortNumber());
      // Handle locally
      // Message type specific processing
      dispatchRoutedMessage(m, source, id);
      return true;
    } else if (htl == 0) {
      Message reject = DMT.createFNPRoutedRejected(id, (short) 0);
      if (source != null)
        try {
          source.sendAsync(reject, null, nodeStats.routedMessageCtr);
        } catch (NotConnectedException e) {
          if (logMINOR) Logger.minor(this, "Lost connection rejecting " + m);
        }
      return true;
    } else {
      return forward(m, id, source, htl, target, ctx, identity);
    }
  }
예제 #3
0
 private boolean forward(
     Message m,
     long id,
     PeerNode pn,
     short htl,
     double target,
     RoutedContext ctx,
     byte[] targetIdentity) {
   if (logMINOR) Logger.minor(this, "Should forward");
   // Forward
   m = preForward(m, htl);
   while (true) {
     PeerNode next = node.peers.getByIdentity(targetIdentity);
     if (next != null && !next.isConnected()) {
       Logger.error(this, "Found target but disconnected!: " + next);
       next = null;
     }
     if (next == null)
       next =
           node.peers.closerPeer(
               pn, ctx.routedTo, target, true, node.isAdvancedModeEnabled(), -1, null, null, htl);
     if (logMINOR) Logger.minor(this, "Next: " + next + " message: " + m);
     if (next != null) {
       // next is connected, or at least has been => next.getPeer() CANNOT be null.
       if (logMINOR)
         Logger.minor(this, "Forwarding " + m.getSpec() + " to " + next.getPeer().getPort());
       ctx.addSent(next);
       try {
         next.sendAsync(m, null, nodeStats.routedMessageCtr);
       } catch (NotConnectedException e) {
         continue;
       }
     } else {
       if (logMINOR)
         Logger.minor(
             this, "Reached dead end for " + m.getSpec() + " on " + node.getDarknetPortNumber());
       // Reached a dead end...
       Message reject = DMT.createFNPRoutedRejected(id, htl);
       if (pn != null)
         try {
           pn.sendAsync(reject, null, nodeStats.routedMessageCtr);
         } catch (NotConnectedException e) {
           Logger.error(this, "Cannot send reject message back to source " + pn);
           return true;
         }
     }
     return true;
   }
 }