SSU: Prep for extended options

This commit is contained in:
zzz
2015-11-08 18:30:51 +00:00
parent bdde11c0ef
commit a3e16614ae
3 changed files with 91 additions and 18 deletions

View File

@@ -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;
}

View File

@@ -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);

View File

@@ -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;