0.5 merging

This commit is contained in:
jrandom
2005-02-16 22:37:24 +00:00
committed by zzz
parent 9646ac2911
commit 7ef9ce8cc6
16 changed files with 1139 additions and 1213 deletions

View File

@ -0,0 +1,80 @@
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 java.util.Date;
import net.i2p.I2PAppContext;
import net.i2p.data.DataFormatException;
import net.i2p.data.DataHelper;
import net.i2p.util.Log;
/**
* Contains the sending router's current time, to sync (and verify sync)
*
*/
public class DateMessage extends I2NPMessageImpl {
private final static Log _log = new Log(DateMessage.class);
public final static int MESSAGE_TYPE = 16;
private long _now;
public DateMessage(I2PAppContext context) {
super(context);
_now = context.clock().now();
}
public long getNow() { return _now; }
public void setNow(long now) { _now = now; }
public void readMessage(byte data[], int offset, int dataSize, int type) throws I2NPMessageException, IOException {
if (type != MESSAGE_TYPE) throw new I2NPMessageException("Message type is incorrect for this message");
int curIndex = offset;
_now = DataHelper.fromLong(data, curIndex, DataHelper.DATE_LENGTH);
}
/** calculate the message body's length (not including the header and footer */
protected int calculateWrittenLength() {
return DataHelper.DATE_LENGTH; // now
}
/** write the message body to the output array, starting at the given index */
protected int writeMessageBody(byte out[], int curIndex) throws I2NPMessageException {
if (_now <= 0) throw new I2NPMessageException("Not enough data to write out");
DataHelper.toLong(out, curIndex, DataHelper.DATE_LENGTH, _now);
curIndex += DataHelper.DATE_LENGTH;
return curIndex;
}
public int getType() { return MESSAGE_TYPE; }
public int hashCode() {
return (int)getNow();
}
public boolean equals(Object object) {
if ( (object != null) && (object instanceof DateMessage) ) {
DateMessage msg = (DateMessage)object;
return msg.getNow() == getNow();
} else {
return false;
}
}
public String toString() {
StringBuffer buf = new StringBuffer();
buf.append("[DateMessage: ");
buf.append("Now: ").append(_now);
buf.append("]");
return buf.toString();
}
}

View File

@ -1,61 +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.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import net.i2p.data.DataFormatException;
import net.i2p.data.DataHelper;
import net.i2p.data.DataStructureImpl;
import net.i2p.data.SessionKey;
import net.i2p.util.Log;
/**
* Contains the session key used by the owner/creator of the tunnel to modify
* its operational settings.
*
* @author jrandom
*/
public class TunnelConfigurationSessionKey extends DataStructureImpl {
private final static Log _log = new Log(TunnelConfigurationSessionKey.class);
private SessionKey _key;
public TunnelConfigurationSessionKey() { this(null); }
public TunnelConfigurationSessionKey(SessionKey key) { setKey(key); }
public SessionKey getKey() { return _key; }
public void setKey(SessionKey key) { _key= key; }
public void readBytes(InputStream in) throws DataFormatException, IOException {
_key = new SessionKey();
_key.readBytes(in);
}
public void writeBytes(OutputStream out) throws DataFormatException, IOException {
if (_key == null) throw new DataFormatException("Invalid key");
_key.writeBytes(out);
}
public boolean equals(Object obj) {
if ( (obj == null) || !(obj instanceof TunnelConfigurationSessionKey))
return false;
return DataHelper.eq(getKey(), ((TunnelConfigurationSessionKey)obj).getKey());
}
public int hashCode() {
if (_key == null) return 0;
return getKey().hashCode();
}
public String toString() {
return "[TunnelConfigurationSessionKey: " + getKey() + "]";
}
}

View File

