Util: Hook in ByteArrayStream

Set accurate lengths for zero-copy
This commit is contained in:
zzz
2020-11-04 12:04:24 +00:00
parent 35da97936d
commit e242015145
25 changed files with 78 additions and 61 deletions

View File

@@ -40,6 +40,7 @@ import net.i2p.data.SigningPrivateKey;
import net.i2p.data.SigningPublicKey;
import net.i2p.data.SimpleDataStructure;
import net.i2p.util.Addresses;
import net.i2p.util.ByteArrayStream;
import net.i2p.util.HexDump;
import net.i2p.util.RandomSource;
import net.i2p.util.SecureFileOutputStream;
@@ -904,11 +905,11 @@ public final class SelfSignedGenerator {
* @throws IllegalArgumentException
*/
private static byte[] getEncodedOIDSeq(String oid) {
ByteArrayOutputStream baos = new ByteArrayOutputStream(16);
byte[] b = getEncodedOID(oid);
ByteArrayStream baos = new ByteArrayStream(4 + b.length);
baos.write(0x30);
// len to be filled in later
baos.write(0);
byte[] b = getEncodedOID(oid);
baos.write(b, 0, b.length);
// NULL
baos.write(0x05);

View File

@@ -19,6 +19,7 @@ import net.i2p.crypto.KeyPair;
import net.i2p.crypto.SHA256Generator;
import net.i2p.crypto.SigType;
import net.i2p.crypto.x25519.X25519DH;
import net.i2p.util.ByteArrayStream;
import net.i2p.util.Clock;
import net.i2p.util.Log;
@@ -853,7 +854,7 @@ public class EncryptedLeaseSet extends LeaseSet2 {
_flags = saveFlags;
SigningPrivateKey bkey = Blinding.blind(key, _alpha);
int len = size();
ByteArrayOutputStream out = new ByteArrayOutputStream(1 + len);
ByteArrayStream out = new ByteArrayStream(1 + len);
try {
// unlike LS1, sig covers type
out.write(getType());

View File

@@ -9,7 +9,6 @@ package net.i2p.data;
*
*/
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
@@ -18,6 +17,7 @@ import java.util.Arrays;
import net.i2p.crypto.EncType;
import net.i2p.crypto.SHA256Generator;
import net.i2p.crypto.SigType;
import net.i2p.util.ByteArrayStream;
/**
* KeysAndCert has a public key, a signing key, and a certificate.
@@ -239,7 +239,9 @@ public class KeysAndCert extends DataStructureImpl {
return __calculatedHash;
byte identBytes[];
try {
ByteArrayOutputStream baos = new ByteArrayOutputStream(400);
if (_certificate == null)
throw new IllegalStateException("KAC hash error");
ByteArrayStream baos = new ByteArrayStream(384 + _certificate.size());
writeBytes(baos);
identBytes = baos.toByteArray();
} catch (IOException ioe) {

View File

@@ -10,7 +10,6 @@ package net.i2p.data;
*/
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
@@ -22,6 +21,7 @@ import net.i2p.I2PAppContext;
import net.i2p.crypto.DSAEngine;
import net.i2p.crypto.EncType;
import net.i2p.crypto.SigType;
import net.i2p.util.ByteArrayStream;
import net.i2p.util.Clock;
import net.i2p.util.Log;
import net.i2p.util.RandomSource;
@@ -335,7 +335,7 @@ public class LeaseSet extends DatabaseEntry {
if ((_destination == null) || (_encryptionKey == null) || (_signingKey == null))
return null;
int len = size();
ByteArrayOutputStream out = new ByteArrayOutputStream(len);
ByteArrayStream out = new ByteArrayStream(len);
try {
_destination.writeBytes(out);
_encryptionKey.writeBytes(out);
@@ -497,7 +497,7 @@ public class LeaseSet extends DatabaseEntry {
if (size < 1 || size > MAX_LEASES-1)
throw new IllegalArgumentException("Bad number of leases for encryption");
int datalen = ((DATA_LEN * size / 16) + 1) * 16;
ByteArrayOutputStream baos = new ByteArrayOutputStream(datalen);
ByteArrayStream baos = new ByteArrayStream(datalen);
for (int i = 0; i < size; i++) {
_leases.get(i).getGateway().writeBytes(baos);
_leases.get(i).getTunnelId().writeBytes(baos);
@@ -545,7 +545,7 @@ public class LeaseSet extends DatabaseEntry {
throw new DataFormatException("Bad number of leases decrypting " + _destination.toBase32() +
" - is this destination encrypted?");
int datalen = DATA_LEN * size;
ByteArrayOutputStream baos = new ByteArrayOutputStream(datalen);
ByteArrayStream baos = new ByteArrayStream(datalen);
for (int i = 0; i < size; i++) {
_leases.get(i).getGateway().writeBytes(baos);
_leases.get(i).getTunnelId().writeBytes(baos);

View File

@@ -1,6 +1,5 @@
package net.i2p.data;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
@@ -16,6 +15,7 @@ import net.i2p.crypto.DSAEngine;
import net.i2p.crypto.EncType;
import net.i2p.crypto.SigAlgo;
import net.i2p.crypto.SigType;
import net.i2p.util.ByteArrayStream;
import net.i2p.util.Clock;
import net.i2p.util.Log;
import net.i2p.util.OrderedProperties;
@@ -289,7 +289,7 @@ public class LeaseSet2 extends LeaseSet {
* @return null on error
*/
public static Signature offlineSign(long expires, SigningPublicKey transientSPK, SigningPrivateKey priv) {
ByteArrayOutputStream baos = new ByteArrayOutputStream(128);
ByteArrayStream baos = new ByteArrayStream(4 + 2 + transientSPK.length());
try {
DataHelper.writeLong(baos, 4, expires / 1000);
DataHelper.writeLong(baos, 2, transientSPK.getType().getCode());
@@ -314,7 +314,7 @@ public class LeaseSet2 extends LeaseSet {
I2PAppContext ctx = I2PAppContext.getGlobalContext();
if (_transientExpires < ctx.clock().now())
return false;
ByteArrayOutputStream baos = new ByteArrayOutputStream(6 + _transientSigningPublicKey.length());
ByteArrayStream baos = new ByteArrayStream(4 + 2 + _transientSigningPublicKey.length());
try {
DataHelper.writeLong(baos, 4, _transientExpires / 1000);
DataHelper.writeLong(baos, 2, _transientSigningPublicKey.getType().getCode());
@@ -387,7 +387,7 @@ public class LeaseSet2 extends LeaseSet {
if (_destination == null)
return null;
int len = size();
ByteArrayOutputStream out = new ByteArrayOutputStream(len);
ByteArrayStream out = new ByteArrayStream(len);
try {
writeBytesWithoutSig(out);
} catch (IOException ioe) {
@@ -605,7 +605,7 @@ public class LeaseSet2 extends LeaseSet {
if (key == null)
throw new DataFormatException("No signing key");
int len = size();
ByteArrayOutputStream out = new ByteArrayOutputStream(1 + len);
ByteArrayStream out = new ByteArrayStream(1 + len);
try {
// unlike LS1, sig covers type
out.write(getType());
@@ -647,7 +647,7 @@ public class LeaseSet2 extends LeaseSet {
spk = getSigningPublicKey();
}
int len = size();
ByteArrayOutputStream out = new ByteArrayOutputStream(1 + len);
ByteArrayStream out = new ByteArrayStream(1 + len);
try {
// unlike LS1, sig covers type
out.write(getType());

View File

@@ -5,12 +5,12 @@ package net.i2p.data.i2cp;
*
*/
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.util.ByteArrayStream;
/**
* Tell the other side the limits
@@ -63,7 +63,7 @@ public class BandwidthLimitsMessage extends I2CPMessageImpl {
@Override
protected byte[] doWriteMessage() throws I2CPMessageException, IOException {
ByteArrayOutputStream os = new ByteArrayOutputStream(64);
ByteArrayStream os = new ByteArrayStream(4 * LIMITS);
try {
for (int i = 0; i < LIMITS; i++) {
DataHelper.writeLong(os, 4, data[i]);

View File

@@ -1,6 +1,5 @@
package net.i2p.data.i2cp;
import java.io.ByteArrayOutputStream;
import java.io.EOFException;
import java.io.IOException;
import java.io.InputStream;
@@ -19,6 +18,7 @@ import net.i2p.data.LeaseSet2;
import net.i2p.data.MetaLeaseSet;
import net.i2p.data.PrivateKey;
import net.i2p.data.PublicKey;
import net.i2p.util.ByteArrayStream;
/**
* Like CreateLeaseSetMessage, but supports both old
@@ -174,7 +174,7 @@ public class CreateLeaseSet2Message extends CreateLeaseSetMessage {
size += pk.length();
}
}
ByteArrayOutputStream os = new ByteArrayOutputStream(size);
ByteArrayStream os = new ByteArrayStream(size);
try {
_sessionId.writeBytes(os);
os.write(_leaseSet.getType());

View File

@@ -9,7 +9,6 @@ package net.i2p.data.i2cp;
*
*/
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
@@ -17,6 +16,7 @@ import net.i2p.data.DataFormatException;
import net.i2p.data.LeaseSet;
import net.i2p.data.PrivateKey;
import net.i2p.data.SigningPrivateKey;
import net.i2p.util.ByteArrayStream;
/**
* Defines the message a client sends to a router when authorizing
@@ -105,7 +105,7 @@ public class CreateLeaseSetMessage extends I2CPMessageImpl {
+ _signingPrivateKey.length()
+ PrivateKey.KEYSIZE_BYTES
+ _leaseSet.size();
ByteArrayOutputStream os = new ByteArrayOutputStream(size);
ByteArrayStream os = new ByteArrayStream(size);
try {
_sessionId.writeBytes(os);
_signingPrivateKey.writeBytes(os);

View File

@@ -6,13 +6,13 @@ package net.i2p.data.i2cp;
*
*/
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import net.i2p.data.DataFormatException;
import net.i2p.data.Destination;
import net.i2p.data.Hash;
import net.i2p.util.ByteArrayStream;
/**
* Response to DestLookupMessage.
@@ -76,7 +76,7 @@ public class DestReplyMessage extends I2CPMessageImpl {
return new byte[0]; // null response allowed
return _hash.getData();
}
ByteArrayOutputStream os = new ByteArrayOutputStream(_dest.size());
ByteArrayStream os = new ByteArrayStream(_dest.size());
try {
_dest.writeBytes(os);
} catch (DataFormatException dfe) {

View File

@@ -9,11 +9,11 @@ package net.i2p.data.i2cp;
*
*/
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import net.i2p.data.DataFormatException;
import net.i2p.util.ByteArrayStream;
/**
* Defines the message a client sends to a router when destroying
@@ -61,7 +61,7 @@ public class DestroySessionMessage extends I2CPMessageImpl {
protected byte[] doWriteMessage() throws I2CPMessageException, IOException {
if (_sessionId == null)
throw new I2CPMessageException("Unable to write out the message as there is not enough data");
ByteArrayOutputStream os = new ByteArrayOutputStream(64);
ByteArrayStream os = new ByteArrayStream(2);
try {
_sessionId.writeBytes(os);
} catch (DataFormatException dfe) {

View File

@@ -9,12 +9,12 @@ package net.i2p.data.i2cp;
*
*/
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.util.ByteArrayStream;
/**
* Defines the message a client sends to a router when destroying
@@ -48,7 +48,10 @@ public class DisconnectMessage extends I2CPMessageImpl {
@Override
protected byte[] doWriteMessage() throws I2CPMessageException, IOException {
ByteArrayOutputStream os = new ByteArrayOutputStream(64);
int len = 1;
if (_reason != null)
len += _reason.length();
ByteArrayStream os = new ByteArrayStream(len);
try {
DataHelper.writeString(os, _reason);
} catch (DataFormatException dfe) {

View File

@@ -9,7 +9,6 @@ package net.i2p.data.i2cp;
*
*/
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Map;
@@ -17,6 +16,7 @@ import java.util.Properties;
import net.i2p.data.DataFormatException;
import net.i2p.data.DataHelper;
import net.i2p.util.ByteArrayStream;
import net.i2p.util.OrderedProperties;
/**
@@ -99,7 +99,7 @@ public class GetDateMessage extends I2CPMessageImpl {
protected byte[] doWriteMessage() throws I2CPMessageException, IOException {
if (_version == null)
return new byte[0];
ByteArrayOutputStream os = new ByteArrayOutputStream(_options != null ? 128 : 16);
ByteArrayStream os = new ByteArrayStream(_options != null ? 128 : (1 + 6));
try {
DataHelper.writeString(os, _version);
if (_options != null && !_options.isEmpty())

View File

@@ -5,7 +5,6 @@ package net.i2p.data.i2cp;
* with no warranty of any kind, either expressed or implied.
*/
import java.io.ByteArrayOutputStream;
import java.io.EOFException;
import java.io.IOException;
import java.io.InputStream;
@@ -13,6 +12,7 @@ import java.io.InputStream;
import net.i2p.data.DataFormatException;
import net.i2p.data.DataHelper;
import net.i2p.data.Hash;
import net.i2p.util.ByteArrayStream;
/**
* Request the router look up the dest for a hash
@@ -158,7 +158,7 @@ public class HostLookupMessage extends I2CPMessageImpl {
} else {
throw new I2CPMessageException("bad type");
}
ByteArrayOutputStream os = new ByteArrayOutputStream(len);
ByteArrayStream os = new ByteArrayStream(len);
try {
_sessionId.writeBytes(os);
DataHelper.writeLong(os, 4, _reqID);

View File

@@ -6,7 +6,6 @@ package net.i2p.data.i2cp;
*
*/
import java.io.ByteArrayOutputStream;
import java.io.EOFException;
import java.io.IOException;
import java.io.InputStream;
@@ -14,6 +13,7 @@ import java.io.InputStream;
import net.i2p.data.DataFormatException;
import net.i2p.data.DataHelper;
import net.i2p.data.Destination;
import net.i2p.util.ByteArrayStream;
/**
* Response to HostLookupMessage. Replaces DestReplyMessage.
@@ -135,7 +135,7 @@ public class HostReplyMessage extends I2CPMessageImpl {
throw new I2CPMessageException("Unable to write out the message as there is not enough data");
len += _dest.size();
}
ByteArrayOutputStream os = new ByteArrayOutputStream(len);
ByteArrayStream os = new ByteArrayStream(len);
try {
_sessionId.writeBytes(os);
DataHelper.writeLong(os, 4, _reqID);

View File

@@ -9,11 +9,11 @@ package net.i2p.data.i2cp;
*
*/
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import net.i2p.data.DataFormatException;
import net.i2p.util.ByteArrayStream;
/**
* Defines the message a client sends to a router when asking the
@@ -93,7 +93,11 @@ public class ReportAbuseMessage extends I2CPMessageImpl {
protected byte[] doWriteMessage() throws I2CPMessageException, IOException {
if ((_sessionId == null) || (_severity == null) || (_reason == null))
throw new I2CPMessageException("Not enough information to construct the message");
ByteArrayOutputStream os = new ByteArrayOutputStream(32);
int len = 2 + 1 + 4 + 1;
String r = _reason.getReason();
if (r != null)
len += r.length();
ByteArrayStream os = new ByteArrayStream(len);
try {
_sessionId.writeBytes(os);
_severity.writeBytes(os);

View File

@@ -9,7 +9,6 @@ package net.i2p.data.i2cp;
*
*/
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.Serializable;
@@ -21,6 +20,7 @@ import net.i2p.data.DataFormatException;
import net.i2p.data.DataHelper;
import net.i2p.data.Hash;
import net.i2p.data.TunnelId;
import net.i2p.util.ByteArrayStream;
/**
* Defines the message a router sends to a client to request that
@@ -38,7 +38,7 @@ public class RequestLeaseSetMessage extends I2CPMessageImpl {
private Date _end;
public RequestLeaseSetMessage() {
_endpoints = new ArrayList<TunnelEndpoint>();
_endpoints = new ArrayList<TunnelEndpoint>(6);
}
public SessionId getSessionId() {
@@ -119,7 +119,8 @@ public class RequestLeaseSetMessage extends I2CPMessageImpl {
protected byte[] doWriteMessage() throws I2CPMessageException, IOException {
if (_sessionId == null)
throw new I2CPMessageException("Unable to write out the message as there is not enough data");
ByteArrayOutputStream os = new ByteArrayOutputStream(256);
int len = 2 + 1 + (_endpoints.size() * (32 + 4)) + 8;
ByteArrayStream os = new ByteArrayStream(len);
try {
_sessionId.writeBytes(os);
os.write((byte) _endpoints.size());

View File

@@ -9,7 +9,6 @@ package net.i2p.data.i2cp;
*
*/
import java.io.ByteArrayOutputStream;
import java.io.EOFException;
import java.io.IOException;
import java.io.InputStream;
@@ -19,6 +18,7 @@ import java.util.List;
import net.i2p.data.DataFormatException;
import net.i2p.data.DataHelper;
import net.i2p.data.Lease;
import net.i2p.util.ByteArrayStream;
import net.i2p.util.VersionComparator;
/**
@@ -38,7 +38,7 @@ public class RequestVariableLeaseSetMessage extends I2CPMessageImpl {
private static final String MIN_VERSION = "0.9.7";
public RequestVariableLeaseSetMessage() {
_endpoints = new ArrayList<Lease>();
_endpoints = new ArrayList<Lease>(6);
}
/**
@@ -109,7 +109,8 @@ public class RequestVariableLeaseSetMessage extends I2CPMessageImpl {
protected byte[] doWriteMessage() throws I2CPMessageException, IOException {
if (_sessionId == null)
throw new I2CPMessageException("No data");
ByteArrayOutputStream os = new ByteArrayOutputStream(256);
int len = 2 + 1 + (_endpoints.size() * 44);
ByteArrayStream os = new ByteArrayStream(len);
try {
_sessionId.writeBytes(os);
os.write((byte) _endpoints.size());

View File

@@ -27,6 +27,7 @@ import net.i2p.data.Destination;
import net.i2p.data.Signature;
import net.i2p.data.SigningPrivateKey;
import net.i2p.data.SigningPublicKey;
import net.i2p.util.ByteArrayStream;
import net.i2p.util.Clock;
import net.i2p.util.Log;
import net.i2p.util.OrderedProperties;
@@ -278,7 +279,7 @@ public class SessionConfig extends DataStructureImpl {
Signature sig = getOfflineSignature();
if (sig == null)
return false;
ByteArrayOutputStream baos = new ByteArrayOutputStream(128);
ByteArrayStream baos = new ByteArrayStream(6 + spk.length());
try {
DataHelper.writeLong(baos, 4, expires / 1000);
DataHelper.writeLong(baos, 2, spk.getType().getCode());
@@ -323,7 +324,7 @@ public class SessionConfig extends DataStructureImpl {
if (_options == null) return null;
if (_creationDate == null) return null;
ByteArrayOutputStream out = new ByteArrayOutputStream();
ByteArrayOutputStream out = new ByteArrayOutputStream(512);
try {
//_log.debug("PubKey size for destination: " + _destination.getPublicKey().getData().length);
//_log.debug("SigningKey size for destination: " + _destination.getSigningPublicKey().getData().length);

View File

@@ -9,13 +9,13 @@ package net.i2p.data.i2cp;
*
*/
import java.io.ByteArrayOutputStream;
import java.io.EOFException;
import java.io.IOException;
import java.io.InputStream;
import net.i2p.data.DataFormatException;
import net.i2p.data.DataHelper;
import net.i2p.util.ByteArrayStream;
/**
* Defines the message a router sends to a client indicating the
@@ -87,7 +87,7 @@ public class SessionStatusMessage extends I2CPMessageImpl {
protected byte[] doWriteMessage() throws I2CPMessageException, IOException {
if (_sessionId == null)
throw new I2CPMessageException("Unable to write out the message as there is not enough data");
ByteArrayOutputStream os = new ByteArrayOutputStream(64);
ByteArrayStream os = new ByteArrayStream(3);
try {
_sessionId.writeBytes(os);
os.write((byte) _status);

View File

@@ -9,13 +9,13 @@ package net.i2p.data.i2cp;
*
*/
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Date;
import net.i2p.data.DataFormatException;
import net.i2p.data.DataHelper;
import net.i2p.util.ByteArrayStream;
import net.i2p.util.Clock;
/**
@@ -74,7 +74,7 @@ public class SetDateMessage extends I2CPMessageImpl {
protected byte[] doWriteMessage() throws I2CPMessageException, IOException {
if (_date == null)
throw new I2CPMessageException("Unable to write out the message as there is not enough data");
ByteArrayOutputStream os = new ByteArrayOutputStream(32);
ByteArrayStream os = new ByteArrayStream(8 + 1 + 6);
try {
DataHelper.writeDate(os, _date);
if (_version != null)

View File

@@ -18,6 +18,9 @@ public class ByteArrayStream extends ByteArrayOutputStream {
super();
}
/**
* @param size if accurate, toByteArray() will be zero-copy
*/
public ByteArrayStream(int size) {
super(size);
}