Package freenet.io.comm

Examples of freenet.io.comm.Message


   * error CANNOT_FORWARD.
   * @return True if no further action needed; false if HTL decremented to zero and a local response is needed.
   */
  private boolean route(final Type type, final long uid, byte htl, final Listener listener) {
    //Recreate the request so that any sub-messages or unintended fields are not forwarded.
    final Message message = DMT.createProbeRequest(htl, uid, type);
    PeerNode[] peers;
    //Degree of the local node.
    int degree;
    PeerNode candidate;
    /*
     * Attempt to forward until success or until reaching the send attempt limit.
     */
    for (int sendAttempts = 0; sendAttempts < MAX_SEND_ATTEMPTS; sendAttempts++) {
      peers = node.getConnectedPeers();
      degree = peers.length;
      //Can't handle a probe request if not connected to peers.
      if (degree == 0 ) {
        if (logMINOR) {
          Logger.minor(Probe.class, "Aborting probe request: no connections.");
        }

        /*
         * If this is a locally-started request, not a relayed one, give an error.
         * Otherwise, in this case there's nowhere to send the error.
         */
        listener.onError(Error.DISCONNECTED, null, true);
        return true;
      }

      candidate = peers[node.random.nextInt(degree)];

      if (candidate.isConnected()) {
        //acceptProbability is the MH correction.
        float acceptProbability;
        int candidateDegree = candidate.getDegree();
        /* Candidate's degree is unknown; fall back to random walk by accepting this candidate
         * regardless of its degree.
         */
        if (candidateDegree == 0) acceptProbability = 1.0f;
        else acceptProbability = (float)degree / candidateDegree;

        if (logDEBUG) Logger.debug(Probe.class, "acceptProbability is " + acceptProbability);
        if (node.random.nextFloat() < acceptProbability) {
          if (logDEBUG) Logger.debug(Probe.class, "Accepted candidate.");
          //Filter for response to this probe with requested result type.
          final MessageFilter filter = createResponseFilter(type, candidate, uid, htl);
          message.set(DMT.HTL, htl);
          try {
            node.getUSM().addAsyncFilter(filter, new ResultListener(listener), this);
            if (logDEBUG) Logger.debug(Probe.class, "Sending.");
            candidate.sendAsync(message, null, this);
            return true;
View Full Code Here


      long xferUID = sendTo(next);
      if(xferUID == -1) continue;

      hasForwarded = true;

      Message msg = null;

      while(true) {

        /**
         * What are we waiting for?
         * FNPAccepted - continue
         * FNPRejectedLoop - go to another node
         * FNPRejectedOverload - go to another node
         */

        MessageFilter mfAccepted = MessageFilter.create().setSource(next).setField(DMT.UID, uid).setTimeout(ACCEPTED_TIMEOUT).setType(DMT.FNPAccepted);
        MessageFilter mfRejectedLoop = MessageFilter.create().setSource(next).setField(DMT.UID, uid).setTimeout(ACCEPTED_TIMEOUT).setType(DMT.FNPRejectedLoop);
        MessageFilter mfRejectedOverload = MessageFilter.create().setSource(next).setField(DMT.UID, uid).setTimeout(ACCEPTED_TIMEOUT).setType(DMT.FNPRejectedOverload);
        MessageFilter mfOpennetDisabled = MessageFilter.create().setSource(next).setField(DMT.UID, uid).setTimeout(ACCEPTED_TIMEOUT).setType(DMT.FNPOpennetDisabled);

        // mfRejectedOverload must be the last thing in the or
        // So its or pointer remains null
        // Otherwise we need to recreate it below
        MessageFilter mf = mfAccepted.or(mfRejectedLoop.or(mfRejectedOverload.or(mfOpennetDisabled)));

        try {
          msg = node.usm.waitFor(mf, this);
          if(logMINOR) Logger.minor(this, "first part got "+msg);
        } catch (DisconnectedException e) {
          Logger.normal(this, "Disconnected from "+next+" while waiting for Accepted on "+uid);
          break;
        }

        if(msg == null) {
          if(logMINOR) Logger.minor(this, "Timeout waiting for Accepted");
          // Try next node
          msg = null;
          break;
        }

        if(msg.getSpec() == DMT.FNPRejectedLoop) {
          if(logMINOR) Logger.minor(this, "Rejected loop");
          // Find another node to route to
          msg = null;
          break;
        }

        if(msg.getSpec() == DMT.FNPRejectedOverload) {
          if(logMINOR) Logger.minor(this, "Rejected: overload");
          // Give up on this one, try another
          msg = null;
          break;
        }

        if(msg.getSpec() == DMT.FNPOpennetDisabled) {
          if(logMINOR) Logger.minor(this, "Opennet disabled");
          msg = null;
          break;
        }

        if(msg.getSpec() != DMT.FNPAccepted) {
          Logger.error(this, "Unrecognized message: "+msg);
          continue;
        }

        break;
      }

      if((msg == null) || (msg.getSpec() != DMT.FNPAccepted)) {
        // Try another node
        continue;
      }

      if(logMINOR) Logger.minor(this, "Got Accepted");
     
      if(cb != null)
        cb.acceptedSomewhere();

      // Send the rest

      try {
        sendRest(next, xferUID);
      } catch (NotConnectedException e1) {
        if(logMINOR)
          Logger.minor(this, "Not connected while sending noderef on "+next);
        continue;
      }

      // Otherwise, must be Accepted

      // So wait...

      while(true) {

        MessageFilter mfAnnounceCompleted = MessageFilter.create().setSource(next).setField(DMT.UID, uid).setTimeout(ANNOUNCE_TIMEOUT).setType(DMT.FNPOpennetAnnounceCompleted);
        MessageFilter mfRouteNotFound = MessageFilter.create().setSource(next).setField(DMT.UID, uid).setTimeout(ANNOUNCE_TIMEOUT).setType(DMT.FNPRouteNotFound);
        MessageFilter mfRejectedOverload = MessageFilter.create().setSource(next).setField(DMT.UID, uid).setTimeout(ANNOUNCE_TIMEOUT).setType(DMT.FNPRejectedOverload);
        MessageFilter mfAnnounceReply = MessageFilter.create().setSource(next).setField(DMT.UID, uid).setTimeout(ANNOUNCE_TIMEOUT).setType(DMT.FNPOpennetAnnounceReply);
        MessageFilter mfOpennetDisabled = MessageFilter.create().setSource(next).setField(DMT.UID, uid).setTimeout(ANNOUNCE_TIMEOUT).setType(DMT.FNPOpennetDisabled);
        MessageFilter mfNotWanted = MessageFilter.create().setSource(next).setField(DMT.UID, uid).setTimeout(ANNOUNCE_TIMEOUT).setType(DMT.FNPOpennetAnnounceNodeNotWanted);
        MessageFilter mfOpennetNoderefRejected = MessageFilter.create().setSource(next).setField(DMT.UID, uid).setTimeout(ANNOUNCE_TIMEOUT).setType(DMT.FNPOpennetNoderefRejected);
        MessageFilter mf = mfAnnounceCompleted.or(mfRouteNotFound.or(mfRejectedOverload.or(mfAnnounceReply.or(mfOpennetDisabled.or(mfNotWanted.or(mfOpennetNoderefRejected))))));

        try {
          msg = node.usm.waitFor(mf, this);
        } catch (DisconnectedException e) {
          Logger.normal(this, "Disconnected from "+next+" while waiting for announcement");
          break;
        }

        if(logMINOR) Logger.minor(this, "second part got "+msg);

        if(msg == null) {
          // Fatal timeout, must be terminal (IS_LOCAL==true)
          timedOut(next);
          return;
        }

        if(msg.getSpec() == DMT.FNPOpennetNoderefRejected) {
          int reason = msg.getInt(DMT.REJECT_CODE);
          Logger.normal(this, "Announce rejected by "+next+" : "+DMT.getOpennetRejectedCode(reason));
          msg = null;
          break;
        }

        if(msg.getSpec() == DMT.FNPOpennetAnnounceCompleted) {
          // Send the completion on immediately. We don't want to accumulate 30 seconds per hop!
          complete();
          mfAnnounceReply.setTimeout(END_TIMEOUT).setTimeoutRelativeToCreation(true);
          mfNotWanted.setTimeout(END_TIMEOUT).setTimeoutRelativeToCreation(true);
          mfAnnounceReply.clearOr();
          mfNotWanted.clearOr();
          mf = mfAnnounceReply.or(mfNotWanted);
          while(true)  {
            try {
              msg = node.usm.waitFor(mf, this);
            } catch (DisconnectedException e) {
              return;
            }
            if(msg == null) return;
            if(msg.getSpec() == DMT.FNPOpennetAnnounceReply) {
              validateForwardReply(msg, next);
              continue;
            }
            if(msg.getSpec() == DMT.FNPOpennetAnnounceNodeNotWanted) {
              if(cb != null)
                cb.nodeNotWanted();
              if(source != null) {
                try {
                  sendNotWanted();
                } catch (NotConnectedException e) {
                  Logger.warning(this, "Lost connection to source (announce completed)");
                  return;
                }
              }
              continue;
            }
          }
        }

        if(msg.getSpec() == DMT.FNPRouteNotFound) {
          // Backtrack within available hops
          short newHtl = msg.getShort(DMT.HTL);
          if(newHtl < 0) newHtl = 0;
          if(newHtl < htl) htl = newHtl;
          break;
        }

        if(msg.getSpec() == DMT.FNPRejectedOverload) {
          // Give up on this one, try another
          break;
        }

        if(msg.getSpec() == DMT.FNPOpennetDisabled) {
          Logger.minor(this, "Opennet disabled");
          msg = null;
          break;
        }

        if(msg.getSpec() == DMT.FNPOpennetAnnounceReply) {
          validateForwardReply(msg, next);
          continue; // There may be more
        }

        if(msg.getSpec() == DMT.FNPOpennetAnnounceNodeNotWanted) {
          if(cb != null)
            cb.nodeNotWanted();
          if(source != null) {
            try {
              sendNotWanted();
View Full Code Here

  private void sendRest(PeerNode next, long xferUID) throws NotConnectedException {
    om.finishSentAnnouncementRequest(next, noderefBuf, this, xferUID);
  }

  private void timedOut(PeerNode next) {
    Message msg = DMT.createFNPRejectedOverload(uid, true, false, false);
    if(source != null) {
      try {
        source.sendAsync(msg, null, this);
      } catch (NotConnectedException e) {
        // Ok
View Full Code Here

    }
    if(cb != null) cb.nodeFailed(next, "timed out");
  }

  private void rnf(PeerNode next) {
    Message msg = DMT.createFNPRouteNotFound(uid, htl);
    if(source != null) {
      try {
        source.sendAsync(msg, null, this);
      } catch (NotConnectedException e) {
        // Ok
View Full Code Here

        } catch (InterruptedException e) {
          // Ignore.
        }
      }
    }
    Message msg = DMT.createFNPOpennetAnnounceCompleted(uid);
    if(source != null) {
      try {
        source.sendAsync(msg, null, this);
      } catch (NotConnectedException e) {
        // Oh well.
View Full Code Here

    }
    return true;
  }

  private void sendNotWanted() throws NotConnectedException {
    Message msg = DMT.createFNPOpennetAnnounceNodeNotWanted(uid);
    source.sendAsync(msg, null, this);
  }
View Full Code Here

  /**
   * Test that different types can be set and retrieved to and from a Message.
   */
  public void test() {
    Message msg = new Message(test);

    //Values used for testing.
    final boolean booleanVal = true;
    final byte byteVal = (byte)123;
    final short shortVal = (short)456;
    final int intVal = 78912;
    final long longVal = 3456789123L;
    final double doubleVal = Math.PI;
    final float floatVal = 0.12345f;
    final double[] doubleArrayVal = new double[] { Math.PI, Math.E };
    final float[] floatArrayVal = new float[] { 1234.5678f, 912345.6789f };

    //Set fields.
    msg.set(BOOLEAN, booleanVal);
    msg.set(BYTE, byteVal);
    msg.set(SHORT, shortVal);
    msg.set(INT, intVal);
    msg.set(LONG, longVal);
    msg.set(DOUBLE, doubleVal);
    msg.set(FLOAT, floatVal);
    msg.set(DOUBLE_ARRAY, doubleArrayVal);
    msg.set(FLOAT_ARRAY, floatArrayVal);

    //Read fields.
    assertEquals(booleanVal, msg.getBoolean(BOOLEAN));
    assertEquals(byteVal, msg.getByte(BYTE));
    assertEquals(shortVal, msg.getShort(SHORT));
    assertEquals(intVal, msg.getInt(INT));
    assertEquals(longVal, msg.getLong(LONG));
    assertEquals(doubleVal, msg.getDouble(DOUBLE));
    assertEquals(floatVal, msg.getFloat(FLOAT));
    assertTrue(Arrays.equals(doubleArrayVal, msg.getDoubleArray(DOUBLE_ARRAY)));
    assertTrue(Arrays.equals(floatArrayVal, msg.getFloatArray(FLOAT_ARRAY)));
  }
View Full Code Here

    assertEquals(0, receiver.handleDecryptedPacket(packet1, receiverKey).size());
  }
 
  // Test sending it when the peer wants it to be sent. This is as a real message, *not* as a lossy message.
  public void testLoadStatsSendWhenPeerWants() throws BlockedTooLongException, InterruptedException {
    final Message loadMessage = DMT.createFNPVoid();
    final MutableBoolean gotMessage = new MutableBoolean();
    final SessionKey senderKey = new SessionKey(null, null, null, null, null, null, null, null, new NewPacketFormatKeyContext(0, 0), 1);
    NullBasePeerNode senderNode = new NullBasePeerNode() {
     
      boolean shouldSend = true;
     
      @Override
      public MessageItem makeLoadStats(boolean realtime, boolean highPriority, boolean noRemember) {
        return new MessageItem(loadMessage, null, null, (short)0);
      }

      @Override
      public synchronized boolean grabSendLoadStatsASAP(boolean realtime) {
        boolean ret = shouldSend;
        shouldSend = false;
        return ret;
      }

      @Override
      public synchronized void setSendLoadStatsASAP(boolean realtime) {
        shouldSend = true;
      }
     
      @Override
      public SessionKey getCurrentKeyTracker() {
        return senderKey;
      }

    };
    NewPacketFormat sender = new NewPacketFormat(senderNode, 0, 0);
    PeerMessageQueue senderQueue = new PeerMessageQueue();
    NullBasePeerNode receiverNode = new NullBasePeerNode() {
     
      @Override
      public void handleMessage(Message msg) {
        assert(msg.getSpec().equals(DMT.FNPVoid));
        synchronized(gotMessage) {
          gotMessage.value = true;
        }
      }
     
      @Override
      public void processDecryptedMessage(byte[] data, int offset, int length, int overhead) {
        Message m = Message.decodeMessageFromPacket(data, offset, length, this, overhead);
        if(m != null) {
          handleMessage(m);
        }
      }
     
View Full Code Here

    // Don't decode the packet because it's not a real message.
  }
 
  // Test sending load message as a per-packet lossy message, including message decoding.
  public void testLoadStatsHighLevel() throws BlockedTooLongException, InterruptedException {
    final Message loadMessage = DMT.createFNPVoid();
    final MutableBoolean gotMessage = new MutableBoolean();
    NullBasePeerNode senderNode = new NullBasePeerNode() {
     
      @Override
      public MessageItem makeLoadStats(boolean realtime, boolean highPriority, boolean noRemember) {
View Full Code Here

    private void realRun() {
        runThread = Thread.currentThread();
       
        // FIXME implement rate limiting or something!
        // Send Accepted
        Message accepted = DMT.createFNPAccepted(uid);
        try {
      //Using sendSync here will help the next message filter not timeout... wait here or at the message filter.
      source.sendSync(accepted, this, realTimeFlag);
    } catch (NotConnectedException e1) {
      if(logMINOR) Logger.minor(this, "Lost connection to source");
      return;
    } catch (SyncSendWaitedTooLongException e) {
      Logger.error(this, "Unable to send "+accepted+" in a reasonable time to "+source);
      return;
    }
   
    if(tag.shouldSlowDown()) {
      try {
        source.sendAsync(DMT.createFNPRejectedOverload(uid, false, false, realTimeFlag), null, this);
      } catch (NotConnectedException e) {
        // Ignore.
      }
    }
   
        // Source will send us a DataInsert
       
        MessageFilter mf;
        mf = makeDataInsertFilter(DATA_INSERT_TIMEOUT);
       
        Message msg;
        try {
            msg = node.usm.waitFor(mf, this);
        } catch (DisconnectedException e) {
            Logger.normal(this, "Disconnected while waiting for DataInsert on "+uid);
            return;
        }
       
        if(logMINOR) Logger.minor(this, "Received "+msg);
       
        if(msg == null) {
          handleNoDataInsert();
          return;
        }
       
        if(msg.getSpec() == DMT.FNPDataInsertRejected) {
          try {
        source.sendAsync(DMT.createFNPDataInsertRejected(uid, msg.getShort(DMT.DATA_INSERT_REJECTED_REASON)), null, this);
      } catch (NotConnectedException e) {
        // Ignore.
      }
          return;
        }
       
        // We have a DataInsert
        headers = ((ShortBuffer)msg.getObject(DMT.BLOCK_HEADERS)).getData();
        // FIXME check the headers
       
        // Now create an CHKInsertSender, or use an existing one, or
        // discover that the data is in the store.

        // From this point onwards, if we return cleanly we must go through finish().
       
        prb = new PartiallyReceivedBlock(Node.PACKETS_IN_BLOCK, Node.PACKET_SIZE);
        if(htl > 0)
            sender = node.makeInsertSender(key, htl, uid, tag, source, headers, prb, false, false, forkOnCacheable, preferInsert, ignoreLowBackoff, realTimeFlag);
        br = new BlockReceiver(node.usm, source, uid, prb, this, node.getTicker(), false, realTimeFlag, myTimeoutHandler, false);
       
        // Receive the data, off thread
        Runnable dataReceiver = new DataReceiver();
    receiveStarted = true;
        node.executor.execute(dataReceiver, "CHKInsertHandler$DataReceiver for UID "+uid);

        // Wait...
        // What do we want to wait for?
        // If the data receive completes, that's very nice,
        // but doesn't really matter. What matters is what
        // happens to the CHKInsertSender. If the data receive
        // fails, that does matter...
       
        // We are waiting for a terminal status on the CHKInsertSender,
        // including SUCCESS.
        // If we get transfer failed, we can check whether the receive
        // failed first. If it did it's not our fault.
        // If the receive failed, and we haven't started transferring
        // yet, we probably want to kill the sender.
        // So we call the wait method on the CHKInsertSender, but we
        // also have a flag locally to indicate the receive failed.
        // And if it does, we interrupt.
       
        boolean receivedRejectedOverload = false;
       
        while(true) {
            synchronized(sender) {
                try {
                  if(sender.getStatus() == CHKInsertSender.NOT_FINISHED)
                    sender.wait(5000);
                } catch (InterruptedException e) {
                    // Cool, probably this is because the receive failed...
                }
            }
            if(receiveFailed()) {
                // Nothing else we can do
                finish(CHKInsertSender.RECEIVE_FAILED);
                return;
            }
           
            if((!receivedRejectedOverload) && sender.receivedRejectedOverload()) {
              receivedRejectedOverload = true;
              // Forward it
              // Does not need to be sent synchronously since is non-terminal.
              Message m = DMT.createFNPRejectedOverload(uid, false, true, realTimeFlag);
              try {
          source.sendAsync(m, null, this);
        } catch (NotConnectedException e) {
          if(logMINOR) Logger.minor(this, "Lost connection to source");
          return;
View Full Code Here

TOP

Related Classes of freenet.io.comm.Message

Copyright © 2018 www.massapicom. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.