@ -0,0 +1,139 @@
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 java.io.OutputStream;
import net.i2p.I2PAppContext;
import net.i2p.data.Base64;
import net.i2p.data.ByteArray;
import net.i2p.data.DataFormatException;
import net.i2p.data.DataHelper;
import net.i2p.data.Hash;
import net.i2p.data.Signature;
import net.i2p.data.TunnelId;
import net.i2p.util.ByteCache;
import net.i2p.util.Log;
/**
* Defines the message sent between routers as part of the tunnel delivery
*
*/
public class TunnelDataMessage extends I2NPMessageImpl {
private Log _log;
private TunnelId _tunnelId;
private byte[] _data;
public final static int MESSAGE_TYPE = 18;
private static final int DATA_SIZE = 1024;
/** if we can't deliver a tunnel message in 10s, fuck it */
private static final int EXPIRATION_PERIOD = 10*1000;
private static final ByteCache _cache = ByteCache.getInstance(512, DATA_SIZE);
/**
* When true, it means this tunnelDataMessage is being used as part of a tunnel
* processing pipeline, where the byte array is acquired during the TunnelDataMessage's
* creation (per readMessage), held onto through several transitions (updating and
* moving that array between different TunnelDataMessage instances or the fragment
* handler's cache, etc), until it is finally released back into the cache when written
* to the next peer (or explicitly by the fragment handler's completion).
* Setting this to false just increases memory churn
*/
private static final boolean PIPELINED_CACHE = true;
public TunnelDataMessage(I2PAppContext context) {
super(context);
_log = context.logManager().getLog(TunnelDataMessage.class);
setMessageExpiration(context.clock().now() + EXPIRATION_PERIOD);
}
public TunnelId getTunnelId() { return _tunnelId; }
public void setTunnelId(TunnelId id) { _tunnelId = id; }
public byte[] getData() { return _data; }
public void setData(byte data[]) {
if ( (data == null) || (data.length <= 0) )
throw new IllegalArgumentException("Empty tunnel payload?");
_data = data;
}
public void readMessage(byte data[], int offset, int dataSize, int type) throws I2NPMessageException, IOException {
if (type != MESSAGE_TYPE) throw new I2NPMessageException("Message type is incorrect for this message");
int curIndex = offset;
_tunnelId = new TunnelId(DataHelper.fromLong(data, curIndex, 4));
curIndex += 4;
if (_tunnelId.getTunnelId() <= 0)
throw new I2NPMessageException("Invalid tunnel Id " + _tunnelId);
// we cant cache it in trivial form, as other components (e.g. HopProcessor)
// call getData() and use it as the buffer to write with. it is then used
// again to pass to the 'receiver', which may even cache it in a FragmentMessage.
if (PIPELINED_CACHE)
_data = _cache.acquire().getData();
else
_data = new byte[DATA_SIZE];
System.arraycopy(data, curIndex, _data, 0, DATA_SIZE);
}
/** calculate the message body's length (not including the header and footer */
protected int calculateWrittenLength() { return 4 + DATA_SIZE; }
/** write the message body to the output array, starting at the given index */
protected int writeMessageBody(byte out[], int curIndex) throws I2NPMessageException {
if ( (_tunnelId == null) || (_data == null) )
throw new I2NPMessageException("Not enough data to write out (id=" + _tunnelId + " data=" + _data + ")");
if (_data.length <= 0)
throw new I2NPMessageException("Not enough data to write out (data.length=" + _data.length + ")");
DataHelper.toLong(out, curIndex, 4, _tunnelId.getTunnelId());
curIndex += 4;
System.arraycopy(_data, 0, out, curIndex, DATA_SIZE);
curIndex += _data.length;
if (PIPELINED_CACHE)
_cache.release(new ByteArray(_data));
return curIndex;
}
public int getType() { return MESSAGE_TYPE; }
public int hashCode() {
return DataHelper.hashCode(getTunnelId()) +
DataHelper.hashCode(_data);
}
public boolean equals(Object object) {
if ( (object != null) && (object instanceof TunnelDataMessage) ) {
TunnelDataMessage msg = (TunnelDataMessage)object;
return DataHelper.eq(getTunnelId(),msg.getTunnelId()) &&
DataHelper.eq(getData(),msg.getData());
} else {
return false;
}
}
public byte[] toByteArray() {
byte rv[] = super.toByteArray();
if (rv == null)
throw new RuntimeException("unable to toByteArray(): " + toString());
return rv;
}
public String toString() {
StringBuffer buf = new StringBuffer();
buf.append("[TunnelDataMessage:");
buf.append(" MessageId: ").append(getUniqueId());
buf.append(" Tunnel ID: ").append(getTunnelId());
buf.append("]");
return buf.toString();
}
}

