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; } }
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; }