2004-10-07 jrandom
* Reimplement the I2NP reading with less temporary memory allocation. There is still significant GC churn, especially under load, but this should help. * Catch some oddball errors in the transport (message timeout while establishing).
This commit is contained in:
@ -270,6 +270,22 @@ public class DataHelper {
|
||||
val[numBytes-i-1] = (byte)(value >>> (i*8));
|
||||
return val;
|
||||
}
|
||||
|
||||
public static long fromLong(byte src[], int offset, int numBytes) {
|
||||
if ( (src == null) || (src.length == 0) )
|
||||
return 0;
|
||||
|
||||
long rv = 0;
|
||||
for (int i = 0; i < numBytes; i++) {
|
||||
long cur = src[offset+i] & 0xFF;
|
||||
if (cur < 0) cur = cur+256;
|
||||
cur = (cur << (8*(numBytes-i-1)));
|
||||
rv += cur;
|
||||
}
|
||||
if (rv < 0)
|
||||
throw new IllegalArgumentException("wtf, fromLong got a negative? " + rv + ": offset="+ offset +" numBytes="+numBytes);
|
||||
return rv;
|
||||
}
|
||||
|
||||
public static void main(String args[]) {
|
||||
for (int i = 0; i <= 0xFF; i++)
|
||||
@ -296,6 +312,10 @@ public class DataHelper {
|
||||
byte extract[] = toLong(numBytes, value);
|
||||
if (!eq(written, extract))
|
||||
throw new RuntimeException("testLong("+numBytes+","+value+") FAILED");
|
||||
|
||||
long read = fromLong(extract, 0, extract.length);
|
||||
if (read != value)
|
||||
throw new RuntimeException("testLong("+numBytes+","+value+") FAILED on read (" + read + ")");
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e.getMessage());
|
||||
}
|
||||
@ -336,6 +356,13 @@ public class DataHelper {
|
||||
else
|
||||
return toLong(DATE_LENGTH, date.getTime());
|
||||
}
|
||||
public static Date fromDate(byte src[], int offset) throws IllegalArgumentException {
|
||||
long when = fromLong(src, offset, DATE_LENGTH);
|
||||
if (when <= 0)
|
||||
return null;
|
||||
else
|
||||
return new Date(when);
|
||||
}
|
||||
|
||||
public static final int DATE_LENGTH = 8;
|
||||
|
||||
@ -671,9 +698,12 @@ public class DataHelper {
|
||||
|
||||
/** decompress the GZIP compressed data (returning null on error) */
|
||||
public static byte[] decompress(byte orig[]) throws IOException {
|
||||
return decompress(orig, 0, orig.length);
|
||||
}
|
||||
public static byte[] decompress(byte orig[], int offset, int length) throws IOException {
|
||||
if ((orig == null) || (orig.length <= 0)) return orig;
|
||||
GZIPInputStream in = new GZIPInputStream(new ByteArrayInputStream(orig), orig.length);
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream(orig.length * 2);
|
||||
GZIPInputStream in = new GZIPInputStream(new ByteArrayInputStream(orig, offset, length), length);
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream(length * 2);
|
||||
byte buf[] = new byte[4 * 1024];
|
||||
while (true) {
|
||||
int read = in.read(buf);
|
||||
|
@ -33,9 +33,8 @@ public class Signature extends DataStructureImpl {
|
||||
FAKE_SIGNATURE[i] = 0x00;
|
||||
}
|
||||
|
||||
public Signature() {
|
||||
setData(null);
|
||||
}
|
||||
public Signature() { this(null); }
|
||||
public Signature(byte data[]) { setData(data); }
|
||||
|
||||
public byte[] getData() {
|
||||
return _data;
|
||||
|
@ -29,9 +29,8 @@ public class SigningPrivateKey extends DataStructureImpl {
|
||||
|
||||
public final static int KEYSIZE_BYTES = 20;
|
||||
|
||||
public SigningPrivateKey() {
|
||||
setData(null);
|
||||
}
|
||||
public SigningPrivateKey() { this(null); }
|
||||
public SigningPrivateKey(byte data[]) { setData(data); }
|
||||
|
||||
public byte[] getData() {
|
||||
return _data;
|
||||
|
@ -29,9 +29,8 @@ public class SigningPublicKey extends DataStructureImpl {
|
||||
|
||||
public final static int KEYSIZE_BYTES = 128;
|
||||
|
||||
public SigningPublicKey() {
|
||||
setData(null);
|
||||
}
|
||||
public SigningPublicKey() { this(null); }
|
||||
public SigningPublicKey(byte data[]) { setData(data); }
|
||||
|
||||
public byte[] getData() {
|
||||
return _data;
|
||||
|
@ -35,12 +35,25 @@ public class TunnelId extends DataStructureImpl {
|
||||
public final static int TYPE_PARTICIPANT = 3;
|
||||
|
||||
public TunnelId() {
|
||||
setTunnelId(-1);
|
||||
setType(TYPE_UNSPECIFIED);
|
||||
_tunnelId = -1;
|
||||
_type = TYPE_UNSPECIFIED;
|
||||
}
|
||||
public TunnelId(long id) {
|
||||
if (id <= 0) throw new IllegalArgumentException("wtf, tunnelId " + id);
|
||||
_tunnelId = id;
|
||||
_type = TYPE_UNSPECIFIED;
|
||||
}
|
||||
public TunnelId(long id, int type) {
|
||||
if (id <= 0) throw new IllegalArgumentException("wtf, tunnelId " + id);
|
||||
_tunnelId = id;
|
||||
_type = type;
|
||||
}
|
||||
|
||||
public long getTunnelId() { return _tunnelId; }
|
||||
public void setTunnelId(long id) { _tunnelId = id; }
|
||||
public void setTunnelId(long id) {
|
||||
_tunnelId = id;
|
||||
if (id <= 0) throw new IllegalArgumentException("wtf, tunnelId " + id);
|
||||
}
|
||||
|
||||
/**
|
||||
* is this tunnel inbound, outbound, or a participant (kept in memory only and used only for the router).s
|
||||
|
@ -1,4 +1,11 @@
|
||||
$Id: history.txt,v 1.37 2004/10/06 16:03:52 jrandom Exp $
|
||||
$Id: history.txt,v 1.38 2004/10/07 14:19:52 jrandom Exp $
|
||||
|
||||
2004-10-07 jrandom
|
||||
* Reimplement the I2NP reading with less temporary memory allocation.
|
||||
There is still significant GC churn, especially under load, but this
|
||||
should help.
|
||||
* Catch some oddball errors in the transport (message timeout while
|
||||
establishing).
|
||||
|
||||
2004-10-07 jrandom
|
||||
* Expire queued messages even when the writer is blocked.
|
||||
|
@ -39,19 +39,15 @@ public class DataMessage extends I2NPMessageImpl {
|
||||
|
||||
public int getSize() { return _data.length; }
|
||||
|
||||
public void readMessage(InputStream in, int type) throws I2NPMessageException, IOException {
|
||||
public void readMessage(byte data[], int offset, int dataSize, int type) throws I2NPMessageException, IOException {
|
||||
if (type != MESSAGE_TYPE) throw new I2NPMessageException("Message type is incorrect for this message");
|
||||
try {
|
||||
int size = (int)DataHelper.readLong(in, 4);
|
||||
if ( (size <= 0) || (size > MAX_SIZE) )
|
||||
throw new I2NPMessageException("wtf, size out of range? " + size);
|
||||
_data = new byte[size];
|
||||
int read = read(in, _data);
|
||||
if (read != size)
|
||||
throw new DataFormatException("Not enough bytes to read (read = " + read + ", expected = " + size + ")");
|
||||
} catch (DataFormatException dfe) {
|
||||
throw new I2NPMessageException("Unable to load the message data", dfe);
|
||||
}
|
||||
int curIndex = offset;
|
||||
long size = DataHelper.fromLong(data, curIndex, 4);
|
||||
curIndex += 4;
|
||||
if (size > 64*1024)
|
||||
throw new I2NPMessageException("wtf, size=" + size);
|
||||
_data = new byte[(int)size];
|
||||
System.arraycopy(data, curIndex, _data, 0, (int)size);
|
||||
}
|
||||
|
||||
/** calculate the message body's length (not including the header and footer */
|
||||
|
@ -124,35 +124,53 @@ public class DatabaseLookupMessage extends I2NPMessageImpl {
|
||||
_dontIncludePeers = null;
|
||||
}
|
||||
|
||||
public void readMessage(InputStream in, int type) throws I2NPMessageException, IOException {
|
||||
public void readMessage(byte data[], int offset, int dataSize, int type) throws I2NPMessageException, IOException {
|
||||
if (type != MESSAGE_TYPE) throw new I2NPMessageException("Message type is incorrect for this message");
|
||||
try {
|
||||
_key = new Hash();
|
||||
_key.readBytes(in);
|
||||
_fromHash = new Hash();
|
||||
_fromHash.readBytes(in);
|
||||
Boolean val = DataHelper.readBoolean(in);
|
||||
if (val == null)
|
||||
int curIndex = offset;
|
||||
|
||||
byte keyData[] = new byte[Hash.HASH_LENGTH];
|
||||
System.arraycopy(data, curIndex, keyData, 0, Hash.HASH_LENGTH);
|
||||
curIndex += Hash.HASH_LENGTH;
|
||||
_key = new Hash(keyData);
|
||||
|
||||
byte fromData[] = new byte[Hash.HASH_LENGTH];
|
||||
System.arraycopy(data, curIndex, fromData, 0, Hash.HASH_LENGTH);
|
||||
curIndex += Hash.HASH_LENGTH;
|
||||
_fromHash = new Hash(fromData);
|
||||
|
||||
boolean tunnelSpecified = false;
|
||||
switch (data[curIndex]) {
|
||||
case DataHelper.BOOLEAN_TRUE:
|
||||
tunnelSpecified = true;
|
||||
break;
|
||||
case DataHelper.BOOLEAN_FALSE:
|
||||
tunnelSpecified = false;
|
||||
break;
|
||||
default:
|
||||
throw new I2NPMessageException("Tunnel must be explicitly specified (or not)");
|
||||
boolean tunnelSpecified = val.booleanValue();
|
||||
if (tunnelSpecified) {
|
||||
_replyTunnel = new TunnelId();
|
||||
_replyTunnel.readBytes(in);
|
||||
}
|
||||
int numPeers = (int)DataHelper.readLong(in, 2);
|
||||
if ( (numPeers < 0) || (numPeers >= (1<<16) ) )
|
||||
throw new DataFormatException("Invalid number of peers - " + numPeers);
|
||||
Set peers = new HashSet(numPeers);
|
||||
for (int i = 0; i < numPeers; i++) {
|
||||
Hash peer = new Hash();
|
||||
peer.readBytes(in);
|
||||
peers.add(peer);
|
||||
}
|
||||
_dontIncludePeers = peers;
|
||||
} catch (DataFormatException dfe) {
|
||||
throw new I2NPMessageException("Unable to load the message data", dfe);
|
||||
}
|
||||
curIndex++;
|
||||
|
||||
if (tunnelSpecified) {
|
||||
_replyTunnel = new TunnelId(DataHelper.fromLong(data, curIndex, 4));
|
||||
curIndex += 4;
|
||||
}
|
||||
|
||||
int numPeers = (int)DataHelper.fromLong(data, curIndex, 2);
|
||||
curIndex += 2;
|
||||
|
||||
if ( (numPeers < 0) || (numPeers >= (1<<16) ) )
|
||||
throw new I2NPMessageException("Invalid number of peers - " + numPeers);
|
||||
Set peers = new HashSet(numPeers);
|
||||
for (int i = 0; i < numPeers; i++) {
|
||||
byte peer[] = new byte[Hash.HASH_LENGTH];
|
||||
System.arraycopy(data, curIndex, peer, 0, Hash.HASH_LENGTH);
|
||||
curIndex += Hash.HASH_LENGTH;
|
||||
peers.add(new Hash(peer));
|
||||
}
|
||||
_dontIncludePeers = peers;
|
||||
}
|
||||
|
||||
|
||||
protected int calculateWrittenLength() {
|
||||
int totalLength = 0;
|
||||
|
@ -57,27 +57,32 @@ public class DatabaseSearchReplyMessage extends I2NPMessageImpl {
|
||||
public Hash getFromHash() { return _from; }
|
||||
public void setFromHash(Hash from) { _from = from; }
|
||||
|
||||
public void readMessage(InputStream in, int type) throws I2NPMessageException, IOException {
|
||||
public void readMessage(byte data[], int offset, int dataSize, int type) throws I2NPMessageException, IOException {
|
||||
if (type != MESSAGE_TYPE) throw new I2NPMessageException("Message type is incorrect for this message");
|
||||
try {
|
||||
_key = new Hash();
|
||||
_key.readBytes(in);
|
||||
|
||||
int num = (int)DataHelper.readLong(in, 1);
|
||||
_peerHashes.clear();
|
||||
for (int i = 0; i < num; i++) {
|
||||
Hash peer = new Hash();
|
||||
peer.readBytes(in);
|
||||
addReply(peer);
|
||||
}
|
||||
|
||||
_from = new Hash();
|
||||
_from.readBytes(in);
|
||||
|
||||
_context.statManager().addRateData("netDb.searchReplyMessageReceive", num*32 + 64, 1);
|
||||
} catch (DataFormatException dfe) {
|
||||
throw new I2NPMessageException("Unable to load the message data", dfe);
|
||||
int curIndex = offset;
|
||||
|
||||
byte keyData[] = new byte[Hash.HASH_LENGTH];
|
||||
System.arraycopy(data, curIndex, keyData, 0, Hash.HASH_LENGTH);
|
||||
curIndex += Hash.HASH_LENGTH;
|
||||
_key = new Hash(keyData);
|
||||
|
||||
int num = (int)DataHelper.fromLong(data, curIndex, 1);
|
||||
curIndex++;
|
||||
|
||||
_peerHashes.clear();
|
||||
for (int i = 0; i < num; i++) {
|
||||
byte peer[] = new byte[Hash.HASH_LENGTH];
|
||||
System.arraycopy(data, curIndex, peer, 0, Hash.HASH_LENGTH);
|
||||
curIndex += Hash.HASH_LENGTH;
|
||||
addReply(new Hash(peer));
|
||||
}
|
||||
|
||||
byte from[] = new byte[Hash.HASH_LENGTH];
|
||||
System.arraycopy(data, curIndex, from, 0, Hash.HASH_LENGTH);
|
||||
curIndex += Hash.HASH_LENGTH;
|
||||
_from = new Hash(from);
|
||||
|
||||
_context.statManager().addRateData("netDb.searchReplyMessageReceive", num*32 + 64, 1);
|
||||
}
|
||||
|
||||
/** calculate the message body's length (not including the header and footer */
|
||||
|
@ -119,45 +119,58 @@ public class DatabaseStoreMessage extends I2NPMessageImpl {
|
||||
public Hash getReplyGateway() { return _replyGateway; }
|
||||
public void setReplyGateway(Hash peer) { _replyGateway = peer; }
|
||||
|
||||
public void readMessage(InputStream in, int type) throws I2NPMessageException, IOException {
|
||||
public void readMessage(byte data[], int offset, int dataSize, int type) throws I2NPMessageException, IOException {
|
||||
if (type != MESSAGE_TYPE) throw new I2NPMessageException("Message type is incorrect for this message");
|
||||
try {
|
||||
_key = new Hash();
|
||||
_key.readBytes(in);
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug("Hash read: " + _key.toBase64());
|
||||
_type = (int)DataHelper.readLong(in, 1);
|
||||
_replyToken = DataHelper.readLong(in, 4);
|
||||
if (_replyToken > 0) {
|
||||
_replyTunnel = new TunnelId();
|
||||
_replyTunnel.readBytes(in);
|
||||
_replyGateway = new Hash();
|
||||
_replyGateway.readBytes(in);
|
||||
} else {
|
||||
_replyTunnel = null;
|
||||
_replyGateway = null;
|
||||
int curIndex = offset;
|
||||
|
||||
byte keyData[] = new byte[Hash.HASH_LENGTH];
|
||||
System.arraycopy(data, curIndex, keyData, 0, Hash.HASH_LENGTH);
|
||||
curIndex += Hash.HASH_LENGTH;
|
||||
_key = new Hash(keyData);
|
||||
|
||||
_type = (int)DataHelper.fromLong(data, curIndex, 1);
|
||||
curIndex++;
|
||||
|
||||
_replyToken = DataHelper.fromLong(data, curIndex, 4);
|
||||
curIndex += 4;
|
||||
|
||||
if (_replyToken > 0) {
|
||||
_replyTunnel = new TunnelId(DataHelper.fromLong(data, curIndex, 4));
|
||||
curIndex += 4;
|
||||
|
||||
byte gw[] = new byte[Hash.HASH_LENGTH];
|
||||
System.arraycopy(data, curIndex, gw, 0, Hash.HASH_LENGTH);
|
||||
curIndex += Hash.HASH_LENGTH;
|
||||
_replyGateway = new Hash(gw);
|
||||
} else {
|
||||
_replyTunnel = null;
|
||||
_replyGateway = null;
|
||||
}
|
||||
|
||||
if (_type == KEY_TYPE_LEASESET) {
|
||||
_leaseSet = new LeaseSet();
|
||||
try {
|
||||
_leaseSet.readBytes(new ByteArrayInputStream(data, curIndex, data.length-curIndex));
|
||||
} catch (DataFormatException dfe) {
|
||||
throw new I2NPMessageException("Error reading the leaseSet", dfe);
|
||||
}
|
||||
if (_type == KEY_TYPE_LEASESET) {
|
||||
_leaseSet = new LeaseSet();
|
||||
_leaseSet.readBytes(in);
|
||||
} else if (_type == KEY_TYPE_ROUTERINFO) {
|
||||
_info = new RouterInfo();
|
||||
int compressedSize = (int)DataHelper.readLong(in, 2);
|
||||
byte compressed[] = new byte[compressedSize];
|
||||
int read = DataHelper.read(in, compressed);
|
||||
if (read != compressedSize)
|
||||
throw new I2NPMessageException("Invalid compressed data size (expected "
|
||||
+ compressedSize + " read " + read + ")");
|
||||
ByteArrayInputStream bais = new ByteArrayInputStream(DataHelper.decompress(compressed));
|
||||
_info.readBytes(bais);
|
||||
} else {
|
||||
throw new I2NPMessageException("Invalid type of key read from the structure - " + _type);
|
||||
} else if (_type == KEY_TYPE_ROUTERINFO) {
|
||||
_info = new RouterInfo();
|
||||
int compressedSize = (int)DataHelper.fromLong(data, curIndex, 2);
|
||||
curIndex += 2;
|
||||
|
||||
byte decompressed[] = DataHelper.decompress(data, curIndex, compressedSize);
|
||||
try {
|
||||
_info.readBytes(new ByteArrayInputStream(decompressed));
|
||||
} catch (DataFormatException dfe) {
|
||||
throw new I2NPMessageException("Error reading the routerInfo", dfe);
|
||||
}
|
||||
} catch (DataFormatException dfe) {
|
||||
throw new I2NPMessageException("Unable to load the message data", dfe);
|
||||
} else {
|
||||
throw new I2NPMessageException("Invalid type of key read from the structure - " + _type);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/** calculate the message body's length (not including the header and footer */
|
||||
protected int calculateWrittenLength() {
|
||||
int len = Hash.HASH_LENGTH + 1 + 4; // key+type+replyToken
|
||||
|
@ -42,14 +42,13 @@ public class DeliveryStatusMessage extends I2NPMessageImpl {
|
||||
public Date getArrival() { return _arrival; }
|
||||
public void setArrival(Date arrival) { _arrival = arrival; }
|
||||
|
||||
public void readMessage(InputStream in, int type) throws I2NPMessageException, IOException {
|
||||
public void readMessage(byte data[], int offset, int dataSize, int type) throws I2NPMessageException, IOException {
|
||||
if (type != MESSAGE_TYPE) throw new I2NPMessageException("Message type is incorrect for this message");
|
||||
try {
|
||||
_id = DataHelper.readLong(in, 4);
|
||||
_arrival = DataHelper.readDate(in);
|
||||
} catch (DataFormatException dfe) {
|
||||
throw new I2NPMessageException("Unable to load the message data", dfe);
|
||||
}
|
||||
int curIndex = offset;
|
||||
|
||||
_id = DataHelper.fromLong(data, curIndex, 4);
|
||||
curIndex += 4;
|
||||
_arrival = DataHelper.fromDate(data, curIndex);
|
||||
}
|
||||
|
||||
/** calculate the message body's length (not including the header and footer */
|
||||
|
@ -35,17 +35,15 @@ public class GarlicMessage extends I2NPMessageImpl {
|
||||
public byte[] getData() { return _data; }
|
||||
public void setData(byte[] data) { _data = data; }
|
||||
|
||||
public void readMessage(InputStream in, int type) throws I2NPMessageException, IOException {
|
||||
public void readMessage(byte data[], int offset, int dataSize, int type) throws I2NPMessageException, IOException {
|
||||
if (type != MESSAGE_TYPE) throw new I2NPMessageException("Message type is incorrect for this message");
|
||||
try {
|
||||
long len = DataHelper.readLong(in, 4);
|
||||
_data = new byte[(int)len];
|
||||
int read = read(in, _data);
|
||||
if (read != len)
|
||||
throw new I2NPMessageException("Incorrect size read [" + read + " read, expected " + len + "]");
|
||||
} catch (DataFormatException dfe) {
|
||||
throw new I2NPMessageException("Unable to load the message data", dfe);
|
||||
}
|
||||
int curIndex = offset;
|
||||
|
||||
long len = DataHelper.fromLong(data, curIndex, 4);
|
||||
curIndex += 4;
|
||||
if ( (len <= 0) || (len > 64*1024) ) throw new I2NPMessageException("size="+len);
|
||||
_data = new byte[(int)len];
|
||||
System.arraycopy(data, curIndex, _data, 0, (int)len);
|
||||
}
|
||||
|
||||
/** calculate the message body's length (not including the header and footer */
|
||||
|
@ -28,11 +28,27 @@ public interface I2NPMessage extends DataStructure {
|
||||
*
|
||||
* @param in stream to read from
|
||||
* @param type I2NP message type
|
||||
* @param buffer scratch buffer to be used when reading and parsing
|
||||
* @throws I2NPMessageException if the stream doesn't contain a valid message
|
||||
* that this class can read.
|
||||
* @throws IOException if there is a problem reading from the stream
|
||||
*/
|
||||
public void readBytes(InputStream in, int type) throws I2NPMessageException, IOException;
|
||||
public void readBytes(InputStream in, int type, byte buffer[]) throws I2NPMessageException, IOException;
|
||||
|
||||
/**
|
||||
* Read the body into the data structures, after the initial type byte and
|
||||
* the uniqueId / expiration, using the current class's format as defined by
|
||||
* the I2NP specification
|
||||
*
|
||||
* @param data data to read from
|
||||
* @param offset where to start in the data array
|
||||
* @param dataSize how long into the data to read
|
||||
* @param type I2NP message type
|
||||
* @throws I2NPMessageException if the stream doesn't contain a valid message
|
||||
* that this class can read.
|
||||
* @throws IOException if there is a problem reading from the stream
|
||||
*/
|
||||
public void readMessage(byte data[], int offset, int dataSize, int type) throws I2NPMessageException, IOException;
|
||||
|
||||
/**
|
||||
* Return the unique identifier for this type of I2NP message, as defined in
|
||||
|
@ -26,9 +26,11 @@ public class I2NPMessageHandler {
|
||||
private I2PAppContext _context;
|
||||
private long _lastReadBegin;
|
||||
private long _lastReadEnd;
|
||||
private byte _messageBuffer[];
|
||||
public I2NPMessageHandler(I2PAppContext context) {
|
||||
_context = context;
|
||||
_log = context.logManager().getLog(I2NPMessageHandler.class);
|
||||
_messageBuffer = null;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -39,12 +41,15 @@ public class I2NPMessageHandler {
|
||||
* message - if it is an unknown type or has improper formatting, etc.
|
||||
*/
|
||||
public I2NPMessage readMessage(InputStream in) throws IOException, I2NPMessageException {
|
||||
if (_messageBuffer == null) _messageBuffer = new byte[38*1024]; // more than necessary
|
||||
try {
|
||||
int type = (int)DataHelper.readLong(in, 1);
|
||||
_lastReadBegin = System.currentTimeMillis();
|
||||
I2NPMessage msg = createMessage(in, type);
|
||||
I2NPMessage msg = createMessage(type);
|
||||
if (msg == null)
|
||||
throw new I2NPMessageException("The type "+ type + " is an unknown I2NP message");
|
||||
try {
|
||||
msg.readBytes(in, type);
|
||||
msg.readBytes(in, type, _messageBuffer);
|
||||
} catch (IOException ioe) {
|
||||
throw ioe;
|
||||
} catch (I2NPMessageException ime) {
|
||||
@ -61,14 +66,13 @@ public class I2NPMessageHandler {
|
||||
throw new I2NPMessageException("Error reading the message", dfe);
|
||||
}
|
||||
}
|
||||
|
||||
public long getLastReadTime() { return _lastReadEnd - _lastReadBegin; }
|
||||
|
||||
/**
|
||||
* Yes, this is fairly ugly, but its the only place it ever happens.
|
||||
*
|
||||
*/
|
||||
private I2NPMessage createMessage(InputStream in, int type) throws IOException, I2NPMessageException {
|
||||
private I2NPMessage createMessage(int type) throws I2NPMessageException {
|
||||
switch (type) {
|
||||
case DatabaseStoreMessage.MESSAGE_TYPE:
|
||||
return new DatabaseStoreMessage(_context);
|
||||
@ -89,7 +93,7 @@ public class I2NPMessageHandler {
|
||||
case TunnelCreateStatusMessage.MESSAGE_TYPE:
|
||||
return new TunnelCreateStatusMessage(_context);
|
||||
default:
|
||||
throw new I2NPMessageException("The type "+ type + " is an unknown I2NP message");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -44,29 +44,15 @@ public abstract class I2NPMessageImpl extends DataStructureImpl implements I2NPM
|
||||
_context.statManager().createRateStat("i2np.readTime", "How long it takes to read an I2NP message", "I2NP", new long[] { 10*60*1000, 60*60*1000 });
|
||||
}
|
||||
|
||||
/**
|
||||
* Read the body into the data structures, after the initial type byte and
|
||||
* the uniqueId / expiration, using the current class's format as defined by
|
||||
* the I2NP specification
|
||||
*
|
||||
* @param in stream to read from
|
||||
* @param type I2NP message type
|
||||
* @throws I2NPMessageException if the stream doesn't contain a valid message
|
||||
* that this class can read.
|
||||
* @throws IOException if there is a problem reading from the stream
|
||||
*/
|
||||
protected abstract void readMessage(InputStream in, int type) throws I2NPMessageException, IOException;
|
||||
|
||||
public void readBytes(InputStream in) throws DataFormatException, IOException {
|
||||
try {
|
||||
readBytes(in, -1);
|
||||
readBytes(in, -1, new byte[1024]);
|
||||
} catch (I2NPMessageException ime) {
|
||||
throw new DataFormatException("Bad bytes", ime);
|
||||
}
|
||||
}
|
||||
public void readBytes(InputStream in, int type) throws I2NPMessageException, IOException {
|
||||
public void readBytes(InputStream in, int type, byte buffer[]) throws I2NPMessageException, IOException {
|
||||
try {
|
||||
long start = _context.clock().now();
|
||||
if (type < 0)
|
||||
type = (int)DataHelper.readLong(in, 1);
|
||||
_uniqueId = DataHelper.readLong(in, 4);
|
||||
@ -74,17 +60,28 @@ public abstract class I2NPMessageImpl extends DataStructureImpl implements I2NPM
|
||||
int size = (int)DataHelper.readLong(in, 2);
|
||||
Hash h = new Hash();
|
||||
h.readBytes(in);
|
||||
byte data[] = new byte[size];
|
||||
int read = DataHelper.read(in, data);
|
||||
if (read != size)
|
||||
throw new I2NPMessageException("Payload is too short [" + read + ", wanted " + size + "]");
|
||||
Hash calc = _context.sha().calculateHash(data);
|
||||
if (buffer.length < size) {
|
||||
if (size > 64*1024) throw new I2NPMessageException("size=" + size);
|
||||
buffer = new byte[size];
|
||||
}
|
||||
|
||||
int cur = 0;
|
||||
while (cur < size) {
|
||||
int numRead = in.read(buffer, cur, size- cur);
|
||||
if (numRead == -1) {
|
||||
throw new I2NPMessageException("Payload is too short [" + numRead + ", wanted " + size + "]");
|
||||
}
|
||||
cur += numRead;
|
||||
}
|
||||
|
||||
Hash calc = _context.sha().calculateHash(buffer, 0, size);
|
||||
if (!calc.equals(h))
|
||||
throw new I2NPMessageException("Hash does not match");
|
||||
|
||||
long start = _context.clock().now();
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug("Reading bytes: type = " + type + " / uniqueId : " + _uniqueId + " / expiration : " + _expiration);
|
||||
readMessage(new ByteArrayInputStream(data), type);
|
||||
readMessage(buffer, 0, size, type);
|
||||
long time = _context.clock().now() - start;
|
||||
if (time > 50)
|
||||
_context.statManager().addRateData("i2np.readTime", time, time);
|
||||
|
@ -28,7 +28,8 @@ public class TunnelConfigurationSessionKey extends DataStructureImpl {
|
||||
private final static Log _log = new Log(TunnelConfigurationSessionKey.class);
|
||||
private SessionKey _key;
|
||||
|
||||
public TunnelConfigurationSessionKey() { setKey(null); }
|
||||
public TunnelConfigurationSessionKey() { this(null); }
|
||||
public TunnelConfigurationSessionKey(SessionKey key) { setKey(key); }
|
||||
|
||||
public SessionKey getKey() { return _key; }
|
||||
public void setKey(SessionKey key) { _key= key; }
|
||||
|
@ -128,55 +128,102 @@ public class TunnelCreateMessage extends I2NPMessageImpl {
|
||||
public void setReplyPeer(Hash peer) { _replyPeer = peer; }
|
||||
public Hash getReplyPeer() { return _replyPeer; }
|
||||
|
||||
public void readMessage(InputStream in, int type) throws I2NPMessageException, IOException {
|
||||
public void readMessage(byte data[], int offset, int dataSize, int type) throws I2NPMessageException, IOException {
|
||||
if (type != MESSAGE_TYPE) throw new I2NPMessageException("Message type is incorrect for this message");
|
||||
try {
|
||||
_participantType = (int)DataHelper.readLong(in, 1);
|
||||
if (_participantType != PARTICIPANT_TYPE_ENDPOINT) {
|
||||
_nextRouter = new Hash();
|
||||
_nextRouter.readBytes(in);
|
||||
_nextTunnelId = new TunnelId();
|
||||
_nextTunnelId.readBytes(in);
|
||||
}
|
||||
_tunnelId = new TunnelId();
|
||||
_tunnelId.readBytes(in);
|
||||
_tunnelDuration = DataHelper.readLong(in, 4);
|
||||
_configKey = new TunnelConfigurationSessionKey();
|
||||
_configKey.readBytes(in);
|
||||
_maxPeakMessagesPerMin = DataHelper.readLong(in, 4);
|
||||
_maxAvgMessagesPerMin = DataHelper.readLong(in, 4);
|
||||
_maxPeakBytesPerMin = DataHelper.readLong(in, 4);
|
||||
_maxAvgBytesPerMin = DataHelper.readLong(in, 4);
|
||||
int curIndex = offset;
|
||||
|
||||
_participantType = (int)DataHelper.fromLong(data, curIndex, 1);
|
||||
curIndex++;
|
||||
if (_participantType != PARTICIPANT_TYPE_ENDPOINT) {
|
||||
byte peer[] = new byte[Hash.HASH_LENGTH];
|
||||
System.arraycopy(data, curIndex, peer, 0, Hash.HASH_LENGTH);
|
||||
curIndex += Hash.HASH_LENGTH;
|
||||
_nextRouter = new Hash(peer);
|
||||
|
||||
int flags = (int)DataHelper.readLong(in, 1);
|
||||
_includeDummyTraffic = flagsIncludeDummy(flags);
|
||||
_reorderMessages = flagsReorder(flags);
|
||||
|
||||
_verificationPubKey = new TunnelSigningPublicKey();
|
||||
_verificationPubKey.readBytes(in);
|
||||
if (_participantType == PARTICIPANT_TYPE_GATEWAY) {
|
||||
_verificationPrivKey = new TunnelSigningPrivateKey();
|
||||
_verificationPrivKey.readBytes(in);
|
||||
}
|
||||
if ( (_participantType == PARTICIPANT_TYPE_ENDPOINT) || (_participantType == PARTICIPANT_TYPE_GATEWAY) ) {
|
||||
_tunnelKey = new TunnelSessionKey();
|
||||
_tunnelKey.readBytes(in);
|
||||
}
|
||||
_certificate = new Certificate();
|
||||
_certificate.readBytes(in);
|
||||
_replyTag = new SessionTag();
|
||||
_replyTag.readBytes(in);
|
||||
_replyKey = new SessionKey();
|
||||
_replyKey.readBytes(in);
|
||||
_replyTunnel = new TunnelId();
|
||||
_replyTunnel.readBytes(in);
|
||||
_replyPeer = new Hash();
|
||||
_replyPeer.readBytes(in);
|
||||
} catch (DataFormatException dfe) {
|
||||
throw new I2NPMessageException("Unable to load the message data", dfe);
|
||||
_nextTunnelId = new TunnelId(DataHelper.fromLong(data, curIndex, 4));
|
||||
curIndex += 4;
|
||||
}
|
||||
|
||||
_tunnelId = new TunnelId(DataHelper.fromLong(data, curIndex, 4));
|
||||
curIndex += 4;
|
||||
if (_tunnelId.getTunnelId() <= 0)
|
||||
throw new I2NPMessageException("wtf, tunnelId == " + _tunnelId);
|
||||
|
||||
_tunnelDuration = DataHelper.fromLong(data, curIndex, 4);
|
||||
curIndex += 4;
|
||||
|
||||
byte key[] = new byte[SessionKey.KEYSIZE_BYTES];
|
||||
System.arraycopy(data, curIndex, key, 0, SessionKey.KEYSIZE_BYTES);
|
||||
curIndex += SessionKey.KEYSIZE_BYTES;
|
||||
_configKey = new TunnelConfigurationSessionKey(new SessionKey(key));
|
||||
|
||||
_maxPeakMessagesPerMin = DataHelper.fromLong(data, curIndex, 4);
|
||||
curIndex += 4;
|
||||
_maxAvgMessagesPerMin = DataHelper.fromLong(data, curIndex, 4);
|
||||
curIndex += 4;
|
||||
_maxPeakBytesPerMin = DataHelper.fromLong(data, curIndex, 4);
|
||||
curIndex += 4;
|
||||
_maxAvgBytesPerMin = DataHelper.fromLong(data, curIndex, 4);
|
||||
curIndex += 4;
|
||||
|
||||
int flags = (int)DataHelper.fromLong(data, curIndex, 1);
|
||||
curIndex++;
|
||||
_includeDummyTraffic = flagsIncludeDummy(flags);
|
||||
_reorderMessages = flagsReorder(flags);
|
||||
|
||||
key = new byte[SigningPublicKey.KEYSIZE_BYTES];
|
||||
System.arraycopy(data, curIndex, key, 0, SigningPublicKey.KEYSIZE_BYTES);
|
||||
curIndex += SigningPublicKey.KEYSIZE_BYTES;
|
||||
_verificationPubKey = new TunnelSigningPublicKey(new SigningPublicKey(key));
|
||||
|
||||
if (_participantType == PARTICIPANT_TYPE_GATEWAY) {
|
||||
key = new byte[SigningPrivateKey.KEYSIZE_BYTES];
|
||||
System.arraycopy(data, curIndex, key, 0, SigningPrivateKey.KEYSIZE_BYTES);
|
||||
curIndex += SigningPrivateKey.KEYSIZE_BYTES;
|
||||
_verificationPrivKey = new TunnelSigningPrivateKey(new SigningPrivateKey(key));
|
||||
}
|
||||
|
||||
if ( (_participantType == PARTICIPANT_TYPE_ENDPOINT) || (_participantType == PARTICIPANT_TYPE_GATEWAY) ) {
|
||||
key = new byte[SessionKey.KEYSIZE_BYTES];
|
||||
System.arraycopy(data, curIndex, key, 0, SessionKey.KEYSIZE_BYTES);
|
||||
curIndex += SessionKey.KEYSIZE_BYTES;
|
||||
_tunnelKey = new TunnelSessionKey(new SessionKey(key));
|
||||
}
|
||||
|
||||
int certType = (int) DataHelper.fromLong(data, curIndex, 1);
|
||||
curIndex++;
|
||||
int certLength = (int) DataHelper.fromLong(data, curIndex, 2);
|
||||
curIndex += 2;
|
||||
if (certLength <= 0) {
|
||||
_certificate = new Certificate(certType, null);
|
||||
} else {
|
||||
if (certLength > 16*1024) throw new I2NPMessageException("cert size " + certLength);
|
||||
byte certPayload[] = new byte[certLength];
|
||||
System.arraycopy(data, curIndex, certPayload, 0, certLength);
|
||||
curIndex += certLength;
|
||||
_certificate = new Certificate(certType, certPayload);
|
||||
}
|
||||
|
||||
byte tag[] = new byte[SessionTag.BYTE_LENGTH];
|
||||
System.arraycopy(data, curIndex, tag, 0, SessionTag.BYTE_LENGTH);
|
||||
curIndex += SessionTag.BYTE_LENGTH;
|
||||
_replyTag = new SessionTag(tag);
|
||||
|
||||
key = new byte[SessionKey.KEYSIZE_BYTES];
|
||||
System.arraycopy(data, curIndex, key, 0, SessionKey.KEYSIZE_BYTES);
|
||||
curIndex += SessionKey.KEYSIZE_BYTES;
|
||||
_replyKey = new SessionKey(key);
|
||||
|
||||
_replyTunnel = new TunnelId(DataHelper.fromLong(data, curIndex, 4));
|
||||
curIndex += 4;
|
||||
|
||||
byte peer[] = new byte[Hash.HASH_LENGTH];
|
||||
System.arraycopy(data, curIndex, peer, 0, Hash.HASH_LENGTH);
|
||||
curIndex += Hash.HASH_LENGTH;
|
||||
_replyPeer = new Hash(peer);
|
||||
}
|
||||
|
||||
|
||||
/** calculate the message body's length (not including the header and footer */
|
||||
protected int calculateWrittenLength() {
|
||||
int length = 0;
|
||||
|
@ -46,7 +46,11 @@ public class TunnelCreateStatusMessage extends I2NPMessageImpl {
|
||||
}
|
||||
|
||||
public TunnelId getTunnelId() { return _tunnelId; }
|
||||
public void setTunnelId(TunnelId id) { _tunnelId = id; }
|
||||
public void setTunnelId(TunnelId id) {
|
||||
_tunnelId = id;
|
||||
if ( (id != null) && (id.getTunnelId() <= 0) )
|
||||
throw new IllegalArgumentException("wtf, tunnelId " + id);
|
||||
}
|
||||
|
||||
public int getStatus() { return _status; }
|
||||
public void setStatus(int status) { _status = status; }
|
||||
@ -57,19 +61,25 @@ public class TunnelCreateStatusMessage extends I2NPMessageImpl {
|
||||
public Hash getFromHash() { return _from; }
|
||||
public void setFromHash(Hash from) { _from = from; }
|
||||
|
||||
public void readMessage(InputStream in, int type) throws I2NPMessageException, IOException {
|
||||
public void readMessage(byte data[], int offset, int dataSize, int type) throws I2NPMessageException, IOException {
|
||||
if (type != MESSAGE_TYPE) throw new I2NPMessageException("Message type is incorrect for this message");
|
||||
try {
|
||||
_tunnelId = new TunnelId();
|
||||
_tunnelId.readBytes(in);
|
||||
_status = (int)DataHelper.readLong(in, 1);
|
||||
_from = new Hash();
|
||||
_from.readBytes(in);
|
||||
} catch (DataFormatException dfe) {
|
||||
throw new I2NPMessageException("Unable to load the message data", dfe);
|
||||
}
|
||||
int curIndex = offset;
|
||||
|
||||
_tunnelId = new TunnelId(DataHelper.fromLong(data, curIndex, 4));
|
||||
curIndex += 4;
|
||||
|
||||
if (_tunnelId.getTunnelId() <= 0)
|
||||
throw new I2NPMessageException("wtf, negative tunnelId? " + _tunnelId);
|
||||
|
||||
_status = (int)DataHelper.fromLong(data, curIndex, 1);
|
||||
curIndex++;
|
||||
byte peer[] = new byte[Hash.HASH_LENGTH];
|
||||
System.arraycopy(data, curIndex, peer, 0, Hash.HASH_LENGTH);
|
||||
curIndex += Hash.HASH_LENGTH;
|
||||
_from = new Hash(peer);
|
||||
}
|
||||
|
||||
|
||||
/** calculate the message body's length (not including the header and footer */
|
||||
protected int calculateWrittenLength() {
|
||||
return 4 + 1 + Hash.HASH_LENGTH; // id + status + from
|
||||
@ -77,6 +87,7 @@ public class TunnelCreateStatusMessage extends I2NPMessageImpl {
|
||||
/** write the message body to the output array, starting at the given index */
|
||||
protected int writeMessageBody(byte out[], int curIndex) throws I2NPMessageException {
|
||||
if ( (_tunnelId == null) || (_from == null) ) throw new I2NPMessageException("Not enough data to write out");
|
||||
if (_tunnelId.getTunnelId() < 0) throw new I2NPMessageException("Negative tunnelId!? " + _tunnelId);
|
||||
|
||||
byte id[] = DataHelper.toLong(4, _tunnelId.getTunnelId());
|
||||
System.arraycopy(id, 0, out, curIndex, 4);
|
||||
|
@ -46,7 +46,9 @@ public class TunnelMessage extends I2NPMessageImpl {
|
||||
}
|
||||
|
||||
public TunnelId getTunnelId() { return _tunnelId; }
|
||||
public void setTunnelId(TunnelId id) { _tunnelId = id; }
|
||||
public void setTunnelId(TunnelId id) {
|
||||
_tunnelId = id;
|
||||
}
|
||||
|
||||
public byte[] getData() { return _data; }
|
||||
public void setData(byte data[]) {
|
||||
@ -61,33 +63,42 @@ public class TunnelMessage extends I2NPMessageImpl {
|
||||
public byte[] getEncryptedDeliveryInstructions() { return _encryptedInstructions; }
|
||||
public void setEncryptedDeliveryInstructions(byte instructions[]) { _encryptedInstructions = instructions; }
|
||||
|
||||
public void readMessage(InputStream in, int type) throws I2NPMessageException, IOException {
|
||||
public void readMessage(byte data[], int offset, int dataSize, int type) throws I2NPMessageException, IOException {
|
||||
if (type != MESSAGE_TYPE) throw new I2NPMessageException("Message type is incorrect for this message");
|
||||
try {
|
||||
_tunnelId = new TunnelId();
|
||||
_tunnelId.readBytes(in);
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug("Read tunnel message for tunnel " + _tunnelId);
|
||||
_size = DataHelper.readLong(in, 4);
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug("Read tunnel message size: " + _size);
|
||||
if (_size < 0) throw new I2NPMessageException("Invalid size in the structure: " + _size);
|
||||
_data = new byte[(int)_size];
|
||||
int read = read(in, _data);
|
||||
if (read != _size)
|
||||
throw new I2NPMessageException("Incorrect number of bytes read (" + read + ", expected " + _size);
|
||||
int includeVerification = (int)DataHelper.readLong(in, 1);
|
||||
if (includeVerification == FLAG_INCLUDESTRUCTURE) {
|
||||
_verification = new TunnelVerificationStructure();
|
||||
_verification.readBytes(in);
|
||||
int len = (int)DataHelper.readLong(in, 2);
|
||||
_encryptedInstructions = new byte[len];
|
||||
read = read(in, _encryptedInstructions);
|
||||
if (read != len)
|
||||
throw new I2NPMessageException("Incorrect number of bytes read for instructions (" + read + ", expected " + len + ")");
|
||||
}
|
||||
} catch (DataFormatException dfe) {
|
||||
throw new I2NPMessageException("Unable to load the message data", dfe);
|
||||
int curIndex = offset;
|
||||
|
||||
_tunnelId = new TunnelId(DataHelper.fromLong(data, curIndex, 4));
|
||||
curIndex += 4;
|
||||
|
||||
if (_tunnelId.getTunnelId() <= 0)
|
||||
throw new I2NPMessageException("Invalid tunnel Id " + _tunnelId);
|
||||
|
||||
_size = DataHelper.fromLong(data, curIndex, 4);
|
||||
curIndex += 4;
|
||||
|
||||
if (_size < 0) throw new I2NPMessageException("Invalid size in the structure: " + _size);
|
||||
if (_size > 64*1024) throw new I2NPMessageException("Invalid size in the structure: " + _size);
|
||||
_data = new byte[(int)_size];
|
||||
System.arraycopy(data, curIndex, _data, 0, (int)_size);
|
||||
curIndex += _size;
|
||||
|
||||
int includeVerification = (int)DataHelper.fromLong(data, curIndex, 1);
|
||||
curIndex++;
|
||||
if (includeVerification == FLAG_INCLUDESTRUCTURE) {
|
||||
byte vHash[] = new byte[Hash.HASH_LENGTH];
|
||||
System.arraycopy(data, curIndex, vHash, 0, Hash.HASH_LENGTH);
|
||||
curIndex += Hash.HASH_LENGTH;
|
||||
byte vSig[] = new byte[Signature.SIGNATURE_BYTES];
|
||||
System.arraycopy(data, curIndex, vSig, 0, Signature.SIGNATURE_BYTES);
|
||||
curIndex += Signature.SIGNATURE_BYTES;
|
||||
_verification = new TunnelVerificationStructure(new Hash(vHash), new Signature(vSig));
|
||||
|
||||
int len = (int)DataHelper.fromLong(data, curIndex, 2);
|
||||
curIndex += 2;
|
||||
if ( (len <= 0) || (len > 4*1024) ) throw new I2NPMessageException("wtf, size of instructions: " + len);
|
||||
_encryptedInstructions = new byte[len];
|
||||
System.arraycopy(data, curIndex, _encryptedInstructions, 0, len);
|
||||
curIndex += len;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -28,7 +28,8 @@ public class TunnelSessionKey extends DataStructureImpl {
|
||||
private final static Log _log = new Log(TunnelSessionKey.class);
|
||||
private SessionKey _key;
|
||||
|
||||
public TunnelSessionKey() { setKey(null); }
|
||||
public TunnelSessionKey() { this(null); }
|
||||
public TunnelSessionKey(SessionKey key) { setKey(key); }
|
||||
|
||||
public SessionKey getKey() { return _key; }
|
||||
public void setKey(SessionKey key) { _key= key; }
|
||||
|
@ -29,7 +29,8 @@ public class TunnelSigningPrivateKey extends DataStructureImpl {
|
||||
private final static Log _log = new Log(EndPointPrivateKey.class);
|
||||
private SigningPrivateKey _key;
|
||||
|
||||
public TunnelSigningPrivateKey() { setKey(null); }
|
||||
public TunnelSigningPrivateKey() { this(null); }
|
||||
public TunnelSigningPrivateKey(SigningPrivateKey key) { setKey(key); }
|
||||
|
||||
public SigningPrivateKey getKey() { return _key; }
|
||||
public void setKey(SigningPrivateKey key) { _key= key; }
|
||||
|
@ -28,7 +28,8 @@ public class TunnelSigningPublicKey extends DataStructureImpl {
|
||||
private final static Log _log = new Log(TunnelSigningPublicKey.class);
|
||||
private SigningPublicKey _key;
|
||||
|
||||
public TunnelSigningPublicKey() { setKey(null); }
|
||||
public TunnelSigningPublicKey() { this(null); }
|
||||
public TunnelSigningPublicKey(SigningPublicKey key) { setKey(key); }
|
||||
|
||||
public SigningPublicKey getKey() { return _key; }
|
||||
public void setKey(SigningPublicKey key) { _key= key; }
|
||||
|
@ -29,9 +29,10 @@ public class TunnelVerificationStructure extends DataStructureImpl {
|
||||
private Hash _msgHash;
|
||||
private Signature _authSignature;
|
||||
|
||||
public TunnelVerificationStructure() {
|
||||
setMessageHash(null);
|
||||
setAuthorizationSignature(null);
|
||||
public TunnelVerificationStructure() { this(null, null); }
|
||||
public TunnelVerificationStructure(Hash messageHash, Signature authSig) {
|
||||
setMessageHash(messageHash);
|
||||
setAuthorizationSignature(authSig);
|
||||
}
|
||||
|
||||
public Hash getMessageHash() { return _msgHash; }
|
||||
|
@ -15,9 +15,9 @@ import net.i2p.CoreVersion;
|
||||
*
|
||||
*/
|
||||
public class RouterVersion {
|
||||
public final static String ID = "$Revision: 1.45 $ $Date: 2004/10/06 16:03:52 $";
|
||||
public final static String ID = "$Revision: 1.46 $ $Date: 2004/10/07 14:19:52 $";
|
||||
public final static String VERSION = "0.4.1.1";
|
||||
public final static long BUILD = 11;
|
||||
public final static long BUILD = 12;
|
||||
public static void main(String args[]) {
|
||||
System.out.println("I2P Router version: " + VERSION);
|
||||
System.out.println("Router ID: " + RouterVersion.ID);
|
||||
|
@ -46,7 +46,8 @@ public class GarlicMessageParser {
|
||||
_log.warn("Error decrypting", dfe);
|
||||
}
|
||||
if (decrData == null) {
|
||||
_log.debug("Decryption of garlic message failed");
|
||||
if (_log.shouldLog(Log.WARN))
|
||||
_log.warn("Decryption of garlic message failed (data = " + encData + ")", new Exception("Decrypt fail"));
|
||||
return null;
|
||||
} else {
|
||||
return readCloveSet(decrData);
|
||||
|
@ -396,8 +396,8 @@ public class HandleTunnelMessageJob extends JobImpl {
|
||||
_log.error("Error parsing the message body", ime);
|
||||
} catch (IOException ioe) {
|
||||
if (_log.shouldLog(Log.ERROR))
|
||||
_log.error("Error reading the message body", ioe);
|
||||
}
|
||||
_log.error("Error parsing the message body", ioe);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -68,6 +68,10 @@ class ConnectionRunner implements Runnable {
|
||||
buf = m.toByteArray();
|
||||
written = buf.length;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
_log.log(Log.CRIT, "getting the message data", e);
|
||||
_con.closeConnection();
|
||||
return;
|
||||
}
|
||||
if (written <= 0) {
|
||||
if (_log.shouldLog(Log.WARN))
|
||||
|
@ -287,6 +287,7 @@ public class TCPTransport extends TransportImpl {
|
||||
con.setTransport(this);
|
||||
con.closeConnection();
|
||||
} else {
|
||||
con.setTransport(this);
|
||||
|
||||
if (waitingMsgs != null) {
|
||||
for (int i = 0; i < waitingMsgs.size(); i++) {
|
||||
@ -296,7 +297,6 @@ public class TCPTransport extends TransportImpl {
|
||||
|
||||
_context.shitlist().unshitlistRouter(ident.calculateHash());
|
||||
|
||||
con.setTransport(this);
|
||||
con.runConnection();
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug("Connection set to run");
|
||||
|
Reference in New Issue
Block a user