Exemplo n.º 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;
    }
  }
Exemplo n.º 2
0
 public TunnelGatewayZeroHop(RouterContext context, TunnelCreatorConfig config) {
   super(context, null, null, null);
   _config = config;
   if (config.isInbound())
     _inDistributor = new InboundMessageDistributor(context, config.getDestination());
   else _outDistributor = new OutboundMessageDistributor(context, 400);
 }
Exemplo n.º 3
0
  private TunnelCreatorConfig configOutbound(I2PAppContext ctx) {
    _peers = new Hash[4];
    _pubKeys = new PublicKey[_peers.length];
    _privKeys = new PrivateKey[_peers.length];
    for (int i = 0; i < _peers.length; i++) {
      byte buf[] = new byte[Hash.HASH_LENGTH];
      Arrays.fill(buf, (byte) i); // consistent for repeatability
      Hash h = new Hash(buf);
      _peers[i] = h;
      Object kp[] = ctx.keyGenerator().generatePKIKeypair();
      _pubKeys[i] = (PublicKey) kp[0];
      _privKeys[i] = (PrivateKey) kp[1];
    }

    TunnelCreatorConfig cfg = new TunnelCreatorConfig(null, _peers.length, false);
    long now = ctx.clock().now();
    // peers[] is ordered endpoint first, but cfg.getPeer() is ordered gateway first
    for (int i = 0; i < _peers.length; i++) {
      cfg.setPeer(i, _peers[i]);
      HopConfig hop = cfg.getConfig(i);
      hop.setExpiration(now + 10 * 60 * 1000);
      hop.setIVKey(ctx.keyGenerator().generateSessionKey());
      hop.setLayerKey(ctx.keyGenerator().generateSessionKey());
      hop.setReplyKey(ctx.keyGenerator().generateSessionKey());
      byte iv[] = new byte[BuildRequestRecord.IV_SIZE];
      Arrays.fill(iv, (byte) i); // consistent for repeatability
      hop.setReplyIV(new ByteArray(iv));
      hop.setReceiveTunnelId(new TunnelId(i + 1));
    }
    return cfg;
  }
Exemplo n.º 4
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
 }
Exemplo n.º 5
0
 /**
  * Add a message to be sent down the tunnel (immediately forwarding it to the {@link
  * InboundMessageDistributor} or {@link OutboundMessageDistributor}, as necessary).
  *
  * @param msg message to be sent through the tunnel
  * @param toRouter router to send to after the endpoint (or null for endpoint processing)
  * @param toTunnel tunnel to send to after the endpoint (or null for endpoint or router
  *     processing)
  */
 @Override
 public void add(I2NPMessage msg, Hash toRouter, TunnelId toTunnel) {
   if (_log.shouldLog(Log.DEBUG))
     _log.debug(
         "zero hop gateway: distribute "
             + (_config.isInbound() ? "inbound" : " outbound")
             + " to "
             + (toRouter != null ? toRouter.toBase64().substring(0, 4) : "")
             + "."
             + (toTunnel != null ? toTunnel.getTunnelId() + "" : "")
             + ": "
             + msg);
   if (_config.isInbound()) {
     _inDistributor.distribute(msg, toRouter, toTunnel);
   } else {
     _outDistributor.distribute(msg, toRouter, toTunnel);
   }
   _config.incrementProcessedMessages();
 }
Exemplo n.º 6
0
 private void send(TunnelDataMessage msg, RouterInfo ri) {
   if (_log.shouldLog(Log.DEBUG))
     _log.debug("forwarding encrypted data out " + _config + ": " + msg.getUniqueId());
   OutNetMessage m = new OutNetMessage(_context);
   m.setMessage(msg);
   m.setExpiration(msg.getMessageExpiration());
   m.setTarget(ri);
   m.setPriority(PRIORITY);
   _context.outNetMessagePool().add(m);
   _config.incrementProcessedMessages();
 }
Exemplo n.º 7
0
 /**
  * Add a message to be sent down the tunnel, where we are the inbound gateway. This requires
  * converting the message included in the TGM from an UnknownI2NPMessage to the correct message
  * class. See TunnelGatewayMessage for details.
  *
  * @param msg message received to be sent through the tunnel
  */
 @Override
 public void add(TunnelGatewayMessage msg) {
   I2NPMessage imsg = msg.getMessage();
   if (_config.isInbound()) {
     if (imsg instanceof UnknownI2NPMessage) {
       // Do the delayed deserializing - convert to a standard message class
       try {
         UnknownI2NPMessage umsg = (UnknownI2NPMessage) imsg;
         imsg = umsg.convert();
       } catch (I2NPMessageException ime) {
         if (_log.shouldLog(Log.WARN))
           _log.warn("Unable to convert to std. msg. class at zero-hop IBGW", ime);
         return;
       }
     }
   }
   add(imsg, null, null);
 }
Exemplo n.º 8
0
  @Override
  public String toString() {
    StringBuilder buf = new StringBuilder(64);
    if (_receiveTunnelId != null) {
      buf.append("recv on ");
      buf.append(DataHelper.fromLong(_receiveTunnelId, 0, 4));
      buf.append(" ");
    }

    if (_sendTo != null) {
      buf.append("send to ").append(_sendTo.toBase64().substring(0, 4)).append(":");
      if (_sendTunnelId != null) buf.append(DataHelper.fromLong(_sendTunnelId, 0, 4));
    }

    buf.append(" expiring on ").append(TunnelCreatorConfig.format(_expiration));
    buf.append(" having transferred ").append(_messagesProcessed).append("KB");
    return buf.toString();
  }
Exemplo n.º 9
0
 /**
  * The next hop
  *
  * @return non-null
  * @since 0.9.3
  */
 public Hash getSendTo() {
   return _config.getPeer(1);
 }
Exemplo n.º 10
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================================================================");
  }