I2P Address: [http://git.idk.i2p]

Skip to content
Snippets Groups Projects
Commit 9d80aff9 authored by zzz's avatar zzz
Browse files

* GarlicClove, CloveSet, GarlicMessageParser:

   - Cleanup, reduce object churn, comment out unused code
   - Limit max cloves to 32
parent a0724dc0
No related branches found
No related tags found
No related merge requests found
......@@ -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;
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment