forked from I2P_Developers/i2p.i2p
* GarlicClove, CloveSet, GarlicMessageParser:
- Cleanup, reduce object churn, comment out unused code - Limit max cloves to 32
This commit is contained in:
@@ -13,11 +13,11 @@ import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.util.Date;
|
||||
|
||||
import net.i2p.I2PAppContext;
|
||||
import net.i2p.data.Certificate;
|
||||
import net.i2p.data.DataFormatException;
|
||||
import net.i2p.data.DataHelper;
|
||||
import net.i2p.data.DataStructureImpl;
|
||||
import net.i2p.router.RouterContext;
|
||||
import net.i2p.util.Log;
|
||||
|
||||
/**
|
||||
@@ -29,19 +29,17 @@ import net.i2p.util.Log;
|
||||
* @author jrandom
|
||||
*/
|
||||
public class GarlicClove extends DataStructureImpl {
|
||||
private final Log _log;
|
||||
//private final RouterContext _context;
|
||||
//private final Log _log;
|
||||
private final I2PAppContext _context;
|
||||
private DeliveryInstructions _instructions;
|
||||
private I2NPMessage _msg;
|
||||
private long _cloveId;
|
||||
private Date _expiration;
|
||||
private Certificate _certificate;
|
||||
private final I2NPMessageHandler _handler;
|
||||
|
||||
public GarlicClove(RouterContext context) {
|
||||
//_context = context;
|
||||
_log = context.logManager().getLog(GarlicClove.class);
|
||||
_handler = new I2NPMessageHandler(context);
|
||||
public GarlicClove(I2PAppContext context) {
|
||||
_context = context;
|
||||
//_log = context.logManager().getLog(GarlicClove.class);
|
||||
_cloveId = -1;
|
||||
}
|
||||
|
||||
@@ -58,8 +56,11 @@ public class GarlicClove extends DataStructureImpl {
|
||||
|
||||
/**
|
||||
* @deprecated unused, use byte array method to avoid copying
|
||||
* @throws UnsupportedOperationException always
|
||||
*/
|
||||
public void readBytes(InputStream in) throws DataFormatException, IOException {
|
||||
throw new UnsupportedOperationException();
|
||||
/****
|
||||
_instructions = new DeliveryInstructions();
|
||||
_instructions.readBytes(in);
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
@@ -78,17 +79,22 @@ public class GarlicClove extends DataStructureImpl {
|
||||
_certificate = Certificate.create(in);
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug("Read cert: " + _certificate);
|
||||
****/
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public int readBytes(byte source[], int offset) throws DataFormatException {
|
||||
int cur = offset;
|
||||
_instructions = new DeliveryInstructions();
|
||||
cur += _instructions.readBytes(source, cur);
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug("Read instructions: " + _instructions);
|
||||
//if (_log.shouldLog(Log.DEBUG))
|
||||
// _log.debug("Read instructions: " + _instructions);
|
||||
try {
|
||||
cur += _handler.readMessage(source, cur);
|
||||
_msg = _handler.lastRead();
|
||||
I2NPMessageHandler handler = new I2NPMessageHandler(_context);
|
||||
cur += handler.readMessage(source, cur);
|
||||
_msg = handler.lastRead();
|
||||
} catch (I2NPMessageException ime) {
|
||||
throw new DataFormatException("Unable to read the message from a garlic clove", ime);
|
||||
}
|
||||
@@ -96,21 +102,24 @@ public class GarlicClove extends DataStructureImpl {
|
||||
cur += 4;
|
||||
_expiration = DataHelper.fromDate(source, cur);
|
||||
cur += DataHelper.DATE_LENGTH;
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug("CloveID read: " + _cloveId + " expiration read: " + _expiration);
|
||||
//if (_log.shouldLog(Log.DEBUG))
|
||||
// _log.debug("CloveID read: " + _cloveId + " expiration read: " + _expiration);
|
||||
//_certificate = new Certificate();
|
||||
//cur += _certificate.readBytes(source, cur);
|
||||
_certificate = Certificate.create(source, cur);
|
||||
cur += _certificate.size();
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug("Read cert: " + _certificate);
|
||||
//if (_log.shouldLog(Log.DEBUG))
|
||||
// _log.debug("Read cert: " + _certificate);
|
||||
return cur - offset;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated unused, use byte array method to avoid copying
|
||||
* @throws UnsupportedOperationException always
|
||||
*/
|
||||
public void writeBytes(OutputStream out) throws DataFormatException, IOException {
|
||||
throw new UnsupportedOperationException();
|
||||
/****
|
||||
StringBuilder error = null;
|
||||
if (_instructions == null) {
|
||||
if (error == null) error = new StringBuilder();
|
||||
@@ -158,15 +167,19 @@ public class GarlicClove extends DataStructureImpl {
|
||||
_certificate.writeBytes(out);
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug("Written cert: " + _certificate);
|
||||
****/
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
@Override
|
||||
public byte[] toByteArray() {
|
||||
byte rv[] = new byte[estimateSize()];
|
||||
int offset = 0;
|
||||
offset += _instructions.writeBytes(rv, offset);
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug("Wrote instructions: " + _instructions);
|
||||
//if (_log.shouldLog(Log.DEBUG))
|
||||
// _log.debug("Wrote instructions: " + _instructions);
|
||||
//offset += _msg.toByteArray(rv);
|
||||
try {
|
||||
byte m[] = _msg.toByteArray();
|
||||
@@ -178,8 +191,10 @@ public class GarlicClove extends DataStructureImpl {
|
||||
DataHelper.toDate(rv, offset, _expiration.getTime());
|
||||
offset += DataHelper.DATE_LENGTH;
|
||||
offset += _certificate.writeBytes(rv, offset);
|
||||
if (offset != rv.length)
|
||||
_log.log(Log.CRIT, "Clove offset: " + offset + " but estimated length: " + rv.length);
|
||||
if (offset != rv.length) {
|
||||
Log log = I2PAppContext.getGlobalContext().logManager().getLog(GarlicClove.class);
|
||||
log.error("Clove offset: " + offset + " but estimated length: " + rv.length);
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
@@ -196,31 +211,31 @@ public class GarlicClove extends DataStructureImpl {
|
||||
if ( (obj == null) || !(obj instanceof GarlicClove))
|
||||
return false;
|
||||
GarlicClove clove = (GarlicClove)obj;
|
||||
return DataHelper.eq(getCertificate(), clove.getCertificate()) &&
|
||||
_cloveId == clove.getCloveId() &&
|
||||
DataHelper.eq(getData(), clove.getData()) &&
|
||||
DataHelper.eq(getExpiration(), clove.getExpiration()) &&
|
||||
DataHelper.eq(getInstructions(), clove.getInstructions());
|
||||
return DataHelper.eq(_certificate, clove._certificate) &&
|
||||
_cloveId == clove._cloveId &&
|
||||
DataHelper.eq(_msg, clove._msg) &&
|
||||
DataHelper.eq(_expiration, clove._expiration) &&
|
||||
DataHelper.eq(_instructions, clove._instructions);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return DataHelper.hashCode(getCertificate()) +
|
||||
(int)getCloveId() +
|
||||
DataHelper.hashCode(getData()) +
|
||||
DataHelper.hashCode(getExpiration()) +
|
||||
DataHelper.hashCode(getInstructions());
|
||||
return DataHelper.hashCode(_certificate) ^
|
||||
(int) _cloveId ^
|
||||
DataHelper.hashCode(_msg) ^
|
||||
DataHelper.hashCode(_expiration) ^
|
||||
DataHelper.hashCode(_instructions);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder buf = new StringBuilder(128);
|
||||
buf.append("[GarlicClove: ");
|
||||
buf.append("\n\tInstructions: ").append(getInstructions());
|
||||
buf.append("\n\tCertificate: ").append(getCertificate());
|
||||
buf.append("\n\tClove ID: ").append(getCloveId());
|
||||
buf.append("\n\tExpiration: ").append(getExpiration());
|
||||
buf.append("\n\tData: ").append(getData());
|
||||
buf.append("\n\tInstructions: ").append(_instructions);
|
||||
buf.append("\n\tCertificate: ").append(_certificate);
|
||||
buf.append("\n\tClove ID: ").append(_cloveId);
|
||||
buf.append("\n\tExpiration: ").append(_expiration);
|
||||
buf.append("\n\tData: ").append(_msg);
|
||||
buf.append("]");
|
||||
return buf.toString();
|
||||
}
|
||||
|
@@ -8,45 +8,47 @@ package net.i2p.router.message;
|
||||
*
|
||||
*/
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import net.i2p.data.Certificate;
|
||||
import net.i2p.data.i2np.GarlicClove;
|
||||
|
||||
/**
|
||||
* Wrap up the data contained in a CloveMessage after being decrypted
|
||||
* Wrap up the data contained in a GarlicMessage after being decrypted
|
||||
*
|
||||
*/
|
||||
class CloveSet {
|
||||
private final List<GarlicClove> _cloves;
|
||||
private Certificate _cert;
|
||||
private long _msgId;
|
||||
private long _expiration;
|
||||
private final GarlicClove[] _cloves;
|
||||
private final Certificate _cert;
|
||||
private final long _msgId;
|
||||
private final long _expiration;
|
||||
|
||||
public CloveSet() {
|
||||
_cloves = new ArrayList<GarlicClove>(4);
|
||||
_msgId = -1;
|
||||
_expiration = -1;
|
||||
/**
|
||||
* @param cloves non-null, all entries non-null
|
||||
* @param cert non-null
|
||||
*/
|
||||
public CloveSet(GarlicClove[] cloves, Certificate cert, long msgId, long expiration) {
|
||||
_cloves = cloves;
|
||||
_cert = cert;
|
||||
_msgId = msgId;
|
||||
_expiration = expiration;
|
||||
}
|
||||
|
||||
public int getCloveCount() { return _cloves.size(); }
|
||||
public void addClove(GarlicClove clove) { _cloves.add(clove); }
|
||||
public GarlicClove getClove(int index) { return _cloves.get(index); }
|
||||
public int getCloveCount() { return _cloves.length; }
|
||||
|
||||
/** @throws AIOOBE */
|
||||
public GarlicClove getClove(int index) { return _cloves[index]; }
|
||||
|
||||
public Certificate getCertificate() { return _cert; }
|
||||
public void setCertificate(Certificate cert) { _cert = cert; }
|
||||
|
||||
public long getMessageId() { return _msgId; }
|
||||
public void setMessageId(long id) { _msgId = id; }
|
||||
|
||||
public long getExpiration() { return _expiration; }
|
||||
public void setExpiration(long expiration) { _expiration = expiration; }
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder buf = new StringBuilder(128);
|
||||
buf.append("{");
|
||||
for (int i = 0; i < _cloves.size(); i++) {
|
||||
GarlicClove clove = _cloves.get(i);
|
||||
for (int i = 0; i < _cloves.length; i++) {
|
||||
GarlicClove clove = _cloves[i];
|
||||
if (clove.getData() != null)
|
||||
buf.append(clove.getData().getClass().getName()).append(", ");
|
||||
else
|
||||
|
@@ -28,6 +28,12 @@ class GarlicMessageParser {
|
||||
private final Log _log;
|
||||
private final RouterContext _context;
|
||||
|
||||
/**
|
||||
* Huge limit just to reduce chance of trouble. Typ. usage is 3.
|
||||
* As of 0.9.12. Was 255.
|
||||
*/
|
||||
private static final int MAX_CLOVES = 32;
|
||||
|
||||
public GarlicMessageParser(RouterContext context) {
|
||||
_context = context;
|
||||
_log = _context.logManager().getLog(GarlicMessageParser.class);
|
||||
@@ -64,18 +70,19 @@ class GarlicMessageParser {
|
||||
private CloveSet readCloveSet(byte data[]) throws DataFormatException {
|
||||
int offset = 0;
|
||||
|
||||
CloveSet set = new CloveSet();
|
||||
|
||||
int numCloves = (int)DataHelper.fromLong(data, offset, 1);
|
||||
offset++;
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug("# cloves to read: " + numCloves);
|
||||
if (numCloves <= 0 || numCloves > MAX_CLOVES)
|
||||
throw new DataFormatException("bad clove count " + numCloves);
|
||||
GarlicClove[] cloves = new GarlicClove[numCloves];
|
||||
for (int i = 0; i < numCloves; i++) {
|
||||
//if (_log.shouldLog(Log.DEBUG))
|
||||
// _log.debug("Reading clove " + i);
|
||||
GarlicClove clove = new GarlicClove(_context);
|
||||
offset += clove.readBytes(data, offset);
|
||||
set.addClove(clove);
|
||||
cloves[i] = clove;
|
||||
//if (_log.shouldLog(Log.DEBUG))
|
||||
// _log.debug("After reading clove " + i);
|
||||
}
|
||||
@@ -85,11 +92,10 @@ class GarlicMessageParser {
|
||||
offset += cert.size();
|
||||
long msgId = DataHelper.fromLong(data, offset, 4);
|
||||
offset += 4;
|
||||
Date expiration = DataHelper.fromDate(data, offset);
|
||||
//Date expiration = DataHelper.fromDate(data, offset);
|
||||
long expiration = DataHelper.fromLong(data, offset, 8);
|
||||
|
||||
set.setCertificate(cert);
|
||||
set.setMessageId(msgId);
|
||||
set.setExpiration(expiration.getTime());
|
||||
CloveSet set = new CloveSet(cloves, cert, msgId, expiration);
|
||||
return set;
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user