big ol' update to strip out the singletons, replacing them with

a rooted app context.  The core itself has its own I2PAppContext
(see its javadoc for, uh, docs), and the router extends that to
expose the router's singletons.  The main point of this is to
make it so that we can run multiple routers in the same JVM, even
to allow different apps in the same JVM to switch singleton
implementations (e.g. run some routers with one set of profile
calculators, and other routers with a different one).
There is still some work to be done regarding the actual boot up
of multiple routers in a JVM, as well as their configuration,
though the plan is to have the RouterContext override the
I2PAppContext's getProperty/getPropertyNames methods to read from
a config file (seperate ones per context) instead of using the
System.getProperty that the base I2PAppContext uses.
Once the multi-router is working, i'll shim in a VMCommSystem
that doesn't depend upon sockets or threads to read/write (and
that uses configurable message send delays / disconnects / etc,
perhaps using data from the routerContext.getProperty to drive it).
I could hold off until the sim is all working, but there's a
truckload of changes in here and I hate dealing with conflicts ;)
Everything works - I've been running 'er for a while and kicked
the tires a bit, but if you see something amiss, please let me
know.
This commit is contained in:
jrandom
2004-04-24 11:54:35 +00:00
committed by zzz
parent c29a6b95ae
commit 393b1d7674
217 changed files with 16662 additions and 15452 deletions

View File

@@ -1,9 +1,9 @@
package net.i2p.data.i2np;
/*
* free (adj.): unencumbered; not under the control of others
* Written by jrandom in 2003 and released into the public domain
* with no warranty of any kind, either expressed or implied.
* It probably won't make your computer catch on fire, or eat
* Written by jrandom in 2003 and released into the public domain
* with no warranty of any kind, either expressed or implied.
* It probably won't make your computer catch on fire, or eat
* your children, but it might. Use at your own risk.
*
*/
@@ -15,6 +15,7 @@ import java.io.InputStream;
import net.i2p.data.DataFormatException;
import net.i2p.data.DataHelper;
import net.i2p.util.Log;
import net.i2p.I2PAppContext;
/**
* Defines a message containing arbitrary bytes of data
@@ -26,8 +27,9 @@ public class DataMessage extends I2NPMessageImpl {
public final static int MESSAGE_TYPE = 20;
private byte _data[];
public DataMessage() {
_data = null;
public DataMessage(I2PAppContext context) {
super(context);
_data = null;
}
public byte[] getData() { return _data; }
@@ -36,23 +38,23 @@ public class DataMessage extends I2NPMessageImpl {
public int getSize() { return _data.length; }
public void readMessage(InputStream in, int type) throws I2NPMessageException, IOException {
if (type != MESSAGE_TYPE) throw new I2NPMessageException("Message type is incorrect for this message");
if (type != MESSAGE_TYPE) throw new I2NPMessageException("Message type is incorrect for this message");
try {
int size = (int)DataHelper.readLong(in, 4);
_data = new byte[size];
int read = read(in, _data);
if (read != size)
throw new DataFormatException("Not enough bytes to read (read = " + read + ", expected = " + size + ")");
int size = (int)DataHelper.readLong(in, 4);
_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);
}
}
protected byte[] writeMessage() throws I2NPMessageException, IOException {
ByteArrayOutputStream os = new ByteArrayOutputStream((_data != null ? _data.length + 4 : 4));
ByteArrayOutputStream os = new ByteArrayOutputStream((_data != null ? _data.length + 4 : 4));
try {
DataHelper.writeLong(os, 4, (_data != null ? _data.length : 0));
os.write(_data);
DataHelper.writeLong(os, 4, (_data != null ? _data.length : 0));
os.write(_data);
} catch (DataFormatException dfe) {
throw new I2NPMessageException("Error writing out the message data", dfe);
}
@@ -62,7 +64,7 @@ public class DataMessage extends I2NPMessageImpl {
public int getType() { return MESSAGE_TYPE; }
public int hashCode() {
return DataHelper.hashCode(getData());
return DataHelper.hashCode(getData());
}
public boolean equals(Object object) {
@@ -74,7 +76,7 @@ public class DataMessage extends I2NPMessageImpl {
}
}
public String toString() {
public String toString() {
StringBuffer buf = new StringBuffer();
buf.append("[DataMessage: ");
buf.append("\n\tData: ").append(DataHelper.toString(getData(), 64));

View File

@@ -1,99 +0,0 @@
package net.i2p.data.i2np;
/*
* free (adj.): unencumbered; not under the control of others
* Written by jrandom in 2003 and released into the public domain
* with no warranty of any kind, either expressed or implied.
* It probably won't make your computer catch on fire, or eat
* your children, but it might. Use at your own risk.
*
*/
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import net.i2p.data.DataFormatException;
import net.i2p.data.DataHelper;
import net.i2p.data.Hash;
import net.i2p.util.Log;
/**
* Defines the message a router sends to another router to help integrate into
* the network by searching for routers in a particular keyspace.
*
* @author jrandom
*/
public class DatabaseFindNearestMessage extends I2NPMessageImpl {
private final static Log _log = new Log(DatabaseFindNearestMessage.class);
public final static int MESSAGE_TYPE = 4;
private Hash _key;
private Hash _from;
public DatabaseFindNearestMessage() {
setSearchKey(null);
setFromHash(null);
}
/**
* Defines the key being searched for
*/
public Hash getSearchKey() { return _key; }
public void setSearchKey(Hash key) { _key = key; }
/**
* Contains the SHA256 Hash of the RouterIdentity sending the message
*/
public Hash getFromHash() { return _from; }
public void setFromHash(Hash from) { _from = from; }
public void readMessage(InputStream in, 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);
_from = new Hash();
_from.readBytes(in);
} catch (DataFormatException dfe) {
throw new I2NPMessageException("Unable to load the message data", dfe);
}
}
protected byte[] writeMessage() throws I2NPMessageException, IOException {
if ( (_key == null) || (_from == null) ) throw new I2NPMessageException("Not enough data to write out");
ByteArrayOutputStream os = new ByteArrayOutputStream(32);
try {
_key.writeBytes(os);
_from.writeBytes(os);
} catch (DataFormatException dfe) {
throw new I2NPMessageException("Error writing out the message data", dfe);
}
return os.toByteArray();
}
public int getType() { return MESSAGE_TYPE; }
public int hashCode() {
return DataHelper.hashCode(getSearchKey()) +
DataHelper.hashCode(getFromHash());
}
public boolean equals(Object object) {
if ( (object != null) && (object instanceof DatabaseFindNearestMessage) ) {
DatabaseFindNearestMessage msg = (DatabaseFindNearestMessage)object;
return DataHelper.eq(getSearchKey(),msg.getSearchKey()) &&
DataHelper.eq(getFromHash(),msg.getFromHash());
} else {
return false;
}
}
public String toString() {
StringBuffer buf = new StringBuffer();
buf.append("[DatabaseFindNearestMessage: ");
buf.append("\n\tSearch Key: ").append(getSearchKey());
buf.append("\n\tFrom: ").append(getFromHash());
buf.append("]");
return buf.toString();
}
}

View File

