ByteCache: Move all 16/32 byte users to SimpleByteCache;

increase SimpleByteCache default size.
This commit is contained in:
zzz
2012-09-02 12:31:08 +00:00
parent 4360284355
commit c48aca8d5c
10 changed files with 55 additions and 77 deletions

View File

@@ -16,9 +16,9 @@ import net.i2p.data.Hash;
import net.i2p.data.RouterIdentity;
import net.i2p.data.SessionKey;
import net.i2p.data.Signature;
import net.i2p.util.ByteCache;
import net.i2p.util.Addresses;
import net.i2p.util.Log;
import net.i2p.util.SimpleByteCache;
/**
* Big ol' class to do all our packet formatting. The UDPPackets generated are
@@ -102,9 +102,6 @@ class PacketBuilder {
private final Log _log;
private final UDPTransport _transport;
private static final ByteCache _ivCache = ByteCache.getInstance(64, UDPPacket.IV_SIZE);
private static final ByteCache _hmacCache = ByteCache.getInstance(64, Hash.HASH_LENGTH);
/**
* For debugging and stats only - does not go out on the wire.
* These are chosen to be higher than the highest I2NP message type,
@@ -607,12 +604,12 @@ class PacketBuilder {
// ok, now the full data is in there, but we also need to encrypt
// the signature, which means we need the IV
ByteArray iv = _ivCache.acquire();
_context.random().nextBytes(iv.getData());
byte[] iv = SimpleByteCache.acquire(UDPPacket.IV_SIZE);
_context.random().nextBytes(iv);
int encrWrite = Signature.SIGNATURE_BYTES + 8;
int sigBegin = off - encrWrite;
_context.aes().encrypt(data, sigBegin, data, sigBegin, state.getCipherKey(), iv.getData(), encrWrite);
_context.aes().encrypt(data, sigBegin, data, sigBegin, state.getCipherKey(), iv, encrWrite);
// pad up so we're on the encryption boundary
if ( (off % 16) != 0)
@@ -620,7 +617,7 @@ class PacketBuilder {
packet.getPacket().setLength(off);
authenticate(packet, ourIntroKey, ourIntroKey, iv);
setTo(packet, to, state.getSentPort());
_ivCache.release(iv);
SimpleByteCache.release(iv);
packet.setMessageType(TYPE_CREAT);
return packet;
}
@@ -1290,10 +1287,10 @@ class PacketBuilder {
* @param macKey key to generate the, er, MAC
*/
private void authenticate(UDPPacket packet, SessionKey cipherKey, SessionKey macKey) {
ByteArray iv = _ivCache.acquire();
_context.random().nextBytes(iv.getData());
byte[] iv = SimpleByteCache.acquire(UDPPacket.IV_SIZE);
_context.random().nextBytes(iv);
authenticate(packet, cipherKey, macKey, iv);
_ivCache.release(iv);
SimpleByteCache.release(iv);
}
/**
@@ -1308,38 +1305,38 @@ class PacketBuilder {
* @param macKey key to generate the, er, MAC
* @param iv IV to deliver
*/
private void authenticate(UDPPacket packet, SessionKey cipherKey, SessionKey macKey, ByteArray iv) {
private void authenticate(UDPPacket packet, SessionKey cipherKey, SessionKey macKey, byte[] iv) {
long before = System.currentTimeMillis();
int encryptOffset = packet.getPacket().getOffset() + UDPPacket.IV_SIZE + UDPPacket.MAC_SIZE;
int encryptSize = packet.getPacket().getLength() - UDPPacket.IV_SIZE - UDPPacket.MAC_SIZE - packet.getPacket().getOffset();
byte data[] = packet.getPacket().getData();
_context.aes().encrypt(data, encryptOffset, data, encryptOffset, cipherKey, iv.getData(), encryptSize);
_context.aes().encrypt(data, encryptOffset, data, encryptOffset, cipherKey, iv, encryptSize);
// ok, now we need to prepare things for the MAC, which requires reordering
int off = packet.getPacket().getOffset();
System.arraycopy(data, encryptOffset, data, off, encryptSize);
off += encryptSize;
System.arraycopy(iv.getData(), 0, data, off, UDPPacket.IV_SIZE);
System.arraycopy(iv, 0, data, off, UDPPacket.IV_SIZE);
off += UDPPacket.IV_SIZE;
DataHelper.toLong(data, off, 2, encryptSize ^ PROTOCOL_VERSION);
int hmacOff = packet.getPacket().getOffset();
int hmacLen = encryptSize + UDPPacket.IV_SIZE + 2;
//Hash hmac = _context.hmac().calculate(macKey, data, hmacOff, hmacLen);
ByteArray ba = _hmacCache.acquire();
_context.hmac().calculate(macKey, data, hmacOff, hmacLen, ba.getData(), 0);
byte[] ba = SimpleByteCache.acquire(Hash.HASH_LENGTH);
_context.hmac().calculate(macKey, data, hmacOff, hmacLen, ba, 0);
if (_log.shouldLog(Log.DEBUG))
_log.debug("Authenticating " + packet.getPacket().getLength() +
"\nIV: " + Base64.encode(iv.getData()) +
"\nraw mac: " + Base64.encode(ba.getData()) +
"\nIV: " + Base64.encode(iv) +
"\nraw mac: " + Base64.encode(ba) +
"\nMAC key: " + macKey);
// ok, now lets put it back where it belongs...
System.arraycopy(data, hmacOff, data, encryptOffset, encryptSize);
//System.arraycopy(hmac.getData(), 0, data, hmacOff, UDPPacket.MAC_SIZE);
System.arraycopy(ba.getData(), 0, data, hmacOff, UDPPacket.MAC_SIZE);
System.arraycopy(iv.getData(), 0, data, hmacOff + UDPPacket.MAC_SIZE, UDPPacket.IV_SIZE);
_hmacCache.release(ba);
System.arraycopy(ba, 0, data, hmacOff, UDPPacket.MAC_SIZE);
System.arraycopy(iv, 0, data, hmacOff + UDPPacket.MAC_SIZE, UDPPacket.IV_SIZE);
SimpleByteCache.release(ba);
long timeToAuth = System.currentTimeMillis() - before;
_context.statManager().addRateData("udp.packetAuthTime", timeToAuth, timeToAuth);
if (timeToAuth > 100)

View File

@@ -5,7 +5,7 @@ import net.i2p.data.DataHelper;
import net.i2p.router.RouterContext;
import net.i2p.router.util.DecayingBloomFilter;
import net.i2p.router.util.DecayingHashSet;
import net.i2p.util.ByteCache;
import net.i2p.util.SimpleByteCache;
/**
* Manage the IV validation for all of the router's tunnels by way of a big
@@ -15,7 +15,6 @@ import net.i2p.util.ByteCache;
class BloomFilterIVValidator implements IVValidator {
private final RouterContext _context;
private final DecayingBloomFilter _filter;
private final ByteCache _ivXorCache = ByteCache.getInstance(32, HopProcessor.IV_LENGTH);
/**
* After 2*halflife, an entry is completely forgotten from the bloom filter.
@@ -57,10 +56,10 @@ class BloomFilterIVValidator implements IVValidator {
}
public boolean receiveIV(byte ivData[], int ivOffset, byte payload[], int payloadOffset) {
ByteArray buf = _ivXorCache.acquire();
DataHelper.xor(ivData, ivOffset, payload, payloadOffset, buf.getData(), 0, HopProcessor.IV_LENGTH);
boolean dup = _filter.add(buf.getData());
_ivXorCache.release(buf);
byte[] buf = SimpleByteCache.acquire(HopProcessor.IV_LENGTH);
DataHelper.xor(ivData, ivOffset, payload, payloadOffset, buf, 0, HopProcessor.IV_LENGTH);
boolean dup = _filter.add(buf);
SimpleByteCache.release(buf);
if (dup) _context.statManager().addRateData("tunnel.duplicateIV", 1);
return !dup; // return true if it is OK, false if it isn't
}

View File

@@ -2,7 +2,6 @@ package net.i2p.router.tunnel;
import net.i2p.I2PAppContext;
import net.i2p.data.Hash;
import net.i2p.util.ByteCache;
import net.i2p.util.Log;
/**
@@ -29,7 +28,6 @@ class HopProcessor {
*/
static final boolean USE_DOUBLE_IV_ENCRYPTION = true;
static final int IV_LENGTH = 16;
private static final ByteCache _cache = ByteCache.getInstance(128, IV_LENGTH);
/** @deprecated unused */
public HopProcessor(I2PAppContext ctx, HopConfig config) {

View File

@@ -3,8 +3,8 @@ package net.i2p.router.tunnel;
import net.i2p.data.ByteArray;
import net.i2p.data.Hash;
import net.i2p.router.RouterContext;
import net.i2p.util.ByteCache;
import net.i2p.util.Log;
import net.i2p.util.SimpleByteCache;
/**
* Receive the inbound tunnel message, removing all of the layers
@@ -21,7 +21,6 @@ class InboundEndpointProcessor {
private final IVValidator _validator;
static final boolean USE_ENCRYPTION = HopProcessor.USE_ENCRYPTION;
private static final ByteCache _cache = ByteCache.getInstance(128, HopProcessor.IV_LENGTH);
/** @deprecated unused */
public InboundEndpointProcessor(RouterContext ctx, TunnelCreatorConfig cfg) {
@@ -54,8 +53,7 @@ class InboundEndpointProcessor {
return false;
}
ByteArray ba = _cache.acquire();
byte iv[] = ba.getData(); //new byte[HopProcessor.IV_LENGTH];
byte iv[] = SimpleByteCache.acquire(HopProcessor.IV_LENGTH);
System.arraycopy(orig, offset, iv, 0, iv.length);
//if (_config.getLength() > 1)
// _log.debug("IV at inbound endpoint before decrypt: " + Base64.encode(iv));
@@ -64,7 +62,7 @@ class InboundEndpointProcessor {
if (!ok) {
if (_log.shouldLog(Log.WARN))
_log.warn("Invalid IV, dropping at IBEP " + _config);
_cache.release(ba);
SimpleByteCache.release(iv);
return false;
}
@@ -72,7 +70,7 @@ class InboundEndpointProcessor {
if (USE_ENCRYPTION)
decrypt(_context, _config, iv, orig, offset, length);
_cache.release(ba);
SimpleByteCache.release(iv);
if (_config.getLength() > 0) {
int rtt = 0; // dunno... may not be related to an rtt
@@ -91,8 +89,7 @@ class InboundEndpointProcessor {
*/
private void decrypt(RouterContext ctx, TunnelCreatorConfig cfg, byte iv[], byte orig[], int offset, int length) {
//Log log = ctx.logManager().getLog(OutboundGatewayProcessor.class);
ByteArray ba = _cache.acquire();
byte cur[] = ba.getData(); // new byte[HopProcessor.IV_LENGTH]; // so we dont malloc
byte cur[] = SimpleByteCache.acquire(HopProcessor.IV_LENGTH);
for (int i = cfg.getLength()-2; i >= 0; i--) { // dont include the endpoint, since that is the creator
OutboundGatewayProcessor.decrypt(ctx, iv, orig, offset, length, cur, cfg.getConfig(i));
//if (log.shouldLog(Log.DEBUG)) {
@@ -100,7 +97,7 @@ class InboundEndpointProcessor {
//log.debug("hop " + i + ": " + Base64.encode(orig, offset + HopProcessor.IV_LENGTH, length - HopProcessor.IV_LENGTH));
//}
}
_cache.release(ba);
SimpleByteCache.release(cur);
}
}

View File

@@ -3,8 +3,8 @@ package net.i2p.router.tunnel;
import net.i2p.I2PAppContext;
import net.i2p.data.Base64;
import net.i2p.data.ByteArray;
import net.i2p.util.ByteCache;
import net.i2p.util.Log;
import net.i2p.util.SimpleByteCache;
/**
* Turn the preprocessed tunnel data into something that can be delivered to the
@@ -18,7 +18,6 @@ class OutboundGatewayProcessor {
private final TunnelCreatorConfig _config;
static final boolean USE_ENCRYPTION = HopProcessor.USE_ENCRYPTION;
private static final ByteCache _cache = ByteCache.getInstance(128, HopProcessor.IV_LENGTH);
public OutboundGatewayProcessor(I2PAppContext ctx, TunnelCreatorConfig cfg) {
_context = ctx;
@@ -35,8 +34,7 @@ class OutboundGatewayProcessor {
* @param length how much of orig can we write to (must be a multiple of 16).
*/
public void process(byte orig[], int offset, int length) {
ByteArray ba = _cache.acquire();
byte iv[] = ba.getData(); // new byte[HopProcessor.IV_LENGTH];
byte iv[] = SimpleByteCache.acquire(HopProcessor.IV_LENGTH);
//_context.random().nextBytes(iv);
//System.arraycopy(iv, 0, orig, offset, HopProcessor.IV_LENGTH);
System.arraycopy(orig, offset, iv, 0, HopProcessor.IV_LENGTH);
@@ -49,7 +47,7 @@ class OutboundGatewayProcessor {
decrypt(_context, _config, iv, orig, offset, length);
if (_log.shouldLog(Log.DEBUG))
_log.debug("finished processing the preprocessed data");
_cache.release(ba);
SimpleByteCache.release(iv);
}
/**
@@ -58,8 +56,7 @@ class OutboundGatewayProcessor {
*/
private void decrypt(I2PAppContext ctx, TunnelCreatorConfig cfg, byte iv[], byte orig[], int offset, int length) {
Log log = ctx.logManager().getLog(OutboundGatewayProcessor.class);
ByteArray ba = _cache.acquire();
byte cur[] = ba.getData(); // new byte[HopProcessor.IV_LENGTH]; // so we dont malloc
byte cur[] = SimpleByteCache.acquire(HopProcessor.IV_LENGTH);
for (int i = cfg.getLength()-1; i >= 1; i--) { // dont include hop 0, since that is the creator
decrypt(ctx, iv, orig, offset, length, cur, cfg.getConfig(i));
if (log.shouldLog(Log.DEBUG)) {
@@ -67,7 +64,7 @@ class OutboundGatewayProcessor {
//log.debug("hop " + i + ": " + Base64.encode(orig, offset + HopProcessor.IV_LENGTH, length - HopProcessor.IV_LENGTH));
}
}
_cache.release(ba);
SimpleByteCache.release(cur);
}
/**

View File

@@ -9,6 +9,7 @@ import net.i2p.data.Hash;
import net.i2p.router.RouterContext;
import net.i2p.util.ByteCache;
import net.i2p.util.Log;
import net.i2p.util.SimpleByteCache;
/**
* Do the simplest thing possible for preprocessing - for each message available,
@@ -33,9 +34,6 @@ class TrivialPreprocessor implements TunnelGateway.QueuePreprocessor {
*/
protected static final ByteCache _dataCache = ByteCache.getInstance(32, PREPROCESSED_SIZE);
private static final ByteCache _ivCache = ByteCache.getInstance(128, IV_SIZE);
private static final ByteCache _hashCache = ByteCache.getInstance(128, Hash.HASH_LENGTH);
public TrivialPreprocessor(RouterContext ctx) {
_context = ctx;
_log = ctx.logManager().getLog(getClass());
@@ -63,16 +61,15 @@ class TrivialPreprocessor implements TunnelGateway.QueuePreprocessor {
* @param fragmentLength fragments[0:fragmentLength] is used
*/
protected void preprocess(byte fragments[], int fragmentLength) {
ByteArray ivBuf = _ivCache.acquire();
byte iv[] = ivBuf.getData(); // new byte[IV_SIZE];
byte iv[] = SimpleByteCache.acquire(IV_SIZE);
_context.random().nextBytes(iv);
// payload ready, now H(instructions+payload+IV)
System.arraycopy(iv, 0, fragments, fragmentLength, IV_SIZE);
ByteArray hashBuf = _hashCache.acquire();
byte[] hashBuf = SimpleByteCache.acquire(Hash.HASH_LENGTH);
//Hash h = _context.sha().calculateHash(fragments, 0, fragmentLength + IV_SIZE);
_context.sha().calculateHash(fragments, 0, fragmentLength + IV_SIZE, hashBuf.getData(), 0);
_context.sha().calculateHash(fragments, 0, fragmentLength + IV_SIZE, hashBuf, 0);
//Hash h = _context.sha().calculateHash(target, 0, offset + IV_SIZE);
//_log.debug("before shift: " + Base64.encode(target));
@@ -91,12 +88,12 @@ class TrivialPreprocessor implements TunnelGateway.QueuePreprocessor {
System.arraycopy(iv, 0, fragments, offset, IV_SIZE);
offset += IV_SIZE;
//System.arraycopy(h.getData(), 0, fragments, offset, 4);
System.arraycopy(hashBuf.getData(), 0, fragments, offset, 4);
System.arraycopy(hashBuf, 0, fragments, offset, 4);
offset += 4;
//_log.debug("before pad : " + Base64.encode(target));
_hashCache.release(hashBuf);
_ivCache.release(ivBuf);
SimpleByteCache.release(hashBuf);
SimpleByteCache.release(iv);
// fits in a single message, so may be smaller than the full size
int numPadBytes = PREPROCESSED_SIZE // max