forked from I2P_Developers/i2p.i2p
Merge branch 'master' of 127.0.0.1:i2p-hackers/i2p.i2p
This commit is contained in:
@@ -31,6 +31,7 @@ import java.util.Properties;
|
||||
import net.i2p.I2PAppContext;
|
||||
import net.i2p.app.*;
|
||||
import static net.i2p.app.ClientAppState.*;
|
||||
import net.i2p.servlet.filters.XI2PLocationFilter;
|
||||
import net.i2p.util.FileUtil;
|
||||
import net.i2p.util.I2PAppThread;
|
||||
import net.i2p.util.PortMapper;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package net.i2p.jetty;
|
||||
package net.i2p.servlet.filters;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.File;
|
||||
|
||||
@@ -84,7 +84,7 @@ public class BuildResponseRecord {
|
||||
* @param status the response 0-255
|
||||
* @param replyAD 32 bytes
|
||||
* @param options 116 bytes max when serialized
|
||||
* @return a 236-byte response record
|
||||
* @return a 218-byte response record
|
||||
* @throws IllegalArgumentException if options too big or on encryption failure
|
||||
* @since 0.9.51
|
||||
*/
|
||||
@@ -111,10 +111,10 @@ public class BuildResponseRecord {
|
||||
|
||||
/**
|
||||
* Encrypts in place.
|
||||
* Handles both standard (528) and short (236) byte records as of 0.9.51.
|
||||
* Handles both standard (528) and short (218) byte records as of 0.9.51.
|
||||
*
|
||||
* @param ad non-null
|
||||
* @param data 528 or 236 bytes, data will be encrypted in place.
|
||||
* @param data 528 or 218 bytes, data will be encrypted in place.
|
||||
* @return success
|
||||
* @since 0.9.48
|
||||
*/
|
||||
@@ -131,12 +131,12 @@ public class BuildResponseRecord {
|
||||
|
||||
/*
|
||||
* ChaCha/Poly only for ECIES routers.
|
||||
* Handles both standard (528) and short (236) byte records as of 0.9.51.
|
||||
* Handles both standard (528) and short (218) byte records as of 0.9.51.
|
||||
* Decrypts in place.
|
||||
* Status will be rec.getData()[511 or 219].
|
||||
* Properties will be at rec.getData()[0].
|
||||
*
|
||||
* @param rec 528 or 236 bytes, data will be decrypted in place.
|
||||
* @param rec 528 or 218 bytes, data will be decrypted in place.
|
||||
* @param ad non-null
|
||||
* @return success
|
||||
* @since 0.9.48
|
||||
|
||||
@@ -1,146 +0,0 @@
|
||||
package net.i2p.data.i2np;
|
||||
|
||||
import net.i2p.I2PAppContext;
|
||||
import net.i2p.data.DataHelper;
|
||||
|
||||
/**
|
||||
* Sent from the tunnel creator to the IBGW via an outbound tunnel.
|
||||
* Contains one plaintext variable-sized request record for the IBGW
|
||||
* and a variable number of encrypted records for the following hops.
|
||||
* This message must be garlic-encrypted to hide the contents from the OBEP.
|
||||
*
|
||||
* Preliminary, see proposal 157.
|
||||
*
|
||||
* @since 0.9.50
|
||||
*/
|
||||
public class InboundTunnelBuildMessage extends TunnelBuildMessage {
|
||||
public static final int MESSAGE_TYPE = 27;
|
||||
public static final int SHORT_RECORD_SIZE = ShortTunnelBuildMessage.SHORT_RECORD_SIZE;
|
||||
public static final int MAX_PLAINTEXT_RECORD_SIZE = OutboundTunnelBuildReplyMessage.MAX_PLAINTEXT_RECORD_SIZE;
|
||||
|
||||
private int _plaintextSlot = -1;
|
||||
private byte[] _plaintextRecord;
|
||||
|
||||
/** zero record count, will be set with readMessage() */
|
||||
public InboundTunnelBuildMessage(I2PAppContext context) {
|
||||
super(context, 0);
|
||||
}
|
||||
|
||||
public InboundTunnelBuildMessage(I2PAppContext context, int records) {
|
||||
super(context, records);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param record must be ShortEncryptedBuildRecord or null
|
||||
* @throws IllegalArgumentException on bad slot or record length.
|
||||
*/
|
||||
@Override
|
||||
public void setRecord(int index, EncryptedBuildRecord record) {
|
||||
if (record != null && (record.length() != SHORT_RECORD_SIZE || index == _plaintextSlot))
|
||||
throw new IllegalArgumentException();
|
||||
super.setRecord(index, record);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the slot and data for the plaintext record.
|
||||
* @throws IllegalArgumentException on bad slot or data length.
|
||||
*/
|
||||
public void setPlaintextRecord(int slot, byte[] data) {
|
||||
if (slot < 0 || slot >= RECORD_COUNT || data.length == 0 || data.length > MAX_PLAINTEXT_RECORD_SIZE ||
|
||||
(_records != null && _records[slot] != null))
|
||||
throw new IllegalArgumentException();
|
||||
_plaintextSlot = slot;
|
||||
_plaintextRecord = data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the slot for the plaintext record.
|
||||
* getRecord() for this slot will return null.
|
||||
*/
|
||||
public int getPlaintextSlot() {
|
||||
return _plaintextSlot;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the data for the plaintext record.
|
||||
*/
|
||||
public byte[] getPlaintextRecord() {
|
||||
return _plaintextRecord;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int calculateWrittenLength() {
|
||||
if (_plaintextRecord == null)
|
||||
throw new IllegalStateException("Plaintext record not set");
|
||||
return 4 + _plaintextRecord.length + ((RECORD_COUNT - 1) * SHORT_RECORD_SIZE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getType() { return MESSAGE_TYPE; }
|
||||
|
||||
@Override
|
||||
public void readMessage(byte[] data, int offset, int dataSize, int type) throws I2NPMessageException {
|
||||
if (type != MESSAGE_TYPE)
|
||||
throw new I2NPMessageException("Message type is incorrect for this message");
|
||||
int r = data[offset++];
|
||||
if (r <= 0 || r > MAX_RECORD_COUNT)
|
||||
throw new I2NPMessageException("Bad record count " + r);
|
||||
RECORD_COUNT = r;
|
||||
int _plaintextSlot = data[offset++] & 0xff;
|
||||
if (_plaintextSlot >= r)
|
||||
throw new I2NPMessageException("Bad slot " + _plaintextSlot);
|
||||
int size = (int) DataHelper.fromLong(data, offset, 2);
|
||||
if (size <= 0 || size > MAX_PLAINTEXT_RECORD_SIZE)
|
||||
throw new I2NPMessageException("Bad size " + size);
|
||||
offset += 2;
|
||||
_plaintextRecord = new byte[size];
|
||||
System.arraycopy(data, offset, _plaintextRecord, 0, size);
|
||||
offset += size;
|
||||
|
||||
if (dataSize != calculateWrittenLength())
|
||||
throw new I2NPMessageException("Wrong length (expects " + calculateWrittenLength() + ", recv " + dataSize + ")");
|
||||
_records = new EncryptedBuildRecord[RECORD_COUNT];
|
||||
for (int i = 0; i < RECORD_COUNT; i++) {
|
||||
if (i == _plaintextSlot)
|
||||
continue;
|
||||
byte rec[] = new byte[SHORT_RECORD_SIZE];
|
||||
System.arraycopy(data, offset, rec, 0, SHORT_RECORD_SIZE);
|
||||
setRecord(i, new ShortEncryptedBuildRecord(rec));
|
||||
offset += SHORT_RECORD_SIZE;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int writeMessageBody(byte[] out, int curIndex) throws I2NPMessageException {
|
||||
if (_plaintextRecord == null)
|
||||
throw new I2NPMessageException("Plaintext record not set");
|
||||
int remaining = out.length - (curIndex + calculateWrittenLength());
|
||||
if (remaining < 0)
|
||||
throw new I2NPMessageException("Not large enough (too short by " + remaining + ")");
|
||||
if (RECORD_COUNT <= 0 || RECORD_COUNT > MAX_RECORD_COUNT)
|
||||
throw new I2NPMessageException("Bad record count " + RECORD_COUNT);
|
||||
out[curIndex++] = (byte) RECORD_COUNT;
|
||||
out[curIndex++] = (byte) _plaintextSlot;
|
||||
DataHelper.toLong(out, curIndex, 2, _plaintextRecord.length);
|
||||
curIndex += 2;
|
||||
System.arraycopy(_plaintextRecord, 0, out, curIndex, _plaintextRecord.length);
|
||||
curIndex += _plaintextRecord.length;
|
||||
for (int i = 0; i < RECORD_COUNT; i++) {
|
||||
if (i == _plaintextSlot)
|
||||
continue;
|
||||
System.arraycopy(_records[i].getData(), 0, out, curIndex, SHORT_RECORD_SIZE);
|
||||
curIndex += SHORT_RECORD_SIZE;
|
||||
}
|
||||
return curIndex;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder buf = new StringBuilder(64);
|
||||
buf.append("[InboundTunnelBuildMessage: " +
|
||||
"\n\tID: ").append(getUniqueId())
|
||||
.append("\n\tRecords: ").append(getRecordCount())
|
||||
.append(']');
|
||||
return buf.toString();
|
||||
}
|
||||
}
|
||||
@@ -10,8 +10,7 @@ import net.i2p.data.DataHelper;
|
||||
|
||||
/**
|
||||
* Sent from the OBEP to the tunnel creator via an inbound tunnel.
|
||||
* Contains one plaintext variable-sized reply record for the creator
|
||||
* and a variable number of encrypted records for the following hops.
|
||||
* Contains a variable number of encrypted records.
|
||||
* This message must be garlic-encrypted to hide the contents from the OBGW.
|
||||
*
|
||||
* Preliminary, see proposal 157.
|
||||
@@ -21,10 +20,6 @@ import net.i2p.data.DataHelper;
|
||||
public class OutboundTunnelBuildReplyMessage extends TunnelBuildReplyMessage {
|
||||
public static final int MESSAGE_TYPE = 26;
|
||||
public static final int SHORT_RECORD_SIZE = ShortTunnelBuildMessage.SHORT_RECORD_SIZE;
|
||||
public static final int MAX_PLAINTEXT_RECORD_SIZE = 172;
|
||||
|
||||
private int _plaintextSlot = -1;
|
||||
private byte[] _plaintextRecord;
|
||||
|
||||
/** zero record count, will be set with readMessage() */
|
||||
public OutboundTunnelBuildReplyMessage(I2PAppContext context) {
|
||||
@@ -41,97 +36,14 @@ public class OutboundTunnelBuildReplyMessage extends TunnelBuildReplyMessage {
|
||||
*/
|
||||
@Override
|
||||
public void setRecord(int index, EncryptedBuildRecord record) {
|
||||
if (record != null && (record.length() != SHORT_RECORD_SIZE || index == _plaintextSlot))
|
||||
if (record != null && record.length() != SHORT_RECORD_SIZE)
|
||||
throw new IllegalArgumentException();
|
||||
super.setRecord(index, record);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the slot and data for the plaintext record.
|
||||
* Empty properties will be used.
|
||||
*
|
||||
* @param reply 0-255
|
||||
* @throws IllegalArgumentException on bad slot or data length.
|
||||
* @since 0.9.51
|
||||
*/
|
||||
public void setPlaintextRecord(int slot, int reply) {
|
||||
// 00 00 reply
|
||||
byte[] data = new byte[3];
|
||||
data[2] = (byte) reply;
|
||||
setPlaintextRecord(slot, data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the slot and data for the plaintext record.
|
||||
*
|
||||
* @param reply 0-255
|
||||
* @param props may be null
|
||||
* @throws IllegalArgumentException on bad slot or data length.
|
||||
* @since 0.9.51
|
||||
*/
|
||||
public void setPlaintextRecord(int slot, int reply, Properties props) throws DataFormatException {
|
||||
if (props == null || props.isEmpty()) {
|
||||
setPlaintextRecord(slot, reply);
|
||||
return;
|
||||
}
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
try {
|
||||
DataHelper.writeProperties(baos, props);
|
||||
} catch (IOException ioe) {}
|
||||
baos.write((byte) reply);
|
||||
setPlaintextRecord(slot, baos.toByteArray());
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the slot and data for the plaintext record.
|
||||
* @throws IllegalArgumentException on bad slot or data length.
|
||||
*/
|
||||
public void setPlaintextRecord(int slot, byte[] data) {
|
||||
if (slot < 0 || slot >= RECORD_COUNT || data.length == 0 || data.length > MAX_PLAINTEXT_RECORD_SIZE ||
|
||||
(_records != null && _records[slot] != null))
|
||||
throw new IllegalArgumentException();
|
||||
_plaintextSlot = slot;
|
||||
_plaintextRecord = data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the slot for the plaintext record.
|
||||
* getRecord() for this slot will return null.
|
||||
*/
|
||||
public int getPlaintextSlot() {
|
||||
return _plaintextSlot;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the data for the plaintext record.
|
||||
*/
|
||||
public byte[] getPlaintextRecord() {
|
||||
return _plaintextRecord;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the data for the plaintext record.
|
||||
* @since 0.9.51
|
||||
*/
|
||||
public int getPlaintextReply() {
|
||||
return _plaintextRecord[_plaintextRecord.length - 1] & 0xff;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the data for the plaintext record.
|
||||
* @since 0.9.51
|
||||
*/
|
||||
public Properties getPlaintextOptions() throws DataFormatException {
|
||||
Properties props = new Properties();
|
||||
DataHelper.fromProperties(_plaintextRecord, 0, props);
|
||||
return props;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int calculateWrittenLength() {
|
||||
if (_plaintextRecord == null)
|
||||
throw new IllegalStateException("Plaintext record not set");
|
||||
return 4 + _plaintextRecord.length + ((RECORD_COUNT - 1) * SHORT_RECORD_SIZE);
|
||||
return 1 + (RECORD_COUNT * SHORT_RECORD_SIZE);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -145,23 +57,10 @@ public class OutboundTunnelBuildReplyMessage extends TunnelBuildReplyMessage {
|
||||
if (r <= 0 || r > MAX_RECORD_COUNT)
|
||||
throw new I2NPMessageException("Bad record count " + r);
|
||||
RECORD_COUNT = r;
|
||||
_plaintextSlot = data[offset++] & 0xff;
|
||||
if (_plaintextSlot < 0 || _plaintextSlot >= r)
|
||||
throw new I2NPMessageException("Bad slot " + _plaintextSlot);
|
||||
int size = (int) DataHelper.fromLong(data, offset, 2);
|
||||
if (size <= 0 || size > MAX_PLAINTEXT_RECORD_SIZE)
|
||||
throw new I2NPMessageException("Bad size " + size);
|
||||
offset += 2;
|
||||
_plaintextRecord = new byte[size];
|
||||
System.arraycopy(data, offset, _plaintextRecord, 0, size);
|
||||
offset += size;
|
||||
|
||||
if (dataSize != calculateWrittenLength())
|
||||
throw new I2NPMessageException("Wrong length (expects " + calculateWrittenLength() + ", recv " + dataSize + ")");
|
||||
_records = new EncryptedBuildRecord[RECORD_COUNT];
|
||||
for (int i = 0; i < RECORD_COUNT; i++) {
|
||||
if (i == _plaintextSlot)
|
||||
continue;
|
||||
byte rec[] = new byte[SHORT_RECORD_SIZE];
|
||||
System.arraycopy(data, offset, rec, 0, SHORT_RECORD_SIZE);
|
||||
setRecord(i, new ShortEncryptedBuildRecord(rec));
|
||||
@@ -171,22 +70,13 @@ public class OutboundTunnelBuildReplyMessage extends TunnelBuildReplyMessage {
|
||||
|
||||
@Override
|
||||
protected int writeMessageBody(byte[] out, int curIndex) throws I2NPMessageException {
|
||||
if (_plaintextRecord == null)
|
||||
throw new I2NPMessageException("Plaintext record not set");
|
||||
int remaining = out.length - (curIndex + calculateWrittenLength());
|
||||
if (remaining < 0)
|
||||
throw new I2NPMessageException("Not large enough (too short by " + remaining + ")");
|
||||
if (RECORD_COUNT <= 0 || RECORD_COUNT > MAX_RECORD_COUNT)
|
||||
throw new I2NPMessageException("Bad record count " + RECORD_COUNT);
|
||||
out[curIndex++] = (byte) RECORD_COUNT;
|
||||
out[curIndex++] = (byte) _plaintextSlot;
|
||||
DataHelper.toLong(out, curIndex, 2, _plaintextRecord.length);
|
||||
curIndex += 2;
|
||||
System.arraycopy(_plaintextRecord, 0, out, curIndex, _plaintextRecord.length);
|
||||
curIndex += _plaintextRecord.length;
|
||||
for (int i = 0; i < RECORD_COUNT; i++) {
|
||||
if (i == _plaintextSlot)
|
||||
continue;
|
||||
System.arraycopy(_records[i].getData(), 0, out, curIndex, SHORT_RECORD_SIZE);
|
||||
curIndex += SHORT_RECORD_SIZE;
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@ package net.i2p.data.i2np;
|
||||
|
||||
/**
|
||||
* Small records.
|
||||
* 236 bytes.
|
||||
* 218 bytes.
|
||||
* Preliminary, see proposal 157.
|
||||
*
|
||||
* Note that these are layer-encrypted and layer-decrypted in-place.
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
package net.i2p.router.tunnel;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import net.i2p.data.DataHelper;
|
||||
import net.i2p.data.Hash;
|
||||
import net.i2p.data.SessionKey;
|
||||
@@ -21,8 +19,6 @@ public class HopConfig {
|
||||
private Hash _sendTo;
|
||||
private SessionKey _layerKey;
|
||||
private SessionKey _ivKey;
|
||||
private SessionKey _replyKey;
|
||||
private byte[] _replyIV;
|
||||
private long _creation;
|
||||
private long _expiration;
|
||||
//private Map _options;
|
||||
@@ -179,20 +175,19 @@ public class HopConfig {
|
||||
/** */
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder buf = new StringBuilder(64);
|
||||
StringBuilder buf = new StringBuilder(256);
|
||||
if (_receiveTunnel != null) {
|
||||
buf.append("recv on ");
|
||||
buf.append(_receiveTunnel.getTunnelId());
|
||||
buf.append(' ');
|
||||
}
|
||||
|
||||
if (_sendTo != null) {
|
||||
buf.append("send to ").append(_sendTo.toBase64().substring(0,4)).append(":");
|
||||
buf.append(" send to ").append(_sendTo.toBase64().substring(0,4)).append(":");
|
||||
if (_sendTunnel != null)
|
||||
buf.append(_sendTunnel.getTunnelId());
|
||||
}
|
||||
|
||||
buf.append(" exp. ").append(new Date(_expiration));
|
||||
buf.append(" layer key: ").append(_layerKey);
|
||||
buf.append(" IV key: ").append(_ivKey);
|
||||
buf.append(" exp. ").append(DataHelper.formatTime(_expiration));
|
||||
int messagesProcessed = getProcessedMessagesCount();
|
||||
if (messagesProcessed > 0)
|
||||
buf.append(" used ").append(messagesProcessed).append("KB");
|
||||
|
||||
@@ -1012,7 +1012,6 @@ class BuildHandler implements Runnable {
|
||||
TunnelBuildReplyMessage replyMsg;
|
||||
if (state.msg.getType() == ShortTunnelBuildMessage.MESSAGE_TYPE) {
|
||||
OutboundTunnelBuildReplyMessage otbrm = new OutboundTunnelBuildReplyMessage(_context, records);
|
||||
otbrm.setPlaintextRecord(ourSlot, response);
|
||||
replyMsg = otbrm;
|
||||
} else if (records == TunnelBuildMessage.MAX_RECORD_COUNT) {
|
||||
replyMsg = new TunnelBuildReplyMessage(_context);
|
||||
|
||||
@@ -90,10 +90,6 @@ class BuildReplyHandler {
|
||||
rv[i] = ok;
|
||||
}
|
||||
}
|
||||
if (reply.getType() == OutboundTunnelBuildReplyMessage.MESSAGE_TYPE) {
|
||||
OutboundTunnelBuildReplyMessage otbrm = (OutboundTunnelBuildReplyMessage) reply;
|
||||
rv[otbrm.getPlaintextSlot()] = otbrm.getPlaintextReply();
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
@@ -109,23 +105,10 @@ class BuildReplyHandler {
|
||||
private int decryptRecord(TunnelBuildReplyMessage reply, TunnelCreatorConfig cfg, int recordNum, int hop) {
|
||||
EncryptedBuildRecord rec = reply.getRecord(recordNum);
|
||||
int type = reply.getType();
|
||||
boolean isOTBRM = type == OutboundTunnelBuildReplyMessage.MESSAGE_TYPE;
|
||||
if (rec == null) {
|
||||
if (!isOTBRM) {
|
||||
if (log.shouldWarn())
|
||||
log.warn("Missing record " + recordNum);
|
||||
return -1;
|
||||
}
|
||||
OutboundTunnelBuildReplyMessage otbrm = (OutboundTunnelBuildReplyMessage) reply;
|
||||
if (otbrm.getPlaintextSlot() != recordNum) {
|
||||
if (log.shouldWarn())
|
||||
log.warn("Plaintext slot mismatch expected " + recordNum + " got " + otbrm.getPlaintextSlot());
|
||||
return -1;
|
||||
}
|
||||
int rv = otbrm.getPlaintextReply();
|
||||
if (log.shouldLog(Log.DEBUG))
|
||||
log.debug(reply.getUniqueId() + ": Received: " + rv + " for plaintext record " + recordNum + "/" + hop);
|
||||
return rv;
|
||||
if (log.shouldWarn())
|
||||
log.warn("Missing record " + recordNum);
|
||||
return -1;
|
||||
}
|
||||
byte[] data = rec.getData();
|
||||
int start = cfg.getLength() - 1;
|
||||
@@ -137,6 +120,7 @@ class BuildReplyHandler {
|
||||
if (isEC)
|
||||
end++;
|
||||
// do we need to adjust this for the endpoint?
|
||||
boolean isOTBRM = type == OutboundTunnelBuildReplyMessage.MESSAGE_TYPE;
|
||||
boolean isShort = isOTBRM || type == ShortTunnelBuildReplyMessage.MESSAGE_TYPE;
|
||||
if (isShort) {
|
||||
byte iv[] = new byte[12];
|
||||
|
||||
@@ -158,6 +158,7 @@ public class BuildMessageTestStandalone extends TestCase {
|
||||
for (int j = 0; j < TunnelBuildMessage.MAX_RECORD_COUNT; j++) {
|
||||
if (msg.getRecord(j) == null) {
|
||||
ourSlot = j;
|
||||
msg.setRecord(j, reply);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -198,21 +199,8 @@ public class BuildMessageTestStandalone extends TestCase {
|
||||
TunnelBuildReplyMessage reply;
|
||||
if (testType == 3) {
|
||||
OutboundTunnelBuildReplyMessage otbrm = new OutboundTunnelBuildReplyMessage(ctx, TunnelBuildMessage.MAX_RECORD_COUNT);
|
||||
int ibep = _peers.length - 1;
|
||||
int ibepSlot = -1;
|
||||
for (int i = 0; i < order.size(); i++) {
|
||||
int slot = order.get(i).intValue();
|
||||
if (slot == ibep) {
|
||||
ibepSlot = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
log.debug("OTBRM plaintext slot is " + ibepSlot);
|
||||
for (int i = 0; i < TunnelBuildMessage.MAX_RECORD_COUNT; i++) {
|
||||
if (i == ibepSlot)
|
||||
otbrm.setPlaintextRecord(i, 0);
|
||||
else
|
||||
otbrm.setRecord(i, msg.getRecord(i));
|
||||
otbrm.setRecord(i, msg.getRecord(i));
|
||||
}
|
||||
// test read/write
|
||||
byte[] data = otbrm.toByteArray();
|
||||
|
||||
Reference in New Issue
Block a user