View File

@ -0,0 +1,137 @@
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 java.io.OutputStream;
import java.util.Date;
import net.i2p.I2PAppContext;
import net.i2p.data.Base64;
import net.i2p.data.DataFormatException;
import net.i2p.data.DataHelper;
import net.i2p.data.Hash;
import net.i2p.data.Signature;
import net.i2p.data.TunnelId;
import net.i2p.util.Log;
/**
* Defines the message sent between one tunnel's endpoint and another's gateway.
* format: { tunnelId, sizeof(i2npMessage.toByteArray()), i2npMessage.toByteArray() }
*
*/
public class TunnelGatewayMessage extends I2NPMessageImpl {
private Log _log;
private TunnelId _tunnelId;
private I2NPMessage _msg;
private byte _msgData[];
private Exception _creator;
public final static int MESSAGE_TYPE = 19;
/** if we can't deliver a tunnel message in 10s, fuck it */
private static final int EXPIRATION_PERIOD = 10*1000;
public TunnelGatewayMessage(I2PAppContext context) {
super(context);
_log = context.logManager().getLog(TunnelGatewayMessage.class);
setMessageExpiration(context.clock().now() + EXPIRATION_PERIOD);
//_creator = new Exception("i made this");
}
public TunnelId getTunnelId() { return _tunnelId; }
public void setTunnelId(TunnelId id) { _tunnelId = id; }
public I2NPMessage getMessage() { return _msg; }
public void setMessage(I2NPMessage msg) {
if (msg == null)
throw new IllegalArgumentException("wtf, dont set me to null");
_msg = msg;
}
protected int calculateWrittenLength() {
synchronized (this) {
if (_msgData == null) {
_msgData = _msg.toByteArray();
_msg = null;
}
}
return _msgData.length + 4 + 2;
}
/** write the message body to the output array, starting at the given index */
protected int writeMessageBody(byte out[], int curIndex) throws I2NPMessageException {
if ( (_tunnelId == null) || ( (_msg == null) && (_msgData == null) ) ) {
_log.log(Log.CRIT, "failing to write out gateway message, created by: ", _creator);
throw new I2NPMessageException("Not enough data to write out (id=" + _tunnelId + " data=" + _msg + ")");
}
DataHelper.toLong(out, curIndex, 4, _tunnelId.getTunnelId());
curIndex += 4;
synchronized (this) {
if (_msgData == null) {
_msgData = _msg.toByteArray();
_msg = null;
}
}
DataHelper.toLong(out, curIndex, 2, _msgData.length);
curIndex += 2;
System.arraycopy(_msgData, 0, out, curIndex, _msgData.length);
curIndex += _msgData.length;
return curIndex;
}
public void readMessage(byte data[], int offset, int dataSize, int type) throws I2NPMessageException, IOException {
if (type != MESSAGE_TYPE) throw new I2NPMessageException("Message type is incorrect for this message");
int curIndex = offset;
_tunnelId = new TunnelId(DataHelper.fromLong(data, curIndex, 4));
curIndex += 4;
if (_tunnelId.getTunnelId() <= 0)
throw new I2NPMessageException("Invalid tunnel Id " + _tunnelId);
int size = (int)DataHelper.fromLong(data, curIndex, 2);
curIndex += 2;
I2NPMessageHandler h = new I2NPMessageHandler(_context);
curIndex = h.readMessage(data, curIndex);
_msg = h.lastRead();
if (_msg == null)
throw new I2NPMessageException("wtf, message read has no payload?");
}
public int getType() { return MESSAGE_TYPE; }
public int hashCode() {
return DataHelper.hashCode(getTunnelId()) +
DataHelper.hashCode(_msg);
}
public boolean equals(Object object) {
if ( (object != null) && (object instanceof TunnelGatewayMessage) ) {
TunnelGatewayMessage msg = (TunnelGatewayMessage)object;
return DataHelper.eq(getTunnelId(),msg.getTunnelId()) &&
DataHelper.eq(_msgData, msg._msgData) &&
DataHelper.eq(getMessage(), msg.getMessage());
} else {
return false;
}
}
public String toString() {
StringBuffer buf = new StringBuffer();
buf.append("[TunnelGatewayMessage:");
buf.append(" Tunnel ID: ").append(getTunnelId());
buf.append(" Message: ").append(_msg);
buf.append("]");
return buf.toString();
}
}