@@ -1,9 +1,9 @@
package net.i2p.data.i2np;
/*
* free (adj.): unencumbered; not under the control of others
* Written by jrandom in 2003 and released into the public domain
* with no warranty of any kind, either expressed or implied.
* It probably won't make your computer catch on fire, or eat
* Written by jrandom in 2003 and released into the public domain
* with no warranty of any kind, either expressed or implied.
* It probably won't make your computer catch on fire, or eat
* your children, but it might. Use at your own risk.
*
*/
@@ -21,6 +21,7 @@ import net.i2p.data.Hash;
import net.i2p.data.RouterInfo;
import net.i2p.data.TunnelId;
import net.i2p.util.Log;
import net.i2p.I2PAppContext;
/**
* Defines the message a router sends to another router to search for a
@@ -36,10 +37,11 @@ public class DatabaseLookupMessage extends I2NPMessageImpl {
private TunnelId _replyTunnel;
private Set _dontIncludePeers;
public DatabaseLookupMessage() {
setSearchKey(null);
setFrom(null);
setDontIncludePeers(null);
public DatabaseLookupMessage(I2PAppContext context) {
super(context);
setSearchKey(null);
setFrom(null);
setDontIncludePeers(null);
}
/**
@@ -68,63 +70,63 @@ public class DatabaseLookupMessage extends I2NPMessageImpl {
* @return Set of Hash objects, each of which is the H(routerIdentity) to skip
*/
public Set getDontIncludePeers() { return _dontIncludePeers; }
public void setDontIncludePeers(Set peers) {
if (peers != null)
_dontIncludePeers = new HashSet(peers);
else
_dontIncludePeers = null;
public void setDontIncludePeers(Set peers) {
if (peers != null)
_dontIncludePeers = new HashSet(peers);
else
_dontIncludePeers = null;
}
public void readMessage(InputStream in, int type) throws I2NPMessageException, IOException {
if (type != MESSAGE_TYPE) throw new I2NPMessageException("Message type is incorrect for this message");
if (type != MESSAGE_TYPE) throw new I2NPMessageException("Message type is incorrect for this message");
try {
_key = new Hash();
_key.readBytes(in);
_from = new RouterInfo();
_from.readBytes(in);
boolean tunnelSpecified = DataHelper.readBoolean(in).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;
_key = new Hash();
_key.readBytes(in);
_from = new RouterInfo();
_from.readBytes(in);
boolean tunnelSpecified = DataHelper.readBoolean(in).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);
}
}
protected byte[] writeMessage() throws I2NPMessageException, IOException {
if (_key == null) throw new I2NPMessageException("Key being searched for not specified");
if (_from == null) throw new I2NPMessageException("From address not specified");
if (_key == null) throw new I2NPMessageException("Key being searched for not specified");
if (_from == null) throw new I2NPMessageException("From address not specified");
ByteArrayOutputStream os = new ByteArrayOutputStream(32);
try {
_key.writeBytes(os);
_from.writeBytes(os);
if (_replyTunnel != null) {
DataHelper.writeBoolean(os, Boolean.TRUE);
_replyTunnel.writeBytes(os);
} else {
DataHelper.writeBoolean(os, Boolean.FALSE);
}
if ( (_dontIncludePeers == null) || (_dontIncludePeers.size() <= 0) ) {
DataHelper.writeLong(os, 2, 0);
} else {
DataHelper.writeLong(os, 2, _dontIncludePeers.size());
for (Iterator iter = _dontIncludePeers.iterator(); iter.hasNext(); ) {
Hash peer = (Hash)iter.next();
peer.writeBytes(os);
}
}
_key.writeBytes(os);
_from.writeBytes(os);
if (_replyTunnel != null) {
DataHelper.writeBoolean(os, Boolean.TRUE);
_replyTunnel.writeBytes(os);
} else {
DataHelper.writeBoolean(os, Boolean.FALSE);
}
if ( (_dontIncludePeers == null) || (_dontIncludePeers.size() <= 0) ) {
DataHelper.writeLong(os, 2, 0);
} else {
DataHelper.writeLong(os, 2, _dontIncludePeers.size());
for (Iterator iter = _dontIncludePeers.iterator(); iter.hasNext(); ) {
Hash peer = (Hash)iter.next();
peer.writeBytes(os);
}
}
} catch (DataFormatException dfe) {
throw new I2NPMessageException("Error writing out the message data", dfe);
}
@@ -134,25 +136,25 @@ public class DatabaseLookupMessage extends I2NPMessageImpl {
public int getType() { return MESSAGE_TYPE; }
public int hashCode() {
return DataHelper.hashCode(getSearchKey()) +
DataHelper.hashCode(getFrom()) +
DataHelper.hashCode(getReplyTunnel()) +
DataHelper.hashCode(_dontIncludePeers);
return DataHelper.hashCode(getSearchKey()) +
DataHelper.hashCode(getFrom()) +
DataHelper.hashCode(getReplyTunnel()) +
DataHelper.hashCode(_dontIncludePeers);
}
public boolean equals(Object object) {
if ( (object != null) && (object instanceof DatabaseLookupMessage) ) {
DatabaseLookupMessage msg = (DatabaseLookupMessage)object;
return DataHelper.eq(getSearchKey(),msg.getSearchKey()) &&
DataHelper.eq(getFrom(),msg.getFrom()) &&
DataHelper.eq(getReplyTunnel(),msg.getReplyTunnel()) &&
DataHelper.eq(_dontIncludePeers,msg.getDontIncludePeers());
DataHelper.eq(getFrom(),msg.getFrom()) &&
DataHelper.eq(getReplyTunnel(),msg.getReplyTunnel()) &&
DataHelper.eq(_dontIncludePeers,msg.getDontIncludePeers());
} else {
return false;
}
}
public String toString() {
public String toString() {
StringBuffer buf = new StringBuffer();
buf.append("[DatabaseLookupMessage: ");
buf.append("\n\tSearch Key: ").append(getSearchKey());

View File

@@ -1,9 +1,9 @@
package net.i2p.data.i2np;
/*
* free (adj.): unencumbered; not under the control of others
* Written by jrandom in 2003 and released into the public domain
* with no warranty of any kind, either expressed or implied.
* It probably won't make your computer catch on fire, or eat
* Written by jrandom in 2003 and released into the public domain
* with no warranty of any kind, either expressed or implied.
* It probably won't make your computer catch on fire, or eat
* your children, but it might. Use at your own risk.
*
*/
@@ -21,10 +21,11 @@ import net.i2p.data.DataHelper;
import net.i2p.data.Hash;
import net.i2p.data.RouterInfo;
import net.i2p.util.Log;
import net.i2p.I2PAppContext;
/**
* Defines the message a router sends to another router in response to a
* search (DatabaseFindNearest or DatabaseLookup) when it doesn't have the value,
* Defines the message a router sends to another router in response to a
* search (DatabaseFindNearest or DatabaseLookup) when it doesn't have the value,
* specifying what routers it would search.
*
* @author jrandom
@@ -36,10 +37,11 @@ public class DatabaseSearchReplyMessage extends I2NPMessageImpl {
private List _routerInfoStructures;
private Hash _from;
public DatabaseSearchReplyMessage() {
setSearchKey(null);
_routerInfoStructures = new ArrayList();
setFromHash(null);
public DatabaseSearchReplyMessage(I2PAppContext context) {
super(context);
setSearchKey(null);
_routerInfoStructures = new ArrayList();
setFromHash(null);
}
/**
@@ -57,58 +59,58 @@ public class DatabaseSearchReplyMessage extends I2NPMessageImpl {
public void setFromHash(Hash from) { _from = from; }
public void readMessage(InputStream in, int type) throws I2NPMessageException, IOException {
if (type != MESSAGE_TYPE) throw new I2NPMessageException("Message type is incorrect for this message");
if (type != MESSAGE_TYPE) throw new I2NPMessageException("Message type is incorrect for this message");
try {
_key = new Hash();
_key.readBytes(in);
int compressedLength = (int)DataHelper.readLong(in, 2);
byte compressedData[] = new byte[compressedLength];
int read = DataHelper.read(in, compressedData);
if (read != compressedLength)
throw new IOException("Not enough data to decompress");
byte decompressedData[] = DataHelper.decompress(compressedData);
ByteArrayInputStream bais = new ByteArrayInputStream(decompressedData);
int num = (int)DataHelper.readLong(bais, 1);
_routerInfoStructures.clear();
for (int i = 0; i < num; i++) {
RouterInfo info = new RouterInfo();
info.readBytes(bais);
addReply(info);
}
_from = new Hash();
_from.readBytes(in);
_key = new Hash();
_key.readBytes(in);
int compressedLength = (int)DataHelper.readLong(in, 2);
byte compressedData[] = new byte[compressedLength];
int read = DataHelper.read(in, compressedData);
if (read != compressedLength)
throw new IOException("Not enough data to decompress");
byte decompressedData[] = DataHelper.decompress(compressedData);
ByteArrayInputStream bais = new ByteArrayInputStream(decompressedData);
int num = (int)DataHelper.readLong(bais, 1);
_routerInfoStructures.clear();
for (int i = 0; i < num; i++) {
RouterInfo info = new RouterInfo();
info.readBytes(bais);
addReply(info);
}
_from = new Hash();
_from.readBytes(in);
} catch (DataFormatException dfe) {
throw new I2NPMessageException("Unable to load the message data", dfe);
}
}
protected byte[] writeMessage() throws I2NPMessageException, IOException {
if (_key == null)
throw new I2NPMessageException("Key in reply to not specified");
if (_routerInfoStructures == null)
throw new I2NPMessageException("RouterInfo replies are null");
if (_routerInfoStructures.size() <= 0)
throw new I2NPMessageException("No replies specified in SearchReply! Always include oneself!");
if (_from == null)
throw new I2NPMessageException("No 'from' address specified!");
if (_key == null)
throw new I2NPMessageException("Key in reply to not specified");
if (_routerInfoStructures == null)
throw new I2NPMessageException("RouterInfo replies are null");
if (_routerInfoStructures.size() <= 0)
throw new I2NPMessageException("No replies specified in SearchReply! Always include oneself!");
if (_from == null)
throw new I2NPMessageException("No 'from' address specified!");
ByteArrayOutputStream os = new ByteArrayOutputStream(32);
try {
_key.writeBytes(os);
ByteArrayOutputStream baos = new ByteArrayOutputStream(512);
DataHelper.writeLong(baos, 1, _routerInfoStructures.size());
for (int i = 0; i < getNumReplies(); i++) {
RouterInfo info = getReply(i);
info.writeBytes(baos);
}
byte compressed[] = DataHelper.compress(baos.toByteArray());
DataHelper.writeLong(os, 2, compressed.length);
os.write(compressed);
_from.writeBytes(os);
_key.writeBytes(os);
ByteArrayOutputStream baos = new ByteArrayOutputStream(512);
DataHelper.writeLong(baos, 1, _routerInfoStructures.size());
for (int i = 0; i < getNumReplies(); i++) {
RouterInfo info = getReply(i);
info.writeBytes(baos);
}
byte compressed[] = DataHelper.compress(baos.toByteArray());
DataHelper.writeLong(os, 2, compressed.length);
os.write(compressed);
_from.writeBytes(os);
} catch (DataFormatException dfe) {
throw new I2NPMessageException("Error writing out the message data", dfe);
}
@@ -121,27 +123,27 @@ public class DatabaseSearchReplyMessage extends I2NPMessageImpl {
if ( (object != null) && (object instanceof DatabaseSearchReplyMessage) ) {
DatabaseSearchReplyMessage msg = (DatabaseSearchReplyMessage)object;
return DataHelper.eq(getSearchKey(),msg.getSearchKey()) &&
DataHelper.eq(getFromHash(),msg.getFromHash()) &&
DataHelper.eq(_routerInfoStructures,msg._routerInfoStructures);
DataHelper.eq(getFromHash(),msg.getFromHash()) &&
DataHelper.eq(_routerInfoStructures,msg._routerInfoStructures);
} else {
return false;
}
}
public int hashCode() {
return DataHelper.hashCode(getSearchKey()) +
DataHelper.hashCode(getFromHash()) +
DataHelper.hashCode(_routerInfoStructures);
return DataHelper.hashCode(getSearchKey()) +
DataHelper.hashCode(getFromHash()) +
DataHelper.hashCode(_routerInfoStructures);
}
public String toString() {
public String toString() {
StringBuffer buf = new StringBuffer();
buf.append("[DatabaseSearchReplyMessage: ");
buf.append("\n\tSearch Key: ").append(getSearchKey());
buf.append("\n\tReplies: # = ").append(getNumReplies());
for (int i = 0; i < getNumReplies(); i++) {
buf.append("\n\t\tReply [").append(i).append("]: ").append(getReply(i));
}
for (int i = 0; i < getNumReplies(); i++) {
buf.append("\n\t\tReply [").append(i).append("]: ").append(getReply(i));
}
buf.append("\n\tFrom: ").append(getFromHash());
buf.append("]");
return buf.toString();

View File

@@ -1,9 +1,9 @@
package net.i2p.data.i2np;
/*
* free (adj.): unencumbered; not under the control of others
* Written by jrandom in 2003 and released into the public domain
* with no warranty of any kind, either expressed or implied.
* It probably won't make your computer catch on fire, or eat
* Written by jrandom in 2003 and released into the public domain
* with no warranty of any kind, either expressed or implied.
* It probably won't make your computer catch on fire, or eat
* your children, but it might. Use at your own risk.
*
*/
@@ -19,9 +19,10 @@ import net.i2p.data.Hash;
import net.i2p.data.LeaseSet;
import net.i2p.data.RouterInfo;
import net.i2p.util.Log;
import net.i2p.I2PAppContext;
/**
* Defines the message a router sends to another router to test the network
* Defines the message a router sends to another router to test the network
* database reachability, as well as the reply message sent back.
*
* @author jrandom
@@ -37,11 +38,12 @@ public class DatabaseStoreMessage extends I2NPMessageImpl {
public final static int KEY_TYPE_ROUTERINFO = 0;
public final static int KEY_TYPE_LEASESET = 1;
public DatabaseStoreMessage() {
setValueType(-1);
setKey(null);
setLeaseSet(null);
setRouterInfo(null);
public DatabaseStoreMessage(I2PAppContext context) {
super(context);
setValueType(-1);
setKey(null);
setLeaseSet(null);
setRouterInfo(null);
}
/**
@@ -56,10 +58,10 @@ public class DatabaseStoreMessage extends I2NPMessageImpl {
*
*/
public RouterInfo getRouterInfo() { return _info; }
public void setRouterInfo(RouterInfo routerInfo) {
_info = routerInfo;
if (_info != null)
setValueType(KEY_TYPE_ROUTERINFO);
public void setRouterInfo(RouterInfo routerInfo) {
_info = routerInfo;
if (_info != null)
setValueType(KEY_TYPE_ROUTERINFO);
}
/**
@@ -67,14 +69,14 @@ public class DatabaseStoreMessage extends I2NPMessageImpl {
*
*/
public LeaseSet getLeaseSet() { return _leaseSet; }
public void setLeaseSet(LeaseSet leaseSet) {
_leaseSet = leaseSet;
if (_leaseSet != null)
setValueType(KEY_TYPE_LEASESET);
public void setLeaseSet(LeaseSet leaseSet) {
_leaseSet = leaseSet;
if (_leaseSet != null)
setValueType(KEY_TYPE_LEASESET);
}
/**
* Defines type of key being stored in the network database -
* Defines type of key being stored in the network database -
* either KEY_TYPE_ROUTERINFO or KEY_TYPE_LEASESET
*
*/
@@ -82,52 +84,52 @@ public class DatabaseStoreMessage extends I2NPMessageImpl {
public void setValueType(int type) { _type = type; }
public void readMessage(InputStream in, int type) throws I2NPMessageException, IOException {
if (type != MESSAGE_TYPE) throw new I2NPMessageException("Message type is incorrect for this message");
if (type != MESSAGE_TYPE) throw new I2NPMessageException("Message type is incorrect for this message");
try {
_key = new Hash();
_key.readBytes(in);
_log.debug("Hash read: " + _key.toBase64());
_type = (int)DataHelper.readLong(in, 1);
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");
ByteArrayInputStream bais = new ByteArrayInputStream(DataHelper.decompress(compressed));
_info.readBytes(bais);
} else {
throw new I2NPMessageException("Invalid type of key read from the structure - " + _type);
}
_key = new Hash();
_key.readBytes(in);
_log.debug("Hash read: " + _key.toBase64());
_type = (int)DataHelper.readLong(in, 1);
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");
ByteArrayInputStream bais = new ByteArrayInputStream(DataHelper.decompress(compressed));
_info.readBytes(bais);
} else {
throw new I2NPMessageException("Invalid type of key read from the structure - " + _type);
}
} catch (DataFormatException dfe) {
throw new I2NPMessageException("Unable to load the message data", dfe);
}
}
protected byte[] writeMessage() throws I2NPMessageException, IOException {
if (_key == null) throw new I2NPMessageException("Invalid key");
if ( (_type != KEY_TYPE_LEASESET) && (_type != KEY_TYPE_ROUTERINFO) ) throw new I2NPMessageException("Invalid key type");
if ( (_type == KEY_TYPE_LEASESET) && (_leaseSet == null) ) throw new I2NPMessageException("Missing lease set");
if ( (_type == KEY_TYPE_ROUTERINFO) && (_info == null) ) throw new I2NPMessageException("Missing router info");
if (_key == null) throw new I2NPMessageException("Invalid key");
if ( (_type != KEY_TYPE_LEASESET) && (_type != KEY_TYPE_ROUTERINFO) ) throw new I2NPMessageException("Invalid key type");
if ( (_type == KEY_TYPE_LEASESET) && (_leaseSet == null) ) throw new I2NPMessageException("Missing lease set");
if ( (_type == KEY_TYPE_ROUTERINFO) && (_info == null) ) throw new I2NPMessageException("Missing router info");
ByteArrayOutputStream os = new ByteArrayOutputStream(256);
try {
_key.writeBytes(os);
DataHelper.writeLong(os, 1, _type);
if (_type == KEY_TYPE_LEASESET) {
_leaseSet.writeBytes(os);
} else if (_type == KEY_TYPE_ROUTERINFO) {
ByteArrayOutputStream baos = new ByteArrayOutputStream(4*1024);
_info.writeBytes(baos);
byte uncompressed[] = baos.toByteArray();
byte compressed[] = DataHelper.compress(uncompressed);
DataHelper.writeLong(os, 2, compressed.length);
os.write(compressed);
}
_key.writeBytes(os);
DataHelper.writeLong(os, 1, _type);
if (_type == KEY_TYPE_LEASESET) {
_leaseSet.writeBytes(os);
} else if (_type == KEY_TYPE_ROUTERINFO) {
ByteArrayOutputStream baos = new ByteArrayOutputStream(4*1024);
_info.writeBytes(baos);
byte uncompressed[] = baos.toByteArray();
byte compressed[] = DataHelper.compress(uncompressed);
DataHelper.writeLong(os, 2, compressed.length);
os.write(compressed);
}
} catch (DataFormatException dfe) {
throw new I2NPMessageException("Error writing out the message data", dfe);
}
@@ -137,29 +139,29 @@ public class DatabaseStoreMessage extends I2NPMessageImpl {
public int getType() { return MESSAGE_TYPE; }
public int hashCode() {
return DataHelper.hashCode(getKey()) +
DataHelper.hashCode(getLeaseSet()) +
DataHelper.hashCode(getRouterInfo()) +
getValueType();
return DataHelper.hashCode(getKey()) +
DataHelper.hashCode(getLeaseSet()) +
DataHelper.hashCode(getRouterInfo()) +
getValueType();
}
public boolean equals(Object object) {
if ( (object != null) && (object instanceof DatabaseStoreMessage) ) {
DatabaseStoreMessage msg = (DatabaseStoreMessage)object;
return DataHelper.eq(getKey(),msg.getKey()) &&
DataHelper.eq(getLeaseSet(),msg.getLeaseSet()) &&
DataHelper.eq(getRouterInfo(),msg.getRouterInfo()) &&
DataHelper.eq(getValueType(),msg.getValueType());
DataHelper.eq(getLeaseSet(),msg.getLeaseSet()) &&
DataHelper.eq(getRouterInfo(),msg.getRouterInfo()) &&
DataHelper.eq(getValueType(),msg.getValueType());
} else {
return false;
}
}
public String toString() {
public String toString() {
StringBuffer buf = new StringBuffer();
buf.append("[DatabaseStoreMessage: ");
buf.append("\n\tExpiration: ").append(getMessageExpiration());
buf.append("\n\tUnique ID: ").append(getUniqueId());
buf.append("\n\tExpiration: ").append(getMessageExpiration());
buf.append("\n\tUnique ID: ").append(getUniqueId());
buf.append("\n\tKey: ").append(getKey());
buf.append("\n\tValue Type: ").append(getValueType());
buf.append("\n\tRouter Info: ").append(getRouterInfo());

View File

@@ -1,9 +1,9 @@
package net.i2p.data.i2np;
/*
* free (adj.): unencumbered; not under the control of others
* Written by jrandom in 2003 and released into the public domain
* with no warranty of any kind, either expressed or implied.
* It probably won't make your computer catch on fire, or eat
* Written by jrandom in 2003 and released into the public domain
* with no warranty of any kind, either expressed or implied.
* It probably won't make your computer catch on fire, or eat
* your children, but it might. Use at your own risk.
*
*/
@@ -16,6 +16,7 @@ import java.util.Date;
import net.i2p.data.DataFormatException;
import net.i2p.data.DataHelper;
import net.i2p.util.Log;
import net.i2p.I2PAppContext;
/**
* Defines the message sent back in reply to a message when requested, containing
@@ -29,9 +30,10 @@ public class DeliveryStatusMessage extends I2NPMessageImpl {
private long _id;
private Date _arrival;
public DeliveryStatusMessage() {
setMessageId(-1);
setArrival(null);
public DeliveryStatusMessage(I2PAppContext context) {
super(context);
setMessageId(-1);
setArrival(null);
}
public long getMessageId() { return _id; }
@@ -41,22 +43,22 @@ public class DeliveryStatusMessage extends I2NPMessageImpl {
public void setArrival(Date arrival) { _arrival = arrival; }
public void readMessage(InputStream in, int type) throws I2NPMessageException, IOException {
if (type != MESSAGE_TYPE) throw new I2NPMessageException("Message type is incorrect for this message");
if (type != MESSAGE_TYPE) throw new I2NPMessageException("Message type is incorrect for this message");
try {
_id = DataHelper.readLong(in, 4);
_arrival = DataHelper.readDate(in);
_id = DataHelper.readLong(in, 4);
_arrival = DataHelper.readDate(in);
} catch (DataFormatException dfe) {
throw new I2NPMessageException("Unable to load the message data", dfe);
}
}
protected byte[] writeMessage() throws I2NPMessageException, IOException {
if ( (_id < 0) || (_arrival == null) ) throw new I2NPMessageException("Not enough data to write out");
if ( (_id < 0) || (_arrival == null) ) throw new I2NPMessageException("Not enough data to write out");
ByteArrayOutputStream os = new ByteArrayOutputStream(32);
try {
DataHelper.writeLong(os, 4, _id);
DataHelper.writeDate(os, _arrival);
DataHelper.writeLong(os, 4, _id);
DataHelper.writeDate(os, _arrival);
} catch (DataFormatException dfe) {
throw new I2NPMessageException("Error writing out the message data", dfe);
}
@@ -66,21 +68,21 @@ public class DeliveryStatusMessage extends I2NPMessageImpl {
public int getType() { return MESSAGE_TYPE; }
public int hashCode() {
return (int)getMessageId() +
DataHelper.hashCode(getArrival());
return (int)getMessageId() +
DataHelper.hashCode(getArrival());
}
public boolean equals(Object object) {
if ( (object != null) && (object instanceof DeliveryStatusMessage) ) {
DeliveryStatusMessage msg = (DeliveryStatusMessage)object;
return DataHelper.eq(getMessageId(),msg.getMessageId()) &&
DataHelper.eq(getArrival(),msg.getArrival());
DataHelper.eq(getArrival(),msg.getArrival());
} else {
return false;
}
}
public String toString() {
public String toString() {
StringBuffer buf = new StringBuffer();
buf.append("[DeliveryStatusMessage: ");
buf.append("\n\tMessage ID: ").append(getMessageId());

View File

@@ -1,9 +1,9 @@
package net.i2p.data.i2np;
/*
* free (adj.): unencumbered; not under the control of others
* Written by jrandom in 2003 and released into the public domain
* with no warranty of any kind, either expressed or implied.
* It probably won't make your computer catch on fire, or eat
* Written by jrandom in 2003 and released into the public domain
* with no warranty of any kind, either expressed or implied.
* It probably won't make your computer catch on fire, or eat
* your children, but it might. Use at your own risk.
*
*/
@@ -18,6 +18,7 @@ import net.i2p.data.DataFormatException;
import net.i2p.data.DataHelper;
import net.i2p.data.DataStructureImpl;
import net.i2p.util.Log;
import net.i2p.router.RouterContext;
/**
* Contains one deliverable message encrypted to a router along with instructions
@@ -26,7 +27,8 @@ import net.i2p.util.Log;
* @author jrandom
*/
public class GarlicClove extends DataStructureImpl {
private final static Log _log = new Log(GarlicClove.class);
private Log _log;
private RouterContext _context;
private DeliveryInstructions _instructions;
private I2NPMessage _msg;
private long _cloveId;
@@ -34,30 +36,34 @@ public class GarlicClove extends DataStructureImpl {
private Certificate _certificate;
private int _replyAction;
private SourceRouteBlock _sourceRouteBlock;
private I2NPMessageHandler _handler;
/** No action requested with the source route block */
public final static int ACTION_NONE = 0;
/**
* A DeliveryStatusMessage is requested with the source route block using
/**
* A DeliveryStatusMessage is requested with the source route block using
* the cloveId as the id received
*
*/
public final static int ACTION_STATUS = 1;
/**
/**
* No DeliveryStatusMessage is requested, but the source route block is
* included for message specific replies
*
*/
public final static int ACTION_MESSAGE_SPECIFIC = 2;
public GarlicClove() {
setInstructions(null);
setData(null);
setCloveId(-1);
setExpiration(null);
setCertificate(null);
setSourceRouteBlockAction(ACTION_NONE);
setSourceRouteBlock(null);
public GarlicClove(RouterContext context) {
_context = context;
_log = context.logManager().getLog(GarlicClove.class);
_handler = new I2NPMessageHandler(context);
setInstructions(null);
setData(null);
setCloveId(-1);
setExpiration(null);
setCertificate(null);
setSourceRouteBlockAction(ACTION_NONE);
setSourceRouteBlock(null);
}
public DeliveryInstructions getInstructions() { return _instructions; }
@@ -76,94 +82,94 @@ public class GarlicClove extends DataStructureImpl {
public void setSourceRouteBlock(SourceRouteBlock block) { _sourceRouteBlock = block; }
public void readBytes(InputStream in) throws DataFormatException, IOException {
_instructions = new DeliveryInstructions();
_instructions.readBytes(in);
_log.debug("Read instructions: " + _instructions);
try {
_msg = new I2NPMessageHandler().readMessage(in);
} catch (I2NPMessageException ime) {
throw new DataFormatException("Unable to read the message from a garlic clove", ime);
}
_cloveId = DataHelper.readLong(in, 4);
_expiration = DataHelper.readDate(in);
_log.debug("CloveID read: " + _cloveId + " expiration read: " + _expiration);
_certificate = new Certificate();
_certificate.readBytes(in);
_log.debug("Read cert: " + _certificate);
int replyStyle = (int)DataHelper.readLong(in, 1);
setSourceRouteBlockAction(replyStyle);
if (replyStyle != ACTION_NONE) {
_sourceRouteBlock = new SourceRouteBlock();
_sourceRouteBlock.readBytes(in);
}
_instructions = new DeliveryInstructions();
_instructions.readBytes(in);
_log.debug("Read instructions: " + _instructions);
try {
_msg = _handler.readMessage(in);
} catch (I2NPMessageException ime) {
throw new DataFormatException("Unable to read the message from a garlic clove", ime);
}
_cloveId = DataHelper.readLong(in, 4);
_expiration = DataHelper.readDate(in);
_log.debug("CloveID read: " + _cloveId + " expiration read: " + _expiration);
_certificate = new Certificate();
_certificate.readBytes(in);
_log.debug("Read cert: " + _certificate);
int replyStyle = (int)DataHelper.readLong(in, 1);
setSourceRouteBlockAction(replyStyle);
if (replyStyle != ACTION_NONE) {
_sourceRouteBlock = new SourceRouteBlock();
_sourceRouteBlock.readBytes(in);
}
}
public void writeBytes(OutputStream out) throws DataFormatException, IOException {
StringBuffer error = new StringBuffer();
if (_instructions == null)
error.append("No instructions ");
if (_msg == null)
error.append("No message ");
if (_cloveId < 0)
error.append("CloveID < 0 [").append(_cloveId).append("] ");
if (_expiration == null)
error.append("Expiration is null ");
if (_certificate == null)
error.append("Certificate is null ");
if (_replyAction < 0)
error.append("Reply action is < 0 [").append(_replyAction).append("] ");;
if (error.length() > 0)
throw new DataFormatException(error.toString());
if ( (_replyAction != 0) && (_sourceRouteBlock == null) )
throw new DataFormatException("Source route block must be specified for non-null action");
_instructions.writeBytes(out);
_log.debug("Wrote instructions: " + _instructions);
_msg.writeBytes(out);
DataHelper.writeLong(out, 4, _cloveId);
DataHelper.writeDate(out, _expiration);
_log.debug("CloveID written: " + _cloveId + " expiration written: " + _expiration);
_certificate.writeBytes(out);
_log.debug("Written cert: " + _certificate);
DataHelper.writeLong(out, 1, _replyAction);
if ( (_replyAction != 0) && (_sourceRouteBlock != null) )
_sourceRouteBlock.writeBytes(out);
StringBuffer error = new StringBuffer();
if (_instructions == null)
error.append("No instructions ");
if (_msg == null)
error.append("No message ");
if (_cloveId < 0)
error.append("CloveID < 0 [").append(_cloveId).append("] ");
if (_expiration == null)
error.append("Expiration is null ");
if (_certificate == null)
error.append("Certificate is null ");
if (_replyAction < 0)
error.append("Reply action is < 0 [").append(_replyAction).append("] ");;
if (error.length() > 0)
throw new DataFormatException(error.toString());
if ( (_replyAction != 0) && (_sourceRouteBlock == null) )
throw new DataFormatException("Source route block must be specified for non-null action");
_instructions.writeBytes(out);
_log.debug("Wrote instructions: " + _instructions);
_msg.writeBytes(out);
DataHelper.writeLong(out, 4, _cloveId);
DataHelper.writeDate(out, _expiration);
_log.debug("CloveID written: " + _cloveId + " expiration written: " + _expiration);
_certificate.writeBytes(out);
_log.debug("Written cert: " + _certificate);
DataHelper.writeLong(out, 1, _replyAction);
if ( (_replyAction != 0) && (_sourceRouteBlock != null) )
_sourceRouteBlock.writeBytes(out);
}
public boolean equals(Object obj) {
if ( (obj == null) || !(obj instanceof GarlicClove))
return false;
GarlicClove clove = (GarlicClove)obj;
return DataHelper.eq(getCertificate(), clove.getCertificate()) &&
DataHelper.eq(getCloveId(), clove.getCloveId()) &&
DataHelper.eq(getData(), clove.getData()) &&
DataHelper.eq(getExpiration(), clove.getExpiration()) &&
DataHelper.eq(getInstructions(), clove.getInstructions()) &&
DataHelper.eq(getSourceRouteBlock(), clove.getSourceRouteBlock()) &&
(getSourceRouteBlockAction() == clove.getSourceRouteBlockAction());
GarlicClove clove = (GarlicClove)obj;
return DataHelper.eq(getCertificate(), clove.getCertificate()) &&
DataHelper.eq(getCloveId(), clove.getCloveId()) &&
DataHelper.eq(getData(), clove.getData()) &&
DataHelper.eq(getExpiration(), clove.getExpiration()) &&
DataHelper.eq(getInstructions(), clove.getInstructions()) &&
DataHelper.eq(getSourceRouteBlock(), clove.getSourceRouteBlock()) &&
(getSourceRouteBlockAction() == clove.getSourceRouteBlockAction());
}
public int hashCode() {
return DataHelper.hashCode(getCertificate()) +
(int)getCloveId() +
DataHelper.hashCode(getData()) +
DataHelper.hashCode(getExpiration()) +
DataHelper.hashCode(getInstructions()) +
DataHelper.hashCode(getSourceRouteBlock()) +
getSourceRouteBlockAction();
return DataHelper.hashCode(getCertificate()) +
(int)getCloveId() +
DataHelper.hashCode(getData()) +
DataHelper.hashCode(getExpiration()) +
DataHelper.hashCode(getInstructions()) +
DataHelper.hashCode(getSourceRouteBlock()) +
getSourceRouteBlockAction();
}
public String toString() {
StringBuffer buf = new StringBuffer(128);
StringBuffer buf = new StringBuffer(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\tSource route style: ").append(getSourceRouteBlockAction());
buf.append("\n\tSource route block: ").append(getSourceRouteBlock());
buf.append("\n\tData: ").append(getData());
buf.append("]");
return buf.toString();
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\tSource route style: ").append(getSourceRouteBlockAction());
buf.append("\n\tSource route block: ").append(getSourceRouteBlock());
buf.append("\n\tData: ").append(getData());
buf.append("]");
return buf.toString();
}
}

View File

@@ -1,9 +1,9 @@
package net.i2p.data.i2np;
/*
* free (adj.): unencumbered; not under the control of others
* Written by jrandom in 2003 and released into the public domain
* with no warranty of any kind, either expressed or implied.
* It probably won't make your computer catch on fire, or eat
* Written by jrandom in 2003 and released into the public domain
* with no warranty of any kind, either expressed or implied.
* It probably won't make your computer catch on fire, or eat
* your children, but it might. Use at your own risk.
*
*/
@@ -15,6 +15,7 @@ import java.io.InputStream;
import net.i2p.data.DataFormatException;
import net.i2p.data.DataHelper;
import net.i2p.util.Log;
import net.i2p.I2PAppContext;
/**
* Defines the wrapped garlic message
@@ -26,33 +27,34 @@ public class GarlicMessage extends I2NPMessageImpl {
public final static int MESSAGE_TYPE = 11;
private byte[] _data;
public GarlicMessage() {
setData(null);
public GarlicMessage(I2PAppContext context) {
super(context);
setData(null);
}
public byte[] getData() { return _data; }
public void setData(byte[] data) { _data = data; }
public void readMessage(InputStream in, int type) throws I2NPMessageException, IOException {
if (type != MESSAGE_TYPE) throw new I2NPMessageException("Message type is incorrect for this message");
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");
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");
} catch (DataFormatException dfe) {
throw new I2NPMessageException("Unable to load the message data", dfe);
}
}
protected byte[] writeMessage() throws I2NPMessageException, IOException {
if ( (_data == null) || (_data.length <= 0) ) throw new I2NPMessageException("Not enough data to write out");
if ( (_data == null) || (_data.length <= 0) ) throw new I2NPMessageException("Not enough data to write out");
ByteArrayOutputStream os = new ByteArrayOutputStream(32);
try {
DataHelper.writeLong(os, 4, _data.length);
os.write(_data);
DataHelper.writeLong(os, 4, _data.length);
os.write(_data);
} catch (DataFormatException dfe) {
throw new I2NPMessageException("Error writing out the message data", dfe);
}
@@ -62,7 +64,7 @@ public class GarlicMessage extends I2NPMessageImpl {
public int getType() { return MESSAGE_TYPE; }
public int hashCode() {
return DataHelper.hashCode(getData());
return DataHelper.hashCode(getData());
}
public boolean equals(Object object) {
@@ -74,7 +76,7 @@ public class GarlicMessage extends I2NPMessageImpl {
}
}
public String toString() {
public String toString() {
StringBuffer buf = new StringBuffer();
buf.append("[GarlicMessage: ");
buf.append("\n\tData length: ").append(getData().length).append(" bytes");

View File

@@ -1,9 +1,9 @@
package net.i2p.data.i2np;
/*
* free (adj.): unencumbered; not under the control of others
* Written by jrandom in 2003 and released into the public domain
* with no warranty of any kind, either expressed or implied.
* It probably won't make your computer catch on fire, or eat
* Written by jrandom in 2003 and released into the public domain
* with no warranty of any kind, either expressed or implied.
* It probably won't make your computer catch on fire, or eat
* your children, but it might. Use at your own risk.
*
*/
@@ -16,20 +16,25 @@ import net.i2p.data.DataFormatException;
import net.i2p.data.DataHelper;
import net.i2p.util.Clock;
import net.i2p.util.Log;
import net.i2p.I2PAppContext;
/**
* Handle messages from router to router
*
*/
public class I2NPMessageHandler {
private final static Log _log = new Log(I2NPMessageHandler.class);
private Log _log;
private I2PAppContext _context;
private long _lastReadBegin;
private long _lastReadEnd;
public I2NPMessageHandler() {}
public I2NPMessageHandler(I2PAppContext context) {
_context = context;
_log = context.logManager().getLog(I2NPMessageHandler.class);
}
/**
* Read an I2NPMessage from the stream and return the fully populated object.
*
*
* @throws IOException if there is an IO problem reading from the stream
* @throws I2NPMessageException if there is a problem handling the particular
* message - if it is an unknown type or has improper formatting, etc.
@@ -37,10 +42,10 @@ public class I2NPMessageHandler {
public I2NPMessage readMessage(InputStream in) throws IOException, I2NPMessageException {
try {
int type = (int)DataHelper.readLong(in, 1);
_lastReadBegin = Clock.getInstance().now();
_lastReadBegin = System.currentTimeMillis();
I2NPMessage msg = createMessage(in, type);
msg.readBytes(in, type);
_lastReadEnd = Clock.getInstance().now();
_lastReadEnd = System.currentTimeMillis();
return msg;
} catch (DataFormatException dfe) {
throw new I2NPMessageException("Error reading the message", dfe);
@@ -50,31 +55,31 @@ public class I2NPMessageHandler {
public long getLastReadTime() { return _lastReadEnd - _lastReadBegin; }
/**
* Yes, this is fairly ugly, but its the only place it ever happens.
* Yes, this is fairly ugly, but its the only place it ever happens.
*
*/
private static I2NPMessage createMessage(InputStream in, int type) throws IOException, I2NPMessageException {
private I2NPMessage createMessage(InputStream in, int type) throws IOException, I2NPMessageException {
switch (type) {
case DatabaseStoreMessage.MESSAGE_TYPE:
return new DatabaseStoreMessage();
case DatabaseLookupMessage.MESSAGE_TYPE:
return new DatabaseLookupMessage();
case DatabaseSearchReplyMessage.MESSAGE_TYPE:
return new DatabaseSearchReplyMessage();
case DeliveryStatusMessage.MESSAGE_TYPE:
return new DeliveryStatusMessage();
case GarlicMessage.MESSAGE_TYPE:
return new GarlicMessage();
case TunnelMessage.MESSAGE_TYPE:
return new TunnelMessage();
case DataMessage.MESSAGE_TYPE:
return new DataMessage();
case SourceRouteReplyMessage.MESSAGE_TYPE:
return new SourceRouteReplyMessage();
case TunnelCreateMessage.MESSAGE_TYPE:
return new TunnelCreateMessage();
case TunnelCreateStatusMessage.MESSAGE_TYPE:
return new TunnelCreateStatusMessage();
case DatabaseStoreMessage.MESSAGE_TYPE:
return new DatabaseStoreMessage(_context);
case DatabaseLookupMessage.MESSAGE_TYPE:
return new DatabaseLookupMessage(_context);
case DatabaseSearchReplyMessage.MESSAGE_TYPE:
return new DatabaseSearchReplyMessage(_context);
case DeliveryStatusMessage.MESSAGE_TYPE:
return new DeliveryStatusMessage(_context);
case GarlicMessage.MESSAGE_TYPE:
return new GarlicMessage(_context);
case TunnelMessage.MESSAGE_TYPE:
return new TunnelMessage(_context);
case DataMessage.MESSAGE_TYPE:
return new DataMessage(_context);
case SourceRouteReplyMessage.MESSAGE_TYPE:
return new SourceRouteReplyMessage(_context);
case TunnelCreateMessage.MESSAGE_TYPE:
return new TunnelCreateMessage(_context);
case TunnelCreateStatusMessage.MESSAGE_TYPE:
return new TunnelCreateStatusMessage(_context);
default:
throw new I2NPMessageException("The type "+ type + " is an unknown I2NP message");
}
@@ -82,7 +87,7 @@ public class I2NPMessageHandler {
public static void main(String args[]) {
try {
I2NPMessage msg = new I2NPMessageHandler().readMessage(new FileInputStream(args[0]));
I2NPMessage msg = new I2NPMessageHandler(I2PAppContext.getGlobalContext()).readMessage(new FileInputStream(args[0]));
System.out.println(msg);
} catch (Exception e) {
e.printStackTrace();

View File

@@ -1,9 +1,9 @@
package net.i2p.data.i2np;
/*
* free (adj.): unencumbered; not under the control of others
* Written by jrandom in 2003 and released into the public domain
* with no warranty of any kind, either expressed or implied.
* It probably won't make your computer catch on fire, or eat
* Written by jrandom in 2003 and released into the public domain
* with no warranty of any kind, either expressed or implied.
* It probably won't make your computer catch on fire, or eat
* your children, but it might. Use at your own risk.
*
*/
@@ -19,6 +19,7 @@ import net.i2p.data.DataStructureImpl;
import net.i2p.util.Clock;
import net.i2p.util.Log;
import net.i2p.util.RandomSource;
import net.i2p.I2PAppContext;
/**
* Defines the base message implementation.
@@ -26,15 +27,18 @@ import net.i2p.util.RandomSource;
* @author jrandom
*/
public abstract class I2NPMessageImpl extends DataStructureImpl implements I2NPMessage {
private final static Log _log = new Log(I2NPMessageImpl.class);
private Log _log;
protected I2PAppContext _context;
private Date _expiration;
private long _uniqueId;
public final static long DEFAULT_EXPIRATION_MS = 1*60*1000; // 1 minute by default
public I2NPMessageImpl() {
_expiration = new Date(Clock.getInstance().now() + DEFAULT_EXPIRATION_MS);
_uniqueId = RandomSource.getInstance().nextInt(Integer.MAX_VALUE);
public I2NPMessageImpl(I2PAppContext context) {
_context = context;
_log = context.logManager().getLog(I2NPMessageImpl.class);
_expiration = new Date(_context.clock().now() + DEFAULT_EXPIRATION_MS);
_uniqueId = _context.random().nextInt(Integer.MAX_VALUE);
}
/**
@@ -45,8 +49,8 @@ public abstract class I2NPMessageImpl extends DataStructureImpl implements I2NPM
protected abstract byte[] writeMessage() 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
* 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
@@ -58,35 +62,35 @@ public abstract class I2NPMessageImpl extends DataStructureImpl implements I2NPM
protected abstract void readMessage(InputStream in, int type) throws I2NPMessageException, IOException;
public void readBytes(InputStream in) throws DataFormatException, IOException {
try {
readBytes(in, -1);
} catch (I2NPMessageException ime) {
throw new DataFormatException("Bad bytes", ime);
}
try {
readBytes(in, -1);
} catch (I2NPMessageException ime) {
throw new DataFormatException("Bad bytes", ime);
}
}
public void readBytes(InputStream in, int type) throws I2NPMessageException, IOException {
try {
if (type < 0)
type = (int)DataHelper.readLong(in, 1);
_uniqueId = DataHelper.readLong(in, 4);
_expiration = DataHelper.readDate(in);
} catch (DataFormatException dfe) {
throw new I2NPMessageException("Error reading the message header", dfe);
}
_log.debug("Reading bytes: type = " + type + " / uniqueId : " + _uniqueId + " / expiration : " + _expiration);
readMessage(in, type);
try {
if (type < 0)
type = (int)DataHelper.readLong(in, 1);
_uniqueId = DataHelper.readLong(in, 4);
_expiration = DataHelper.readDate(in);
} catch (DataFormatException dfe) {
throw new I2NPMessageException("Error reading the message header", dfe);
}
_log.debug("Reading bytes: type = " + type + " / uniqueId : " + _uniqueId + " / expiration : " + _expiration);
readMessage(in, type);
}
public void writeBytes(OutputStream out) throws DataFormatException, IOException {
try {
DataHelper.writeLong(out, 1, getType());
DataHelper.writeLong(out, 4, _uniqueId);
DataHelper.writeDate(out, _expiration);
_log.debug("Writing bytes: type = " + getType() + " / uniqueId : " + _uniqueId + " / expiration : " + _expiration);
byte[] data = writeMessage();
out.write(data);
} catch (I2NPMessageException ime) {
throw new DataFormatException("Error writing out the I2NP message data", ime);
}
try {
DataHelper.writeLong(out, 1, getType());
DataHelper.writeLong(out, 4, _uniqueId);
DataHelper.writeDate(out, _expiration);
_log.debug("Writing bytes: type = " + getType() + " / uniqueId : " + _uniqueId + " / expiration : " + _expiration);
byte[] data = writeMessage();
out.write(data);
} catch (I2NPMessageException ime) {
throw new DataFormatException("Error writing out the I2NP message data", ime);
}
}
/**

View File

@@ -1,9 +1,9 @@
package net.i2p.data.i2np;
/*
* free (adj.): unencumbered; not under the control of others
* Written by jrandom in 2003 and released into the public domain
* with no warranty of any kind, either expressed or implied.
* It probably won't make your computer catch on fire, or eat
* Written by jrandom in 2003 and released into the public domain
* with no warranty of any kind, either expressed or implied.
* It probably won't make your computer catch on fire, or eat
* your children, but it might. Use at your own risk.
*
*/
@@ -13,9 +13,10 @@ import java.io.InputStream;
import net.i2p.util.I2PThread;
import net.i2p.util.Log;
import net.i2p.router.RouterContext;
/**
* The I2NPMessageReader reads an InputStream (using
* The I2NPMessageReader reads an InputStream (using
* {@link I2NPMessageHandler I2NPMessageHandler}) and passes out events to a registered
* listener, where events are either messages being received, exceptions being
* thrown, or the connection being closed. Routers should use this rather
@@ -24,23 +25,26 @@ import net.i2p.util.Log;
* @author jrandom
*/
public class I2NPMessageReader {
private final static Log _log = new Log(I2NPMessageReader.class);
private Log _log;
private RouterContext _context;
private InputStream _stream;
private I2NPMessageEventListener _listener;
private I2NPMessageReaderRunner _reader;
private Thread _readerThread;
public I2NPMessageReader(InputStream stream, I2NPMessageEventListener lsnr) {
this(stream, lsnr, "I2NP Reader");
public I2NPMessageReader(RouterContext context, InputStream stream, I2NPMessageEventListener lsnr) {
this(context, stream, lsnr, "I2NP Reader");
}
public I2NPMessageReader(InputStream stream, I2NPMessageEventListener lsnr, String name) {
_stream = stream;
public I2NPMessageReader(RouterContext context, InputStream stream, I2NPMessageEventListener lsnr, String name) {
_context = context;
_log = context.logManager().getLog(I2NPMessageReader.class);
_stream = stream;
setListener(lsnr);
_reader = new I2NPMessageReaderRunner();
_readerThread = new I2PThread(_reader);
_readerThread.setName(name);
_readerThread.setDaemon(true);
_readerThread.setName(name);
_readerThread.setDaemon(true);
}
public void setListener(I2NPMessageEventListener lsnr) { _listener = lsnr; }
@@ -50,7 +54,7 @@ public class I2NPMessageReader {
* Instruct the reader to begin reading messages off the stream
*
*/
public void startReading() { _readerThread.start(); }
public void startReading() { _readerThread.start(); }
/**
* Have the already started reader pause its reading indefinitely
*
@@ -62,7 +66,7 @@ public class I2NPMessageReader {
*/
public void resumeReading() { _reader.resumeRunner(); }
/**
* Cancel reading.
* Cancel reading.
*
*/
public void stopReading() { _reader.cancelRunner(); }
@@ -90,22 +94,22 @@ public class I2NPMessageReader {
*
*/
public void disconnected(I2NPMessageReader reader);
}
}
private class I2NPMessageReaderRunner implements Runnable {
private boolean _doRun;
private boolean _doRun;
private boolean _stayAlive;
private I2NPMessageHandler _handler;
private I2NPMessageHandler _handler;
public I2NPMessageReaderRunner() {
_doRun = true;
_stayAlive = true;
_handler = new I2NPMessageHandler();
_handler = new I2NPMessageHandler(_context);
}
public void pauseRunner() { _doRun = false; }
public void resumeRunner() { _doRun = true; }
public void cancelRunner() {
public void cancelRunner() {
_doRun = false;
_stayAlive = false;
_stayAlive = false;
}
public void run() {
while (_stayAlive) {
@@ -114,16 +118,16 @@ public class I2NPMessageReader {
try {
I2NPMessage msg = _handler.readMessage(_stream);
if (msg != null) {
long msToRead = _handler.getLastReadTime();
long msToRead = _handler.getLastReadTime();
_listener.messageReceived(I2NPMessageReader.this, msg, msToRead);
}
}
} catch (I2NPMessageException ime) {
//_log.warn("Error handling message", ime);
//_log.warn("Error handling message", ime);
_listener.readError(I2NPMessageReader.this, ime);
_listener.disconnected(I2NPMessageReader.this);
cancelRunner();
_listener.disconnected(I2NPMessageReader.this);
cancelRunner();
} catch (IOException ioe) {
_log.warn("IO Error handling message", ioe);
_log.warn("IO Error handling message", ioe);
_listener.disconnected(I2NPMessageReader.this);
cancelRunner();
}

View File

@@ -26,6 +26,7 @@ import net.i2p.data.PublicKey;
import net.i2p.data.SessionKey;
import net.i2p.data.SessionTag;
import net.i2p.util.Log;
import net.i2p.I2PAppContext;
/**
@@ -46,14 +47,14 @@ public class SourceRouteBlock extends DataStructureImpl {
private long _decryptedExpiration;
public SourceRouteBlock() {
setRouter(null);
setData(null);
setKey(null);
setTag((byte[])null);
_decryptedInstructions = null;
_decryptedMessageId = -1;
_decryptedCertificate = null;
_decryptedExpiration = -1;
setRouter(null);
setData(null);
setKey(null);
setTag((byte[])null);
_decryptedInstructions = null;
_decryptedMessageId = -1;
_decryptedCertificate = null;
_decryptedExpiration = -1;
}
/**
@@ -92,9 +93,9 @@ public class SourceRouteBlock extends DataStructureImpl {
public byte[] getTag() { return _tag; }
public void setTag(SessionTag tag) { setTag(tag.getData()); }
public void setTag(byte tag[]) {
if ( (tag != null) && (tag.length != SessionTag.BYTE_LENGTH) )
throw new IllegalArgumentException("Tag must be either null or 32 bytes");
_tag = tag;
if ( (tag != null) && (tag.length != SessionTag.BYTE_LENGTH) )
throw new IllegalArgumentException("Tag must be either null or 32 bytes");
_tag = tag;
}
/**
@@ -126,100 +127,105 @@ public class SourceRouteBlock extends DataStructureImpl {
*
* @throws DataFormatException if the data is invalid or could not be encrypted
*/
public void setData(DeliveryInstructions instructions, long messageId, Certificate cert, long expiration, PublicKey replyThrough) throws DataFormatException {
try {
ByteArrayOutputStream baos = new ByteArrayOutputStream(64);
public void setData(I2PAppContext ctx, DeliveryInstructions instructions,
long messageId, Certificate cert, long expiration,
PublicKey replyThrough) throws DataFormatException {
try {
ByteArrayOutputStream baos = new ByteArrayOutputStream(64);
_decryptedInstructions = instructions;
_decryptedMessageId = messageId;
_decryptedCertificate = cert;
_decryptedExpiration = expiration;
instructions.writeBytes(baos);
DataHelper.writeLong(baos, 4, messageId);
cert.writeBytes(baos);
DataHelper.writeDate(baos, new Date(expiration));
_decryptedInstructions = instructions;
_decryptedMessageId = messageId;
_decryptedCertificate = cert;
_decryptedExpiration = expiration;
int paddedSize = 256;
SessionKey sessKey = null;
SessionTag tag = null;
if (instructions.getDelayRequested()) {
// always use a new key if we're delaying, since the reply block may not be used within the
// window of a session
sessKey = KeyGenerator.getInstance().generateSessionKey();
tag = null;
_log.debug("Delay requested - creating a new session key");
} else {
sessKey = SessionKeyManager.getInstance().getCurrentKey(replyThrough);
if (sessKey == null) {
sessKey = KeyGenerator.getInstance().generateSessionKey();
tag = null;
_log.debug("No delay requested, but no session key is known");
} else {
tag = SessionKeyManager.getInstance().consumeNextAvailableTag(replyThrough, sessKey);
}
}
byte encData[] = ElGamalAESEngine.encrypt(baos.toByteArray(), replyThrough, sessKey, null, tag, paddedSize);
setData(encData);
} catch (IOException ioe) {
throw new DataFormatException("Error writing out the source route block data", ioe);
} catch (DataFormatException dfe) {
throw new DataFormatException("Error writing out the source route block data", dfe);
}
instructions.writeBytes(baos);
DataHelper.writeLong(baos, 4, messageId);
cert.writeBytes(baos);
DataHelper.writeDate(baos, new Date(expiration));
int paddedSize = 256;
SessionKey sessKey = null;
SessionTag tag = null;
if (instructions.getDelayRequested()) {
// always use a new key if we're delaying, since the reply block may not be used within the
// window of a session
sessKey = ctx.keyGenerator().generateSessionKey();
tag = null;
if (_log.shouldLog(Log.DEBUG))
_log.debug("Delay requested - creating a new session key");
} else {
sessKey = ctx.sessionKeyManager().getCurrentKey(replyThrough);
if (sessKey == null) {
sessKey = ctx.keyGenerator().generateSessionKey();
tag = null;
if (_log.shouldLog(Log.DEBUG))
_log.debug("No delay requested, but no session key is known");
} else {
tag = ctx.sessionKeyManager().consumeNextAvailableTag(replyThrough, sessKey);
}
}
byte encData[] = ctx.elGamalAESEngine().encrypt(baos.toByteArray(), replyThrough,
sessKey, null, tag, paddedSize);
setData(encData);
} catch (IOException ioe) {
throw new DataFormatException("Error writing out the source route block data", ioe);
} catch (DataFormatException dfe) {
throw new DataFormatException("Error writing out the source route block data", dfe);
}
}
public void readBytes(InputStream in) throws DataFormatException, IOException {
_router = new Hash();
_router.readBytes(in);
int size = (int)DataHelper.readLong(in, 2);
_data = new byte[size];
int read = read(in, _data);
if (read != _data.length)
throw new DataFormatException("Incorrect # of bytes read for source route block: " + read);
_key = new SessionKey();
_key.readBytes(in);
_tag = new byte[32];
read = read(in, _tag);
if (read != _tag.length)
throw new DataFormatException("Incorrect # of bytes read for session tag: " + read);
_router = new Hash();
_router.readBytes(in);
int size = (int)DataHelper.readLong(in, 2);
_data = new byte[size];
int read = read(in, _data);
if (read != _data.length)
throw new DataFormatException("Incorrect # of bytes read for source route block: " + read);
_key = new SessionKey();
_key.readBytes(in);
_tag = new byte[32];
read = read(in, _tag);
if (read != _tag.length)
throw new DataFormatException("Incorrect # of bytes read for session tag: " + read);
}
public void writeBytes(OutputStream out) throws DataFormatException, IOException {
if ( (_router == null) || (_data == null) || (_key == null) || (_tag == null) || (_tag.length != 32) )
throw new DataFormatException("Insufficient data to write");
_router.writeBytes(out);
DataHelper.writeLong(out, 2, _data.length);
out.write(_data);
_key.writeBytes(out);
out.write(_tag);
throw new DataFormatException("Insufficient data to write");
_router.writeBytes(out);
DataHelper.writeLong(out, 2, _data.length);
out.write(_data);
_key.writeBytes(out);
out.write(_tag);
}
public boolean equals(Object obj) {
if ( (obj == null) || !(obj instanceof SourceRouteBlock))
return false;
SourceRouteBlock block = (SourceRouteBlock)obj;
return DataHelper.eq(getRouter(), block.getRouter()) &&
DataHelper.eq(getData(), block.getData()) &&
DataHelper.eq(getKey(), block.getKey()) &&
DataHelper.eq(getTag(), block.getTag());
SourceRouteBlock block = (SourceRouteBlock)obj;
return DataHelper.eq(getRouter(), block.getRouter()) &&
DataHelper.eq(getData(), block.getData()) &&
DataHelper.eq(getKey(), block.getKey()) &&
DataHelper.eq(getTag(), block.getTag());
}
public int hashCode() {
return DataHelper.hashCode(getRouter()) +
DataHelper.hashCode(getData()) +
DataHelper.hashCode(getKey()) +
DataHelper.hashCode(getTag());
DataHelper.hashCode(getData()) +
DataHelper.hashCode(getKey()) +
DataHelper.hashCode(getTag());
}
public String toString() {
StringBuffer buf = new StringBuffer(128);
StringBuffer buf = new StringBuffer(128);
buf.append("[SourceRouteBlock: ");
buf.append("\n\tRouter: ").append(getRouter());
buf.append("\n\tData: ").append(DataHelper.toString(getData(), getData().length));
buf.append("\n\tTag: ").append(DataHelper.toString(getTag(), (getTag() != null ? getTag().length : 0)));
buf.append("\n\tKey: ").append(getKey());
buf.append("]");
return buf.toString();
buf.append("\n\tRouter: ").append(getRouter());
buf.append("\n\tData: ").append(DataHelper.toString(getData(), getData().length));
buf.append("\n\tTag: ").append(DataHelper.toString(getTag(), (getTag() != null ? getTag().length : 0)));
buf.append("\n\tKey: ").append(getKey());
buf.append("]");
return buf.toString();
}
}

View File

@@ -19,6 +19,7 @@ import net.i2p.data.DataFormatException;
import net.i2p.data.DataHelper;
import net.i2p.data.PrivateKey;
import net.i2p.util.Log;
import net.i2p.I2PAppContext;
/**
* Defines a message directed by a source route block to deliver a message to an
@@ -35,14 +36,17 @@ public class SourceRouteReplyMessage extends I2NPMessageImpl {
private long _decryptedMessageId;
private Certificate _decryptedCertificate;
private long _decryptedExpiration;
private I2NPMessageHandler _handler;
public SourceRouteReplyMessage() {
_encryptedHeader = null;
_message = null;
_decryptedInstructions = null;
_decryptedMessageId = -1;
_decryptedCertificate = null;
_decryptedExpiration = -1;
public SourceRouteReplyMessage(I2PAppContext context) {
super(context);
_handler = new I2NPMessageHandler(context);
_encryptedHeader = null;
_message = null;
_decryptedInstructions = null;
_decryptedMessageId = -1;
_decryptedCertificate = null;
_decryptedExpiration = -1;
}
/**
@@ -77,54 +81,56 @@ public class SourceRouteReplyMessage extends I2NPMessageImpl {
* @throws DataFormatException if the decryption fails or if the data is somehow malformed
*/
public void decryptHeader(PrivateKey key) throws DataFormatException {
if ( (_encryptedHeader == null) || (_encryptedHeader.length <= 0) )
throw new DataFormatException("No header to decrypt");
byte decr[] = ElGamalAESEngine.decrypt(_encryptedHeader, key);
if (decr == null)
throw new DataFormatException("Decrypted data is null");
try {
ByteArrayInputStream bais = new ByteArrayInputStream(decr);
_decryptedInstructions = new DeliveryInstructions();
_decryptedInstructions.readBytes(bais);
_decryptedMessageId = DataHelper.readLong(bais, 4);
_decryptedCertificate = new Certificate();
_decryptedCertificate.readBytes(bais);
_decryptedExpiration = DataHelper.readDate(bais).getTime();
if ( (_encryptedHeader == null) || (_encryptedHeader.length <= 0) )
throw new DataFormatException("No header to decrypt");
} catch (IOException ioe) {
throw new DataFormatException("Error reading the source route reply header", ioe);
} catch (DataFormatException dfe) {
throw new DataFormatException("Error reading the source route reply header", dfe);
}
byte decr[] = _context.elGamalAESEngine().decrypt(_encryptedHeader, key);
if (decr == null)
throw new DataFormatException("Decrypted data is null");
try {
ByteArrayInputStream bais = new ByteArrayInputStream(decr);
_decryptedInstructions = new DeliveryInstructions();
_decryptedInstructions.readBytes(bais);
_decryptedMessageId = DataHelper.readLong(bais, 4);
_decryptedCertificate = new Certificate();
_decryptedCertificate.readBytes(bais);
_decryptedExpiration = DataHelper.readDate(bais).getTime();
} catch (IOException ioe) {
throw new DataFormatException("Error reading the source route reply header", ioe);
} catch (DataFormatException dfe) {
throw new DataFormatException("Error reading the source route reply header", dfe);
}
}
public void readMessage(InputStream in, int type) throws I2NPMessageException, IOException {
if (type != MESSAGE_TYPE) throw new I2NPMessageException("Message type is incorrect for this message");
if (type != MESSAGE_TYPE)
throw new I2NPMessageException("Message type is incorrect for this message");
try {
int headerSize = (int)DataHelper.readLong(in, 2);
_encryptedHeader = new byte[headerSize];
int read = read(in, _encryptedHeader);
if (read != headerSize)
throw new DataFormatException("Not enough bytes to read the header (read = " + read + ", required = " + headerSize + ")");
_message = new I2NPMessageHandler().readMessage(in);
int headerSize = (int)DataHelper.readLong(in, 2);
_encryptedHeader = new byte[headerSize];
int read = read(in, _encryptedHeader);
if (read != headerSize)
throw new DataFormatException("Not enough bytes to read the header (read = " + read
+ ", required = " + headerSize + ")");
_message = _handler.readMessage(in);
} catch (DataFormatException dfe) {
throw new I2NPMessageException("Unable to load the message data", dfe);
}
}
protected byte[] writeMessage() throws I2NPMessageException, IOException {
if ( (_encryptedHeader == null) || (_message == null) )
throw new I2NPMessageException("Not enough data to write out");
ByteArrayOutputStream os = new ByteArrayOutputStream(1024);
if ( (_encryptedHeader == null) || (_message == null) )
throw new I2NPMessageException("Not enough data to write out");
ByteArrayOutputStream os = new ByteArrayOutputStream(1024);
try {
DataHelper.writeLong(os, 2, _encryptedHeader.length);
os.write(_encryptedHeader);
_message.writeBytes(os);
DataHelper.writeLong(os, 2, _encryptedHeader.length);
os.write(_encryptedHeader);
_message.writeBytes(os);
} catch (DataFormatException dfe) {
throw new I2NPMessageException("Error writing out the message data", dfe);
}
@@ -134,15 +140,15 @@ public class SourceRouteReplyMessage extends I2NPMessageImpl {
public int getType() { return MESSAGE_TYPE; }
public int hashCode() {
return DataHelper.hashCode(_encryptedHeader) +
DataHelper.hashCode(_message);
return DataHelper.hashCode(_encryptedHeader) +
DataHelper.hashCode(_message);
}
public boolean equals(Object object) {
if ( (object != null) && (object instanceof SourceRouteReplyMessage) ) {
SourceRouteReplyMessage msg = (SourceRouteReplyMessage)object;
return DataHelper.eq(_message,msg._message) &&
DataHelper.eq(_encryptedHeader,msg._encryptedHeader);
DataHelper.eq(_encryptedHeader,msg._encryptedHeader);
} else {
return false;
}

View File

@@ -1,9 +1,9 @@
package net.i2p.data.i2np;
/*
* free (adj.): unencumbered; not under the control of others
* Written by jrandom in 2003 and released into the public domain
* with no warranty of any kind, either expressed or implied.
* It probably won't make your computer catch on fire, or eat
* Written by jrandom in 2003 and released into the public domain
* with no warranty of any kind, either expressed or implied.
* It probably won't make your computer catch on fire, or eat
* your children, but it might. Use at your own risk.
*
*/
@@ -18,6 +18,7 @@ import net.i2p.data.DataHelper;
import net.i2p.data.Hash;
import net.i2p.data.TunnelId;
import net.i2p.util.Log;
import net.i2p.I2PAppContext;
/**
* Defines the message sent to a router to request that it participate in a
@@ -52,23 +53,24 @@ public class TunnelCreateMessage extends I2NPMessageImpl {
private final static long FLAG_DUMMY = 1 << 7;
private final static long FLAG_REORDER = 1 << 6;
public TunnelCreateMessage() {
setParticipantType(-1);
setNextRouter(null);
setTunnelId(null);
setTunnelDurationSeconds(-1);
setConfigurationKey(null);
setMaxPeakMessagesPerMin(-1);
setMaxAvgMessagesPerMin(-1);
setMaxPeakBytesPerMin(-1);
setMaxAvgBytesPerMin(-1);
setIncludeDummyTraffic(false);
setReorderMessages(false);
setVerificationPublicKey(null);
setVerificationPrivateKey(null);
setTunnelKey(null);
setCertificate(null);
setReplyBlock(null);
public TunnelCreateMessage(I2PAppContext context) {
super(context);
setParticipantType(-1);
setNextRouter(null);
setTunnelId(null);
setTunnelDurationSeconds(-1);
setConfigurationKey(null);
setMaxPeakMessagesPerMin(-1);
setMaxAvgMessagesPerMin(-1);
setMaxPeakBytesPerMin(-1);
setMaxAvgBytesPerMin(-1);
setIncludeDummyTraffic(false);
setReorderMessages(false);
setVerificationPublicKey(null);
setVerificationPrivateKey(null);
setTunnelKey(null);
setCertificate(null);
setReplyBlock(null);
}
public void setParticipantType(int type) { _participantType = type; }
@@ -105,41 +107,41 @@ public class TunnelCreateMessage extends I2NPMessageImpl {
public SourceRouteBlock getReplyBlock() { return _replyBlock; }
public void readMessage(InputStream in, int type) throws I2NPMessageException, IOException {
if (type != MESSAGE_TYPE) throw new I2NPMessageException("Message type is incorrect for this message");
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);
}
_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 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);
_replyBlock = new SourceRouteBlock();
_replyBlock.readBytes(in);
_participantType = (int)DataHelper.readLong(in, 1);
if (_participantType != PARTICIPANT_TYPE_ENDPOINT) {
_nextRouter = new Hash();
_nextRouter.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 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);
_replyBlock = new SourceRouteBlock();
_replyBlock.readBytes(in);
} catch (DataFormatException dfe) {
throw new I2NPMessageException("Unable to load the message data", dfe);
}
@@ -148,146 +150,99 @@ public class TunnelCreateMessage extends I2NPMessageImpl {
protected byte[] writeMessage() throws I2NPMessageException, IOException {
ByteArrayOutputStream os = new ByteArrayOutputStream(32);
try {
DataHelper.writeLong(os, 1, _participantType);
if (_participantType != PARTICIPANT_TYPE_ENDPOINT) {
_nextRouter.writeBytes(os);
}
_tunnelId.writeBytes(os);
DataHelper.writeLong(os, 4, _tunnelDuration);
_configKey.writeBytes(os);
DataHelper.writeLong(os, 4, _maxPeakMessagesPerMin);
DataHelper.writeLong(os, 4, _maxAvgMessagesPerMin);
DataHelper.writeLong(os, 4, _maxPeakBytesPerMin);
DataHelper.writeLong(os, 4, _maxAvgBytesPerMin);
long flags = getFlags();
DataHelper.writeLong(os, 1, flags);
_verificationPubKey.writeBytes(os);
if (_participantType == PARTICIPANT_TYPE_GATEWAY) {
_verificationPrivKey.writeBytes(os);
}
if ( (_participantType == PARTICIPANT_TYPE_ENDPOINT) || (_participantType == PARTICIPANT_TYPE_GATEWAY) ) {
_tunnelKey.writeBytes(os);
}
_certificate.writeBytes(os);
_replyBlock.writeBytes(os);
DataHelper.writeLong(os, 1, _participantType);
if (_participantType != PARTICIPANT_TYPE_ENDPOINT) {
_nextRouter.writeBytes(os);
}
_tunnelId.writeBytes(os);
DataHelper.writeLong(os, 4, _tunnelDuration);
_configKey.writeBytes(os);
DataHelper.writeLong(os, 4, _maxPeakMessagesPerMin);
DataHelper.writeLong(os, 4, _maxAvgMessagesPerMin);
DataHelper.writeLong(os, 4, _maxPeakBytesPerMin);
DataHelper.writeLong(os, 4, _maxAvgBytesPerMin);
long flags = getFlags();
DataHelper.writeLong(os, 1, flags);
_verificationPubKey.writeBytes(os);
if (_participantType == PARTICIPANT_TYPE_GATEWAY) {
_verificationPrivKey.writeBytes(os);
}
if ( (_participantType == PARTICIPANT_TYPE_ENDPOINT) || (_participantType == PARTICIPANT_TYPE_GATEWAY) ) {
_tunnelKey.writeBytes(os);
}
_certificate.writeBytes(os);
_replyBlock.writeBytes(os);
} catch (Throwable t) {
throw new I2NPMessageException("Error writing out the message data", t);
}
/*
try {
DataHelper.writeLong(os, 1, _participantType);
if (_participantType != PARTICIPANT_TYPE_ENDPOINT) {
if (_nextRouter == null)
throw new I2NPMessageException("Next router is not defined");
_nextRouter.writeBytes(os);
}
if (_tunnelId == null)
throw new I2NPMessageException("Tunnel ID is not defined");
_tunnelId.writeBytes(os);
if (_tunnelDuration < 0)
throw new I2NPMessageException("Tunnel duration is negative");
DataHelper.writeLong(os, 4, _tunnelDuration);
if (_configKey == null)
throw new I2NPMessageException("Configuration key is not defined");
_configKey.writeBytes(os);
if ( (_maxPeakMessagesPerMin < 0) || (_maxAvgMessagesPerMin < 0) ||
(_maxAvgMessagesPerMin < 0) || (_maxAvgBytesPerMin < 0) )
throw new I2NPMessageException("Negative limits defined");
long flags = getFlags();
DataHelper.writeLong(os, 1, flags);
if (_verificationPubKey == null)
throw new I2NPMessageException("Verification public key is not defined");
_verificationPubKey.writeBytes(os);
if (_participantType == PARTICIPANT_TYPE_GATEWAY) {
if (_verificationPrivKey == null)
throw new I2NPMessageException("Verification private key is needed and not defined");
_verificationPrivKey.writeBytes(os);
}
if ( (_participantType == PARTICIPANT_TYPE_ENDPOINT) || (_participantType == PARTICIPANT_TYPE_GATEWAY) ) {
if (_tunnelKey == null)
throw new I2NPMessageException("Tunnel key is needed and not defined");
_tunnelKey.writeBytes(os);
}
if (_certificate == null)
throw new I2NPMessageException("Certificate is not defined");
_certificate.writeBytes(os);
if (_replyBlock == null)
throw new I2NPMessageException("Reply block not defined");
_replyBlock.writeBytes(os);
} catch (DataFormatException dfe) {
throw new I2NPMessageException("Error writing out the message data", dfe);
}
*/
return os.toByteArray();
}
private boolean flagsIncludeDummy(long flags) {
return (0 != (flags & FLAG_DUMMY));
return (0 != (flags & FLAG_DUMMY));
}
private boolean flagsReorder(long flags) {
return (0 != (flags & FLAG_REORDER));
return (0 != (flags & FLAG_REORDER));
}
private long getFlags() {
long val = 0L;
if (getIncludeDummyTraffic())
val = val | FLAG_DUMMY;
if (getReorderMessages())
val = val | FLAG_REORDER;
return val;
long val = 0L;
if (getIncludeDummyTraffic())
val = val | FLAG_DUMMY;
if (getReorderMessages())
val = val | FLAG_REORDER;
return val;
}
public int getType() { return MESSAGE_TYPE; }
public int hashCode() {
return (int)(DataHelper.hashCode(getCertificate()) +
DataHelper.hashCode(getConfigurationKey()) +
DataHelper.hashCode(getNextRouter()) +
DataHelper.hashCode(getReplyBlock()) +
DataHelper.hashCode(getTunnelId()) +
DataHelper.hashCode(getTunnelKey()) +
DataHelper.hashCode(getVerificationPrivateKey()) +
DataHelper.hashCode(getVerificationPublicKey()) +
(getIncludeDummyTraffic() ? 1 : 0) +
getMaxAvgBytesPerMin() +
getMaxAvgMessagesPerMin() +
getMaxPeakBytesPerMin() +
getMaxPeakMessagesPerMin() +
getParticipantType() +
(getReorderMessages() ? 1 : 0) +
getTunnelDurationSeconds());
return (int)(DataHelper.hashCode(getCertificate()) +
DataHelper.hashCode(getConfigurationKey()) +
DataHelper.hashCode(getNextRouter()) +
DataHelper.hashCode(getReplyBlock()) +
DataHelper.hashCode(getTunnelId()) +
DataHelper.hashCode(getTunnelKey()) +
DataHelper.hashCode(getVerificationPrivateKey()) +
DataHelper.hashCode(getVerificationPublicKey()) +
(getIncludeDummyTraffic() ? 1 : 0) +
getMaxAvgBytesPerMin() +
getMaxAvgMessagesPerMin() +
getMaxPeakBytesPerMin() +
getMaxPeakMessagesPerMin() +
getParticipantType() +
(getReorderMessages() ? 1 : 0) +
getTunnelDurationSeconds());
}
public boolean equals(Object object) {
if ( (object != null) && (object instanceof TunnelCreateMessage) ) {
TunnelCreateMessage msg = (TunnelCreateMessage)object;
return DataHelper.eq(getCertificate(), msg.getCertificate()) &&
DataHelper.eq(getConfigurationKey(), msg.getConfigurationKey()) &&
DataHelper.eq(getNextRouter(), msg.getNextRouter()) &&
DataHelper.eq(getReplyBlock(), msg.getReplyBlock()) &&
DataHelper.eq(getTunnelId(), msg.getTunnelId()) &&
DataHelper.eq(getTunnelKey(), msg.getTunnelKey()) &&
DataHelper.eq(getVerificationPrivateKey(), msg.getVerificationPrivateKey()) &&
DataHelper.eq(getVerificationPublicKey(), msg.getVerificationPublicKey()) &&
(getIncludeDummyTraffic() == msg.getIncludeDummyTraffic()) &&
(getMaxAvgBytesPerMin() == msg.getMaxAvgBytesPerMin()) &&
(getMaxAvgMessagesPerMin() == msg.getMaxAvgMessagesPerMin()) &&
(getMaxPeakBytesPerMin() == msg.getMaxPeakBytesPerMin()) &&
(getMaxPeakMessagesPerMin() == msg.getMaxPeakMessagesPerMin()) &&
(getParticipantType() == msg.getParticipantType()) &&
(getReorderMessages() == msg.getReorderMessages()) &&
(getTunnelDurationSeconds() == msg.getTunnelDurationSeconds());
return DataHelper.eq(getCertificate(), msg.getCertificate()) &&
DataHelper.eq(getConfigurationKey(), msg.getConfigurationKey()) &&
DataHelper.eq(getNextRouter(), msg.getNextRouter()) &&
DataHelper.eq(getReplyBlock(), msg.getReplyBlock()) &&
DataHelper.eq(getTunnelId(), msg.getTunnelId()) &&
DataHelper.eq(getTunnelKey(), msg.getTunnelKey()) &&
DataHelper.eq(getVerificationPrivateKey(), msg.getVerificationPrivateKey()) &&
DataHelper.eq(getVerificationPublicKey(), msg.getVerificationPublicKey()) &&
(getIncludeDummyTraffic() == msg.getIncludeDummyTraffic()) &&
(getMaxAvgBytesPerMin() == msg.getMaxAvgBytesPerMin()) &&
(getMaxAvgMessagesPerMin() == msg.getMaxAvgMessagesPerMin()) &&
(getMaxPeakBytesPerMin() == msg.getMaxPeakBytesPerMin()) &&
(getMaxPeakMessagesPerMin() == msg.getMaxPeakMessagesPerMin()) &&
(getParticipantType() == msg.getParticipantType()) &&
(getReorderMessages() == msg.getReorderMessages()) &&
(getTunnelDurationSeconds() == msg.getTunnelDurationSeconds());
} else {
return false;
}
}
public String toString() {
public String toString() {
StringBuffer buf = new StringBuffer();
buf.append("[TunnelCreateMessage: ");
buf.append("\n\tParticipant Type: ").append(getParticipantType());

View File

@@ -1,9 +1,9 @@
package net.i2p.data.i2np;
/*
* free (adj.): unencumbered; not under the control of others
* Written by jrandom in 2003 and released into the public domain
* with no warranty of any kind, either expressed or implied.
* It probably won't make your computer catch on fire, or eat
* Written by jrandom in 2003 and released into the public domain
* with no warranty of any kind, either expressed or implied.
* It probably won't make your computer catch on fire, or eat
* your children, but it might. Use at your own risk.
*
*/
@@ -17,9 +17,10 @@ import net.i2p.data.DataHelper;
import net.i2p.data.Hash;
import net.i2p.data.TunnelId;
import net.i2p.util.Log;
import net.i2p.I2PAppContext;
/**
* Defines the message a router sends to another router in reply to a
* Defines the message a router sends to another router in reply to a
* TunnelCreateMessage
*
* @author jrandom
@@ -37,10 +38,11 @@ public class TunnelCreateStatusMessage extends I2NPMessageImpl {
public final static int STATUS_FAILED_CERTIFICATE = 3;
public final static int STATUS_FAILED_DELETED = 100;
public TunnelCreateStatusMessage() {
setTunnelId(null);
setStatus(-1);
setFromHash(null);
public TunnelCreateStatusMessage(I2PAppContext context) {
super(context);
setTunnelId(null);
setStatus(-1);
setFromHash(null);
}
public TunnelId getTunnelId() { return _tunnelId; }
@@ -56,26 +58,26 @@ public class TunnelCreateStatusMessage extends I2NPMessageImpl {
public void setFromHash(Hash from) { _from = from; }
public void readMessage(InputStream in, int type) throws I2NPMessageException, IOException {
if (type != MESSAGE_TYPE) throw new I2NPMessageException("Message type is incorrect for this message");
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);
_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);
}
}
protected byte[] writeMessage() throws I2NPMessageException, IOException {
if ( (_tunnelId == null) || (_from == null) ) throw new I2NPMessageException("Not enough data to write out");
if ( (_tunnelId == null) || (_from == null) ) throw new I2NPMessageException("Not enough data to write out");
ByteArrayOutputStream os = new ByteArrayOutputStream(32);
try {
_tunnelId.writeBytes(os);
DataHelper.writeLong(os, 1, (_status < 0 ? 255 : _status));
_from.writeBytes(os);
_tunnelId.writeBytes(os);
DataHelper.writeLong(os, 1, (_status < 0 ? 255 : _status));
_from.writeBytes(os);
} catch (DataFormatException dfe) {
throw new I2NPMessageException("Error writing out the message data", dfe);
}
@@ -85,23 +87,23 @@ public class TunnelCreateStatusMessage extends I2NPMessageImpl {
public int getType() { return MESSAGE_TYPE; }
public int hashCode() {
return DataHelper.hashCode(getTunnelId()) +
getStatus() +
DataHelper.hashCode(getFromHash());
return DataHelper.hashCode(getTunnelId()) +
getStatus() +
DataHelper.hashCode(getFromHash());
}
public boolean equals(Object object) {
if ( (object != null) && (object instanceof TunnelCreateStatusMessage) ) {
TunnelCreateStatusMessage msg = (TunnelCreateStatusMessage)object;
return DataHelper.eq(getTunnelId(),msg.getTunnelId()) &&
DataHelper.eq(getFromHash(),msg.getFromHash()) &&
(getStatus() == msg.getStatus());
DataHelper.eq(getFromHash(),msg.getFromHash()) &&
(getStatus() == msg.getStatus());
} else {
return false;
}
}
public String toString() {
public String toString() {
StringBuffer buf = new StringBuffer();
buf.append("[TunnelCreateStatusMessage: ");
buf.append("\n\tTunnel ID: ").append(getTunnelId());

View File

@@ -1,9 +1,9 @@
package net.i2p.data.i2np;
/*
* free (adj.): unencumbered; not under the control of others
* Written by jrandom in 2003 and released into the public domain
* with no warranty of any kind, either expressed or implied.
* It probably won't make your computer catch on fire, or eat
* Written by jrandom in 2003 and released into the public domain
* with no warranty of any kind, either expressed or implied.
* It probably won't make your computer catch on fire, or eat
* your children, but it might. Use at your own risk.
*
*/
@@ -16,6 +16,7 @@ import net.i2p.data.DataFormatException;
import net.i2p.data.DataHelper;
import net.i2p.data.TunnelId;
import net.i2p.util.Log;
import net.i2p.I2PAppContext;
/**
* Defines the message sent between routers for tunnel delivery
@@ -34,11 +35,12 @@ public class TunnelMessage extends I2NPMessageImpl {
private final static int FLAG_INCLUDESTRUCTURE = 0;
private final static int FLAG_DONT_INCLUDESTRUCTURE = 1;
public TunnelMessage() {
setTunnelId(null);
setData(null);
setVerificationStructure(null);
setEncryptedDeliveryInstructions(null);
public TunnelMessage(I2PAppContext context) {
super(context);
setTunnelId(null);
setData(null);
setVerificationStructure(null);
setEncryptedDeliveryInstructions(null);
}
public TunnelId getTunnelId() { return _tunnelId; }
@@ -54,85 +56,85 @@ public class TunnelMessage extends I2NPMessageImpl {
public void setEncryptedDeliveryInstructions(byte instructions[]) { _encryptedInstructions = instructions; }
public void readMessage(InputStream in, int type) throws I2NPMessageException, IOException {
if (type != MESSAGE_TYPE) throw new I2NPMessageException("Message type is incorrect for this message");
if (type != MESSAGE_TYPE) throw new I2NPMessageException("Message type is incorrect for this message");
try {
_tunnelId = new TunnelId();
_tunnelId.readBytes(in);
_log.debug("Read tunnel message for tunnel " + _tunnelId);
_size = DataHelper.readLong(in, 4);
_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 + ")");
}
_tunnelId = new TunnelId();
_tunnelId.readBytes(in);
_log.debug("Read tunnel message for tunnel " + _tunnelId);
_size = DataHelper.readLong(in, 4);
_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);
}
}
protected byte[] writeMessage() throws I2NPMessageException, IOException {
if ( (_tunnelId == null) || (_data == null) || (_data.length <= 0) )
throw new I2NPMessageException("Not enough data to write out");
if ( (_tunnelId == null) || (_data == null) || (_data.length <= 0) )
throw new I2NPMessageException("Not enough data to write out");
ByteArrayOutputStream os = new ByteArrayOutputStream(32);
try {
_tunnelId.writeBytes(os);
_log.debug("Writing tunnel message for tunnel " + _tunnelId);
DataHelper.writeLong(os, 4, _data.length);
_log.debug("Writing tunnel message length: " + _data.length);
os.write(_data);
_log.debug("Writing tunnel message data");
if ( (_verification == null) || (_encryptedInstructions == null) ) {
DataHelper.writeLong(os, 1, FLAG_DONT_INCLUDESTRUCTURE);
_log.debug("Writing DontIncludeStructure flag");
} else {
DataHelper.writeLong(os, 1, FLAG_INCLUDESTRUCTURE);
_log.debug("Writing IncludeStructure flag, then the verification structure, then the E(instr).length [" + _encryptedInstructions.length + "], then the E(instr)");
_verification.writeBytes(os);
DataHelper.writeLong(os, 2, _encryptedInstructions.length);
os.write(_encryptedInstructions);
}
_tunnelId.writeBytes(os);
_log.debug("Writing tunnel message for tunnel " + _tunnelId);
DataHelper.writeLong(os, 4, _data.length);
_log.debug("Writing tunnel message length: " + _data.length);
os.write(_data);
_log.debug("Writing tunnel message data");
if ( (_verification == null) || (_encryptedInstructions == null) ) {
DataHelper.writeLong(os, 1, FLAG_DONT_INCLUDESTRUCTURE);
_log.debug("Writing DontIncludeStructure flag");
} else {
DataHelper.writeLong(os, 1, FLAG_INCLUDESTRUCTURE);
_log.debug("Writing IncludeStructure flag, then the verification structure, then the E(instr).length [" + _encryptedInstructions.length + "], then the E(instr)");
_verification.writeBytes(os);
DataHelper.writeLong(os, 2, _encryptedInstructions.length);
os.write(_encryptedInstructions);
}
} catch (DataFormatException dfe) {
throw new I2NPMessageException("Error writing out the message data", dfe);
}
byte rv[] = os.toByteArray();
_log.debug("Overall data being written: " + rv.length);
byte rv[] = os.toByteArray();
_log.debug("Overall data being written: " + rv.length);
return rv;
}
public int getType() { return MESSAGE_TYPE; }
public int hashCode() {
return DataHelper.hashCode(getTunnelId()) +
DataHelper.hashCode(_data) +
DataHelper.hashCode(getVerificationStructure()) +
DataHelper.hashCode(getEncryptedDeliveryInstructions());
return DataHelper.hashCode(getTunnelId()) +
DataHelper.hashCode(_data) +
DataHelper.hashCode(getVerificationStructure()) +
DataHelper.hashCode(getEncryptedDeliveryInstructions());
}
public boolean equals(Object object) {
if ( (object != null) && (object instanceof TunnelMessage) ) {
TunnelMessage msg = (TunnelMessage)object;
return DataHelper.eq(getTunnelId(),msg.getTunnelId()) &&
DataHelper.eq(getVerificationStructure(),msg.getVerificationStructure()) &&
DataHelper.eq(getData(),msg.getData()) &&
DataHelper.eq(getEncryptedDeliveryInstructions(), msg.getEncryptedDeliveryInstructions());
DataHelper.eq(getVerificationStructure(),msg.getVerificationStructure()) &&
DataHelper.eq(getData(),msg.getData()) &&
DataHelper.eq(getEncryptedDeliveryInstructions(), msg.getEncryptedDeliveryInstructions());
} else {
return false;
}
}
public String toString() {
public String toString() {
StringBuffer buf = new StringBuffer();
buf.append("[TunnelMessage: ");
buf.append("\n\tTunnel ID: ").append(getTunnelId());

View File

@@ -1,9 +1,9 @@
package net.i2p.data.i2np;
/*
* free (adj.): unencumbered; not under the control of others
* Written by jrandom in 2003 and released into the public domain
* with no warranty of any kind, either expressed or implied.
* It probably won't make your computer catch on fire, or eat
* Written by jrandom in 2003 and released into the public domain
* with no warranty of any kind, either expressed or implied.
* It probably won't make your computer catch on fire, or eat
* your children, but it might. Use at your own risk.
*
*/
@@ -21,19 +21,19 @@ import net.i2p.data.Signature;
import net.i2p.data.SigningPrivateKey;
import net.i2p.data.SigningPublicKey;
import net.i2p.util.Log;
import net.i2p.router.RouterContext;
/**
*
* @author jrandom
*/
public class TunnelVerificationStructure extends DataStructureImpl {
private final static Log _log = new Log(TunnelVerificationStructure.class);
private Hash _msgHash;
private Signature _authSignature;
public TunnelVerificationStructure() {
setMessageHash(null);
setAuthorizationSignature(null);
public TunnelVerificationStructure() {
setMessageHash(null);
setAuthorizationSignature(null);
}
public Hash getMessageHash() { return _msgHash; }
@@ -42,45 +42,45 @@ public class TunnelVerificationStructure extends DataStructureImpl {
public Signature getAuthorizationSignature() { return _authSignature; }
public void setAuthorizationSignature(Signature sig) { _authSignature = sig; }
public void sign(SigningPrivateKey key) {
if (_msgHash != null) {
Signature sig = DSAEngine.getInstance().sign(_msgHash.getData(), key);
setAuthorizationSignature(sig);
}
public void sign(RouterContext context, SigningPrivateKey key) {
if (_msgHash != null) {
Signature sig = context.dsa().sign(_msgHash.getData(), key);
setAuthorizationSignature(sig);
}
}
public boolean verifySignature(SigningPublicKey key) {
if (_msgHash == null) return false;
return DSAEngine.getInstance().verifySignature(_authSignature, _msgHash.getData(), key);
public boolean verifySignature(RouterContext context, SigningPublicKey key) {
if (_msgHash == null) return false;
return context.dsa().verifySignature(_authSignature, _msgHash.getData(), key);
}
public void readBytes(InputStream in) throws DataFormatException, IOException {
_msgHash = new Hash();
_msgHash.readBytes(in);
_authSignature = new Signature();
_authSignature.readBytes(in);
_msgHash = new Hash();
_msgHash.readBytes(in);
_authSignature = new Signature();
_authSignature.readBytes(in);
}
public void writeBytes(OutputStream out) throws DataFormatException, IOException {
if (_authSignature == null) {
_authSignature = new Signature();
_authSignature.setData(Signature.FAKE_SIGNATURE);
}
if (_authSignature == null) {
_authSignature = new Signature();
_authSignature.setData(Signature.FAKE_SIGNATURE);
}
if ( (_msgHash == null) || (_authSignature == null) ) throw new DataFormatException("Invalid data");
_msgHash.writeBytes(out);
_authSignature.writeBytes(out);
_msgHash.writeBytes(out);
_authSignature.writeBytes(out);
}
public boolean equals(Object obj) {
if ( (obj == null) || !(obj instanceof TunnelVerificationStructure))
return false;
TunnelVerificationStructure str = (TunnelVerificationStructure)obj;
return DataHelper.eq(getMessageHash(), str.getMessageHash()) &&
DataHelper.eq(getAuthorizationSignature(), str.getAuthorizationSignature());
TunnelVerificationStructure str = (TunnelVerificationStructure)obj;
return DataHelper.eq(getMessageHash(), str.getMessageHash()) &&
DataHelper.eq(getAuthorizationSignature(), str.getAuthorizationSignature());
}
public int hashCode() {
if ( (_msgHash == null) || (_authSignature == null) ) return 0;
return getMessageHash().hashCode() + getAuthorizationSignature().hashCode();
if ( (_msgHash == null) || (_authSignature == null) ) return 0;
return getMessageHash().hashCode() + getAuthorizationSignature().hashCode();
}
public String toString() {