forked from I2P_Developers/i2p.i2p
SSU: Prep for extended options
This commit is contained in:
@@ -783,10 +783,13 @@ class PacketBuilder {
|
||||
* @return ready to send packet, or null if there was a problem
|
||||
*/
|
||||
public UDPPacket buildSessionRequestPacket(OutboundEstablishState state) {
|
||||
// TODO
|
||||
//byte[] options = new byte[3];
|
||||
//UDPPacket packet = buildPacketHeader(SESSION_REQUEST_FLAG_BYTE, options);
|
||||
UDPPacket packet = buildPacketHeader(SESSION_REQUEST_FLAG_BYTE);
|
||||
DatagramPacket pkt = packet.getPacket();
|
||||
byte data[] = pkt.getData();
|
||||
int off = HEADER_SIZE;
|
||||
int off = HEADER_SIZE; // + 1 + options.length;
|
||||
|
||||
byte toIP[] = state.getSentIP();
|
||||
if (!_transport.isValid(toIP)) {
|
||||
@@ -1433,24 +1436,49 @@ class PacketBuilder {
|
||||
/**
|
||||
* Create a new packet and add the flag byte and the time stamp.
|
||||
* Caller should add data starting at HEADER_SIZE.
|
||||
* At this point, adding support for extended options and rekeying is unlikely,
|
||||
* but if we do, we'll have to change this.
|
||||
* Does not include extended options or rekeying.
|
||||
*
|
||||
* @param flagByte contains type and flags
|
||||
* @since 0.8.1
|
||||
*/
|
||||
private UDPPacket buildPacketHeader(byte flagByte) {
|
||||
return buildPacketHeader(flagByte, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new packet and add the flag byte and the time stamp.
|
||||
* Caller should add data starting at HEADER_SIZE.
|
||||
* (if extendedOptions != null, at HEADER_SIZE + 1 + extendedOptions.length)
|
||||
* Does not include rekeying.
|
||||
*
|
||||
* @param flagByte contains type and flags
|
||||
* @param extendedOptions May be null. If non-null, we will add the associated flag here.
|
||||
* 255 bytes max.
|
||||
* @since 0.9.24
|
||||
*/
|
||||
private UDPPacket buildPacketHeader(byte flagByte, byte[] extendedOptions) {
|
||||
UDPPacket packet = UDPPacket.acquire(_context, false);
|
||||
byte data[] = packet.getPacket().getData();
|
||||
Arrays.fill(data, 0, data.length, (byte)0x0);
|
||||
int off = UDPPacket.MAC_SIZE + UDPPacket.IV_SIZE;
|
||||
|
||||
// header
|
||||
if (extendedOptions != null)
|
||||
flagByte |= UDPPacket.HEADER_FLAG_EXTENDED_OPTIONS;
|
||||
data[off] = flagByte;
|
||||
off++;
|
||||
long now = (_context.clock().now() + 500) / 1000;
|
||||
DataHelper.toLong(data, off, 4, now);
|
||||
// todo: add support for rekeying and extended options
|
||||
// todo: add support for rekeying
|
||||
// extended options
|
||||
if (extendedOptions != null) {
|
||||
off+= 4;
|
||||
int len = extendedOptions.length;
|
||||
if (len > 255)
|
||||
throw new IllegalArgumentException();
|
||||
data[off++] = (byte) len;
|
||||
System.arraycopy(extendedOptions, 0, data, off, len);
|
||||
}
|
||||
return packet;
|
||||
}
|
||||
|
||||
|
@@ -89,14 +89,26 @@ class UDPPacket implements CDQEntry {
|
||||
/** @since 0.8.1 */
|
||||
public static final int PAYLOAD_TYPE_SESSION_DESTROY = 8;
|
||||
|
||||
// various flag fields for use in the header
|
||||
/**
|
||||
* Defined in the spec from the beginning, Unused
|
||||
* @since 0.9.24
|
||||
*/
|
||||
public static final byte HEADER_FLAG_REKEY = (1 << 3);
|
||||
/**
|
||||
* Defined in the spec from the beginning, Used starting in 0.9.24
|
||||
* @since 0.9.24
|
||||
*/
|
||||
public static final byte HEADER_FLAG_EXTENDED_OPTIONS = (1 << 2);
|
||||
|
||||
// various flag fields for use in the data packets
|
||||
public static final byte DATA_FLAG_EXPLICIT_ACK = (byte)(1 << 7);
|
||||
public static final byte DATA_FLAG_ACK_BITFIELDS = (1 << 6);
|
||||
// unused
|
||||
/** unused */
|
||||
public static final byte DATA_FLAG_ECN = (1 << 4);
|
||||
public static final byte DATA_FLAG_WANT_ACKS = (1 << 3);
|
||||
public static final byte DATA_FLAG_WANT_REPLY = (1 << 2);
|
||||
// unused
|
||||
/** unused */
|
||||
public static final byte DATA_FLAG_EXTENDED = (1 << 1);
|
||||
|
||||
public static final byte BITFIELD_CONTINUATION = (byte)(1 << 7);
|
||||
|
@@ -67,13 +67,19 @@ class UDPPacketReader {
|
||||
return (_message[_payloadBeginOffset] & 0xFF) >>> 4;
|
||||
}
|
||||
|
||||
/** does this packet include rekeying data? */
|
||||
public boolean readRekeying() {
|
||||
return (_message[_payloadBeginOffset] & (1 << 3)) != 0;
|
||||
/**
|
||||
* Does this packet include rekeying data in the header?
|
||||
* Unused, should always be false.
|
||||
*/
|
||||
public boolean isRekeyingIncluded() {
|
||||
return (_message[_payloadBeginOffset] & UDPPacket.HEADER_FLAG_REKEY) != 0;
|
||||
}
|
||||
|
||||
public boolean readExtendedOptionsIncluded() {
|
||||
return (_message[_payloadBeginOffset] & (1 << 2)) != 0;
|
||||
/**
|
||||
* Does this packet include extended options in the header?
|
||||
*/
|
||||
public boolean isExtendedOptionsIncluded() {
|
||||
return (_message[_payloadBeginOffset] & UDPPacket.HEADER_FLAG_EXTENDED_OPTIONS) != 0;
|
||||
}
|
||||
|
||||
/** @return seconds */
|
||||
@@ -81,19 +87,46 @@ class UDPPacketReader {
|
||||
return DataHelper.fromLong(_message, _payloadBeginOffset + 1, 4);
|
||||
}
|
||||
|
||||
public void readKeyingMaterial(byte target[], int targetOffset) {
|
||||
if (!readRekeying())
|
||||
throw new IllegalStateException("This packet is not rekeying!");
|
||||
System.arraycopy(_message, _payloadBeginOffset + 1 + 4, target, targetOffset, KEYING_MATERIAL_LENGTH);
|
||||
/**
|
||||
* Returns rekeying data (64 bytes), or null if none.
|
||||
* Unused, should always return null.
|
||||
*
|
||||
* @deprecated unused
|
||||
*/
|
||||
@Deprecated
|
||||
public byte[] readKeyingMaterial() {
|
||||
if (!isRekeyingIncluded())
|
||||
return null;
|
||||
byte[] rv = new byte[KEYING_MATERIAL_LENGTH];
|
||||
System.arraycopy(_message, _payloadBeginOffset + 1 + 4, rv, 0, KEYING_MATERIAL_LENGTH);
|
||||
return rv;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns extended option data, 0-255 bytes, or null if none.
|
||||
*
|
||||
* @return extended options or null if none is included
|
||||
* @since 0.9.24
|
||||
*/
|
||||
public byte[] readExtendedOptions() {
|
||||
if (!isExtendedOptionsIncluded())
|
||||
return null;
|
||||
int offset = _payloadBeginOffset + 1 + 4;
|
||||
if (isRekeyingIncluded())
|
||||
offset += KEYING_MATERIAL_LENGTH;
|
||||
int optionsSize = _message[offset++] & 0xff;
|
||||
byte[] rv = new byte[optionsSize];
|
||||
System.arraycopy(_message, offset, rv, 0, optionsSize);
|
||||
return rv;
|
||||
}
|
||||
|
||||
/** index into the message where the body begins */
|
||||
private int readBodyOffset() {
|
||||
int offset = _payloadBeginOffset + 1 + 4;
|
||||
if (readRekeying())
|
||||
if (isRekeyingIncluded())
|
||||
offset += KEYING_MATERIAL_LENGTH;
|
||||
if (readExtendedOptionsIncluded()) {
|
||||
int optionsSize = (int)DataHelper.fromLong(_message, offset, 1);
|
||||
if (isExtendedOptionsIncluded()) {
|
||||
int optionsSize = _message[offset] & 0xff;
|
||||
offset += optionsSize + 1;
|
||||
}
|
||||
return offset;
|
||||
|
Reference in New Issue
Block a user