View File

@ -1,188 +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.I2PAppContext;
import net.i2p.data.DataFormatException;
import net.i2p.data.DataHelper;
import net.i2p.data.Hash;
import net.i2p.data.Signature;
import net.i2p.data.TunnelId;
import net.i2p.util.Log;
/**
* Defines the message sent between routers for tunnel delivery
*
* @author jrandom
*/
public class TunnelMessage extends I2NPMessageImpl {
private final static Log _log = new Log(TunnelMessage.class);
public final static int MESSAGE_TYPE = 8;
private TunnelId _tunnelId;
private long _size;
private byte[] _data;
private TunnelVerificationStructure _verification;
private byte[] _encryptedInstructions;
private final static int FLAG_INCLUDESTRUCTURE = 0;
private final static int FLAG_DONT_INCLUDESTRUCTURE = 1;
public TunnelMessage(I2PAppContext context) {
super(context);
setTunnelId(null);
setData(null);
setVerificationStructure(null);
setEncryptedDeliveryInstructions(null);
}
public TunnelId getTunnelId() { return _tunnelId; }
public void setTunnelId(TunnelId id) {
_tunnelId = id;
}
public byte[] getData() { return _data; }
public void setData(byte data[]) {
_data = data;
if ( (data != null) && (_data.length <= 0) )
throw new IllegalArgumentException("Empty tunnel payload?");
}
public TunnelVerificationStructure getVerificationStructure() { return _verification; }
public void setVerificationStructure(TunnelVerificationStructure verification) { _verification = verification; }
public byte[] getEncryptedDeliveryInstructions() { return _encryptedInstructions; }
public void setEncryptedDeliveryInstructions(byte instructions[]) { _encryptedInstructions = instructions; }
public void readMessage(byte data[], int offset, int dataSize, int type) throws I2NPMessageException, IOException {
if (type != MESSAGE_TYPE) throw new I2NPMessageException("Message type is incorrect for this message");
int curIndex = offset;
_tunnelId = new TunnelId(DataHelper.fromLong(data, curIndex, 4));
curIndex += 4;
if (_tunnelId.getTunnelId() <= 0)
throw new I2NPMessageException("Invalid tunnel Id " + _tunnelId);
_size = DataHelper.fromLong(data, curIndex, 4);
curIndex += 4;
if (_size < 0) throw new I2NPMessageException("Invalid size in the structure: " + _size);
if (_size > 64*1024) throw new I2NPMessageException("Invalid size in the structure: " + _size);
_data = new byte[(int)_size];
System.arraycopy(data, curIndex, _data, 0, (int)_size);
curIndex += _size;
int includeVerification = (int)DataHelper.fromLong(data, curIndex, 1);
curIndex++;
if (includeVerification == FLAG_INCLUDESTRUCTURE) {
byte vHash[] = new byte[Hash.HASH_LENGTH];
System.arraycopy(data, curIndex, vHash, 0, Hash.HASH_LENGTH);
curIndex += Hash.HASH_LENGTH;
byte vSig[] = new byte[Signature.SIGNATURE_BYTES];
System.arraycopy(data, curIndex, vSig, 0, Signature.SIGNATURE_BYTES);
curIndex += Signature.SIGNATURE_BYTES;
_verification = new TunnelVerificationStructure(new Hash(vHash), new Signature(vSig));
int len = (int)DataHelper.fromLong(data, curIndex, 2);
curIndex += 2;
if ( (len <= 0) || (len > 4*1024) ) throw new I2NPMessageException("wtf, size of instructions: " + len);
_encryptedInstructions = new byte[len];
System.arraycopy(data, curIndex, _encryptedInstructions, 0, len);
curIndex += len;
}
}
/** calculate the message body's length (not including the header and footer */
protected int calculateWrittenLength() {
int length = 0;
length += 4; // tunnelId
length += 4; // data length
length += _data.length;
if ( (_verification == null) || (_encryptedInstructions == null) ) {
length += 1; // include verification?
} else {
length += 1; // include verification?
length += Hash.HASH_LENGTH + Signature.SIGNATURE_BYTES;
length += 2; // instructions length
length += _encryptedInstructions.length;
}
return length;
}
/** write the message body to the output array, starting at the given index */
protected int writeMessageBody(byte out[], int curIndex) throws I2NPMessageException {
if ( (_tunnelId == null) || (_data == null) )
throw new I2NPMessageException("Not enough data to write out (id=" + _tunnelId + " data=" + _data + ")");
if (_data.length <= 0)
throw new I2NPMessageException("Not enough data to write out (data.length=" + _data.length + ")");
byte id[] = DataHelper.toLong(4, _tunnelId.getTunnelId());
System.arraycopy(id, 0, out, curIndex, 4);
curIndex += 4;
byte len[] = DataHelper.toLong(4, _data.length);
System.arraycopy(len, 0, out, curIndex, 4);
curIndex += 4;
System.arraycopy(_data, 0, out, curIndex, _data.length);
curIndex += _data.length;
if ( (_verification == null) || (_encryptedInstructions == null) ) {
byte flag[] = DataHelper.toLong(1, FLAG_DONT_INCLUDESTRUCTURE);
out[curIndex++] = flag[0];
} else {
byte flag[] = DataHelper.toLong(1, FLAG_INCLUDESTRUCTURE);
out[curIndex++] = flag[0];
System.arraycopy(_verification.getMessageHash().getData(), 0, out, curIndex, Hash.HASH_LENGTH);
curIndex += Hash.HASH_LENGTH;
System.arraycopy(_verification.getAuthorizationSignature().getData(), 0, out, curIndex, Signature.SIGNATURE_BYTES);
curIndex += Signature.SIGNATURE_BYTES;
len = DataHelper.toLong(2, _encryptedInstructions.length);
System.arraycopy(len, 0, out, curIndex, 2);
curIndex += 2;
System.arraycopy(_encryptedInstructions, 0, out, curIndex, _encryptedInstructions.length);
curIndex += _encryptedInstructions.length;
}
return curIndex;
}
public int getType() { return MESSAGE_TYPE; }
public int hashCode() {
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());
} else {
return false;
}
}
public String toString() {
StringBuffer buf = new StringBuffer();
buf.append("[TunnelMessage: ");
buf.append("\n\tMessageId: ").append(getUniqueId());
buf.append("\n\tExpiration: ").append(getMessageExpiration());
buf.append("\n\tTunnel ID: ").append(getTunnelId());
buf.append("\n\tVerification Structure: ").append(getVerificationStructure());
buf.append("\n\tEncrypted Instructions: ").append(getEncryptedDeliveryInstructions());
buf.append("\n\tData size: ").append(getData().length);
buf.append("]");
return buf.toString();
}
}