示例#1
0
  public long receiveEncrypted(byte encrypted[]) {
    TunnelDataMessage msg = new TunnelDataMessage(_context);
    msg.setData(encrypted);
    msg.setTunnelId(_config.getConfig(0).getSendTunnel());

    if (_log.shouldLog(Log.DEBUG))
      _log.debug("received encrypted, sending out " + _config + ": " + msg);
    RouterInfo ri = _nextHopCache;
    if (ri == null) ri = _context.netDb().lookupRouterInfoLocally(_config.getPeer(1));
    if (ri != null) {
      _nextHopCache = ri;
      send(msg, ri);
      return msg.getUniqueId();
    } else {
      // It should be rare to forget the router info for a peer in our own tunnel.
      if (_log.shouldLog(Log.WARN))
        _log.warn("lookup of " + _config.getPeer(1) + " required for " + msg);
      _context
          .netDb()
          .lookupRouterInfo(
              _config.getPeer(1),
              new SendJob(_context, msg),
              new FailedJob(_context),
              MAX_LOOKUP_TIME);
      return -1;
    }
  }
示例#2
0
 public OutboundReceiver(RouterContext ctx, TunnelCreatorConfig cfg) {
   _context = ctx;
   _log = ctx.logManager().getLog(OutboundReceiver.class);
   _config = cfg;
   _nextHopCache = _context.netDb().lookupRouterInfoLocally(_config.getPeer(1));
   // all createRateStat() in TunnelDispatcher
 }
示例#3
0
 /**
  * The next hop
  *
  * @return non-null
  * @since 0.9.3
  */
 public Hash getSendTo() {
   return _config.getPeer(1);
 }
示例#4
0
  private void runTest() {
    I2PAppContext ctx = I2PAppContext.getGlobalContext();
    Log log = ctx.logManager().getLog(getClass());

    List order = pickOrder(ctx);

    TunnelCreatorConfig cfg = createConfig(ctx);
    _replyRouter = new Hash();
    byte h[] = new byte[Hash.HASH_LENGTH];
    Arrays.fill(h, (byte) 0xFF);
    _replyRouter.setData(h);
    _replyTunnel = 42;

    // populate and encrypt the message
    BuildMessageGenerator gen = new BuildMessageGenerator();
    TunnelBuildMessage msg = new TunnelBuildMessage(ctx);
    for (int i = 0; i < BuildMessageGenerator.ORDER.length; i++) {
      int hop = ((Integer) order.get(i)).intValue();
      PublicKey key = null;
      if (hop < _pubKeys.length) key = _pubKeys[hop];
      gen.createRecord(i, hop, msg, cfg, _replyRouter, _replyTunnel, ctx, key);
    }
    gen.layeredEncrypt(ctx, msg, cfg, order);

    log.debug(
        "\n================================================================"
            + "\nMessage fully encrypted"
            + "\n================================================================");

    // now msg is fully encrypted, so lets go through the hops, decrypting and replying
    // as necessary

    BuildMessageProcessor proc = new BuildMessageProcessor(ctx);
    for (int i = 0; i < cfg.getLength(); i++) {
      // this not only decrypts the current hop's record, but encrypts the other records
      // with the reply key
      BuildRequestRecord req = proc.decrypt(ctx, msg, _peers[i], _privKeys[i]);
      if (req == null) {
        // no records matched the _peers[i], or the decryption failed
        throw new RuntimeException("foo @ " + i);
      }
      long ourId = req.readReceiveTunnelId();
      byte replyIV[] = req.readReplyIV();
      long nextId = req.readNextTunnelId();
      Hash nextPeer = req.readNextIdentity();
      boolean isInGW = req.readIsInboundGateway();
      boolean isOutEnd = req.readIsOutboundEndpoint();
      long time = req.readRequestTime();
      long now = (ctx.clock().now() / (60l * 60l * 1000l)) * (60 * 60 * 1000);
      int ourSlot = -1;

      BuildResponseRecord resp = new BuildResponseRecord();
      byte reply[] = resp.create(ctx, 0, req.readReplyKey(), req.readReplyIV(), -1);
      for (int j = 0; j < TunnelBuildMessage.RECORD_COUNT; j++) {
        if (msg.getRecord(j) == null) {
          ourSlot = j;
          msg.setRecord(j, new ByteArray(reply));
          break;
        }
      }

      log.debug(
          "Read slot "
              + ourSlot
              + " containing hop "
              + i
              + " @ "
              + _peers[i].toBase64()
              + " receives on "
              + ourId
              + " w/ replyIV "
              + Base64.encode(replyIV)
              + " sending to "
              + nextId
              + " on "
              + nextPeer.toBase64()
              + " inGW? "
              + isInGW
              + " outEnd? "
              + isOutEnd
              + " time difference "
              + (now - time));
    }

    log.debug(
        "\n================================================================"
            + "\nAll hops traversed and replies gathered"
            + "\n================================================================");

    // now all of the replies are populated, toss 'em into a reply message and handle it
    TunnelBuildReplyMessage reply = new TunnelBuildReplyMessage(ctx);
    for (int i = 0; i < TunnelBuildMessage.RECORD_COUNT; i++) reply.setRecord(i, msg.getRecord(i));

    BuildReplyHandler handler = new BuildReplyHandler();
    int statuses[] = handler.decrypt(ctx, reply, cfg, order);
    if (statuses == null) throw new RuntimeException("bar");
    boolean allAgree = true;
    for (int i = 0; i < cfg.getLength(); i++) {
      Hash peer = cfg.getPeer(i);
      int record = ((Integer) order.get(i)).intValue();
      if (statuses[record] != 0) allAgree = false;
      // else
      //    penalize peer according to the rejection cause
    }

    log.debug(
        "\n================================================================"
            + "\nAll peers agree? "
            + allAgree
            + "\n================================================================");
  }