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