2005-02-24 jrandom
* Cache temporary memory allocation in the DSA's SHA1 impl, and the packet data in the streaming lib. * Fixed a streaming lib bug where the connection initiator would fail the stream if the ACK to their SYN was lost.
This commit is contained in:
@ -31,7 +31,7 @@ public class I2PTunnelRunner extends I2PThread implements I2PSocket.SocketErrorL
|
||||
* Sun's impl of BufferedOutputStream), but that is the streaming
|
||||
* api's job...
|
||||
*/
|
||||
static int MAX_PACKET_SIZE = 1024 * 32;
|
||||
static int MAX_PACKET_SIZE = 1024 * 16;
|
||||
|
||||
static final int NETWORK_BUFFER_SIZE = MAX_PACKET_SIZE;
|
||||
|
||||
|
@ -3,6 +3,8 @@ package net.i2p.client.streaming;
|
||||
import java.io.InterruptedIOException;
|
||||
import java.io.IOException;
|
||||
import net.i2p.I2PAppContext;
|
||||
import net.i2p.data.ByteArray;
|
||||
import net.i2p.util.ByteCache;
|
||||
import net.i2p.util.Log;
|
||||
|
||||
/**
|
||||
@ -18,11 +20,13 @@ class ConnectionDataReceiver implements MessageOutputStream.DataReceiver {
|
||||
private Log _log;
|
||||
private Connection _connection;
|
||||
private static final MessageOutputStream.WriteStatus _dummyStatus = new DummyStatus();
|
||||
private ByteCache _cache;
|
||||
|
||||
public ConnectionDataReceiver(I2PAppContext ctx, Connection con) {
|
||||
_context = ctx;
|
||||
_log = ctx.logManager().getLog(ConnectionDataReceiver.class);
|
||||
_connection = con;
|
||||
_cache = ByteCache.getInstance(128, Packet.MAX_PAYLOAD_SIZE);
|
||||
}
|
||||
|
||||
public boolean writeInProcess() {
|
||||
@ -133,9 +137,11 @@ class ConnectionDataReceiver implements MessageOutputStream.DataReceiver {
|
||||
private PacketLocal buildPacket(Connection con, byte buf[], int off, int size, boolean forceIncrement) {
|
||||
boolean ackOnly = isAckOnly(con, size);
|
||||
PacketLocal packet = new PacketLocal(_context, con.getRemotePeer(), con);
|
||||
byte data[] = new byte[size];
|
||||
ByteArray data = (size <= Packet.MAX_PAYLOAD_SIZE ? _cache.acquire() : new ByteArray(new byte[size]));
|
||||
if (size > 0)
|
||||
System.arraycopy(buf, off, data, 0, size);
|
||||
System.arraycopy(buf, off, data.getData(), 0, size);
|
||||
data.setValid(size);
|
||||
data.setOffset(0);
|
||||
packet.setPayload(data);
|
||||
if (ackOnly && !forceIncrement)
|
||||
packet.setSequenceNum(0);
|
||||
|
@ -6,6 +6,7 @@ import net.i2p.I2PAppContext;
|
||||
import net.i2p.I2PException;
|
||||
import net.i2p.data.DataHelper;
|
||||
import net.i2p.data.Destination;
|
||||
import net.i2p.util.ByteCache;
|
||||
import net.i2p.util.Log;
|
||||
import net.i2p.util.SimpleTimer;
|
||||
|
||||
@ -17,9 +18,11 @@ import net.i2p.util.SimpleTimer;
|
||||
public class ConnectionPacketHandler {
|
||||
private I2PAppContext _context;
|
||||
private Log _log;
|
||||
private ByteCache _cache;
|
||||
|
||||
public ConnectionPacketHandler(I2PAppContext context) {
|
||||
_context = context;
|
||||
_cache = ByteCache.getInstance(128, Packet.MAX_PAYLOAD_SIZE);
|
||||
_log = context.logManager().getLog(ConnectionPacketHandler.class);
|
||||
_context.statManager().createRateStat("stream.con.receiveMessageSize", "Size of a message received on a connection", "Stream", new long[] { 60*1000, 10*60*1000, 60*60*1000 });
|
||||
_context.statManager().createRateStat("stream.con.receiveDuplicateSize", "Size of a duplicate message received on a connection", "Stream", new long[] { 60*1000, 10*60*1000, 60*60*1000 });
|
||||
@ -34,6 +37,7 @@ public class ConnectionPacketHandler {
|
||||
if (!ok) {
|
||||
if ( (!packet.isFlagSet(Packet.FLAG_RESET)) && (_log.shouldLog(Log.ERROR)) )
|
||||
_log.error("Packet does NOT verify: " + packet);
|
||||
_cache.release(packet.getPayload());
|
||||
return;
|
||||
}
|
||||
|
||||
@ -47,6 +51,7 @@ public class ConnectionPacketHandler {
|
||||
if (_log.shouldLog(Log.WARN))
|
||||
_log.warn("Received a packet after hard disconnect, ignoring: " + packet + " on " + con);
|
||||
}
|
||||
_cache.release(packet.getPayload());
|
||||
return;
|
||||
}
|
||||
|
||||
@ -72,6 +77,7 @@ public class ConnectionPacketHandler {
|
||||
+ ": dropping " + packet);
|
||||
ack(con, packet.getAckThrough(), packet.getNacks(), null, false);
|
||||
con.getOptions().setChoke(5*1000);
|
||||
_cache.release(packet.getPayload());
|
||||
return;
|
||||
}
|
||||
con.getOptions().setChoke(0);
|
||||
@ -91,6 +97,7 @@ public class ConnectionPacketHandler {
|
||||
con.closeReceived();
|
||||
|
||||
boolean fastAck = false;
|
||||
boolean ackOnly = false;
|
||||
|
||||
if (isNew) {
|
||||
con.incrementUnackedPacketsReceived();
|
||||
@ -127,11 +134,19 @@ public class ConnectionPacketHandler {
|
||||
} else {
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug("ACK only packet received: " + packet);
|
||||
ackOnly = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fastAck = fastAck || ack(con, packet.getAckThrough(), packet.getNacks(), packet, isNew);
|
||||
|
||||
if (packet.isFlagSet(Packet.FLAG_SYNCHRONIZE) &&
|
||||
((packet.getSendStreamId() == null) ||
|
||||
DataHelper.eq(packet.getSendStreamId(), Packet.STREAM_ID_UNKNOWN) ) ) {
|
||||
// don't honor the ACK 0 in SYN packets received when the other side
|
||||
// has obviously not seen our messages
|
||||
} else {
|
||||
fastAck = fastAck || ack(con, packet.getAckThrough(), packet.getNacks(), packet, isNew);
|
||||
}
|
||||
con.eventOccurred();
|
||||
if (fastAck) {
|
||||
if (con.getLastSendTime() + 2000 < _context.clock().now()) {
|
||||
@ -140,6 +155,11 @@ public class ConnectionPacketHandler {
|
||||
con.ackImmediately();
|
||||
}
|
||||
}
|
||||
|
||||
if (ackOnly) {
|
||||
// non-ack message payloads are queued in the MessageInputStream
|
||||
_cache.release(packet.getPayload());
|
||||
}
|
||||
}
|
||||
|
||||
private boolean ack(Connection con, long ackThrough, long nacks[], Packet packet, boolean isNew) {
|
||||
|
@ -13,6 +13,7 @@ import java.util.Map;
|
||||
|
||||
import net.i2p.I2PAppContext;
|
||||
import net.i2p.data.ByteArray;
|
||||
import net.i2p.util.ByteCache;
|
||||
import net.i2p.util.Log;
|
||||
|
||||
/**
|
||||
@ -52,6 +53,7 @@ public class MessageInputStream extends InputStream {
|
||||
private int _readTimeout;
|
||||
private IOException _streamError;
|
||||
private long _readTotal;
|
||||
private ByteCache _cache;
|
||||
|
||||
private byte[] _oneByte = new byte[1];
|
||||
|
||||
@ -70,6 +72,7 @@ public class MessageInputStream extends InputStream {
|
||||
_dataLock = new Object();
|
||||
_closeReceived = false;
|
||||
_locallyClosed = false;
|
||||
_cache = ByteCache.getInstance(128, Packet.MAX_PAYLOAD_SIZE);
|
||||
}
|
||||
|
||||
/** What is the highest block ID we've completely received through? */
|
||||
@ -166,7 +169,7 @@ public class MessageInputStream extends InputStream {
|
||||
buf.append("Close received, ready bytes: ");
|
||||
long available = 0;
|
||||
for (int i = 0; i < _readyDataBlocks.size(); i++)
|
||||
available += ((ByteArray)_readyDataBlocks.get(i)).getData().length;
|
||||
available += ((ByteArray)_readyDataBlocks.get(i)).getValid();
|
||||
available -= _readyDataBlockIndex;
|
||||
buf.append(available);
|
||||
buf.append(" blocks: ").append(_readyDataBlocks.size());
|
||||
@ -178,8 +181,8 @@ public class MessageInputStream extends InputStream {
|
||||
ByteArray ba = (ByteArray)_notYetReadyBlocks.get(id);
|
||||
buf.append(id).append(" ");
|
||||
|
||||
if (ba.getData() != null)
|
||||
notAvailable += ba.getData().length;
|
||||
if (ba != null)
|
||||
notAvailable += ba.getValid();
|
||||
}
|
||||
|
||||
buf.append("not ready bytes: ").append(notAvailable);
|
||||
@ -198,10 +201,10 @@ public class MessageInputStream extends InputStream {
|
||||
*
|
||||
* @return true if this is a new packet, false if it is a dup
|
||||
*/
|
||||
public boolean messageReceived(long messageId, byte payload[]) {
|
||||
public boolean messageReceived(long messageId, ByteArray payload) {
|
||||
synchronized (_dataLock) {
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug("received " + messageId + " with " + payload.length);
|
||||
_log.debug("received " + messageId + " with " + payload.getValid());
|
||||
if (messageId <= _highestReadyBlockId) {
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug("ignoring dup message " + messageId);
|
||||
@ -212,17 +215,17 @@ public class MessageInputStream extends InputStream {
|
||||
_highestBlockId = messageId;
|
||||
|
||||
if (_highestReadyBlockId + 1 == messageId) {
|
||||
if (!_locallyClosed && payload.length > 0) {
|
||||
if (!_locallyClosed && payload.getValid() > 0) {
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug("accepting bytes as ready: " + payload.length);
|
||||
_readyDataBlocks.add(new ByteArray(payload));
|
||||
_log.debug("accepting bytes as ready: " + payload.getValid());
|
||||
_readyDataBlocks.add(payload);
|
||||
}
|
||||
_highestReadyBlockId = messageId;
|
||||
long cur = _highestReadyBlockId + 1;
|
||||
// now pull in any previously pending blocks
|
||||
while (_notYetReadyBlocks.containsKey(new Long(cur))) {
|
||||
ByteArray ba = (ByteArray)_notYetReadyBlocks.remove(new Long(cur));
|
||||
if ( (ba != null) && (ba.getData() != null) && (ba.getData().length > 0) ) {
|
||||
if ( (ba != null) && (ba.getData() != null) && (ba.getValid() > 0) ) {
|
||||
_readyDataBlocks.add(ba);
|
||||
}
|
||||
|
||||
@ -238,7 +241,7 @@ public class MessageInputStream extends InputStream {
|
||||
if (_locallyClosed) // dont need the payload, just the msgId in order
|
||||
_notYetReadyBlocks.put(new Long(messageId), new ByteArray(null));
|
||||
else
|
||||
_notYetReadyBlocks.put(new Long(messageId), new ByteArray(payload));
|
||||
_notYetReadyBlocks.put(new Long(messageId), payload);
|
||||
_dataLock.notifyAll();
|
||||
}
|
||||
}
|
||||
@ -324,21 +327,25 @@ public class MessageInputStream extends InputStream {
|
||||
} else {
|
||||
// either was already ready, or we wait()ed and it arrived
|
||||
ByteArray cur = (ByteArray)_readyDataBlocks.get(0);
|
||||
byte rv = cur.getData()[_readyDataBlockIndex];
|
||||
byte rv = cur.getData()[cur.getOffset()+_readyDataBlockIndex];
|
||||
_readyDataBlockIndex++;
|
||||
if (cur.getData().length <= _readyDataBlockIndex) {
|
||||
boolean removed = false;
|
||||
if (cur.getValid() <= _readyDataBlockIndex) {
|
||||
_readyDataBlockIndex = 0;
|
||||
_readyDataBlocks.remove(0);
|
||||
removed = true;
|
||||
}
|
||||
_readTotal++;
|
||||
target[offset + i] = rv; // rv < 0 ? rv + 256 : rv
|
||||
if ( (_readyDataBlockIndex <= 3) || (_readyDataBlockIndex >= cur.getData().length - 5) ) {
|
||||
if ( (_readyDataBlockIndex <= 3) || (_readyDataBlockIndex >= cur.getValid() - 5) ) {
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug("read(...," + offset+", " + length+ ")[" + i
|
||||
+ "] after ready data: readyDataBlockIndex=" + _readyDataBlockIndex
|
||||
+ " readyBlocks=" + _readyDataBlocks.size()
|
||||
+ " readTotal=" + _readTotal);
|
||||
}
|
||||
if (removed)
|
||||
_cache.release(cur);
|
||||
}
|
||||
} // for (int i = 0; i < length; i++) {
|
||||
} // synchronized (_dataLock)
|
||||
@ -357,9 +364,9 @@ public class MessageInputStream extends InputStream {
|
||||
for (int i = 0; i < _readyDataBlocks.size(); i++) {
|
||||
ByteArray cur = (ByteArray)_readyDataBlocks.get(i);
|
||||
if (i == 0)
|
||||
numBytes += cur.getData().length - _readyDataBlockIndex;
|
||||
numBytes += cur.getValid() - _readyDataBlockIndex;
|
||||
else
|
||||
numBytes += cur.getData().length;
|
||||
numBytes += cur.getValid();
|
||||
}
|
||||
}
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
@ -380,13 +387,13 @@ public class MessageInputStream extends InputStream {
|
||||
for (int i = 0; i < _readyDataBlocks.size(); i++) {
|
||||
ByteArray cur = (ByteArray)_readyDataBlocks.get(i);
|
||||
if (i == 0)
|
||||
numBytes += cur.getData().length - _readyDataBlockIndex;
|
||||
numBytes += cur.getValid() - _readyDataBlockIndex;
|
||||
else
|
||||
numBytes += cur.getData().length;
|
||||
numBytes += cur.getValid();
|
||||
}
|
||||
for (Iterator iter = _notYetReadyBlocks.values().iterator(); iter.hasNext(); ) {
|
||||
ByteArray cur = (ByteArray)iter.next();
|
||||
numBytes += cur.getData().length;
|
||||
numBytes += cur.getValid();
|
||||
}
|
||||
return numBytes;
|
||||
}
|
||||
@ -399,9 +406,9 @@ public class MessageInputStream extends InputStream {
|
||||
for (int i = 0; i < _readyDataBlocks.size(); i++) {
|
||||
ByteArray cur = (ByteArray)_readyDataBlocks.get(i);
|
||||
if (i == 0)
|
||||
numBytes += cur.getData().length - _readyDataBlockIndex;
|
||||
numBytes += cur.getValid() - _readyDataBlockIndex;
|
||||
else
|
||||
numBytes += cur.getData().length;
|
||||
numBytes += cur.getValid();
|
||||
}
|
||||
return numBytes;
|
||||
}
|
||||
@ -409,13 +416,15 @@ public class MessageInputStream extends InputStream {
|
||||
|
||||
public void close() {
|
||||
synchronized (_dataLock) {
|
||||
_readyDataBlocks.clear();
|
||||
while (_readyDataBlocks.size() > 0)
|
||||
_cache.release((ByteArray)_readyDataBlocks.remove(0));
|
||||
|
||||
// we don't need the data, but we do need to keep track of the messageIds
|
||||
// received, so we can ACK accordingly
|
||||
for (Iterator iter = _notYetReadyBlocks.values().iterator(); iter.hasNext(); ) {
|
||||
ByteArray ba = (ByteArray)iter.next();
|
||||
ba.setData(null);
|
||||
//ba.setData(null);
|
||||
_cache.release(ba);
|
||||
}
|
||||
_locallyClosed = true;
|
||||
_dataLock.notifyAll();
|
||||
|
@ -3,11 +3,13 @@ package net.i2p.client.streaming;
|
||||
import java.util.Arrays;
|
||||
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.Destination;
|
||||
import net.i2p.data.Signature;
|
||||
import net.i2p.data.SigningPrivateKey;
|
||||
import net.i2p.util.ByteCache;
|
||||
|
||||
/**
|
||||
* Contain a single packet transferred as part of a streaming connection.
|
||||
@ -56,12 +58,13 @@ public class Packet {
|
||||
private long _nacks[];
|
||||
private int _resendDelay;
|
||||
private int _flags;
|
||||
private byte _payload[];
|
||||
private ByteArray _payload;
|
||||
// the next four are set only if the flags say so
|
||||
private Signature _optionSignature;
|
||||
private Destination _optionFrom;
|
||||
private int _optionDelay;
|
||||
private int _optionMaxSize;
|
||||
private ByteCache _cache;
|
||||
|
||||
/**
|
||||
* The receiveStreamId will be set to this when the packet doesn't know
|
||||
@ -135,6 +138,10 @@ public class Packet {
|
||||
|
||||
public static final int DEFAULT_MAX_SIZE = 32*1024;
|
||||
private static final int MAX_DELAY_REQUEST = 65535;
|
||||
|
||||
public Packet() {
|
||||
_cache = ByteCache.getInstance(128, MAX_PAYLOAD_SIZE);
|
||||
}
|
||||
|
||||
/** what stream is this packet a part of? */
|
||||
public byte[] getSendStreamId() {
|
||||
@ -200,14 +207,14 @@ public class Packet {
|
||||
public static final int MAX_PAYLOAD_SIZE = 32*1024;
|
||||
|
||||
/** get the actual payload of the message. may be null */
|
||||
public byte[] getPayload() { return _payload; }
|
||||
public void setPayload(byte payload[]) {
|
||||
public ByteArray getPayload() { return _payload; }
|
||||
public void setPayload(ByteArray payload) {
|
||||
_payload = payload;
|
||||
if ( (payload != null) && (payload.length > MAX_PAYLOAD_SIZE) )
|
||||
throw new IllegalArgumentException("Too large payload: " + payload.length);
|
||||
if ( (payload != null) && (payload.getValid() > MAX_PAYLOAD_SIZE) )
|
||||
throw new IllegalArgumentException("Too large payload: " + payload.getValid());
|
||||
}
|
||||
public int getPayloadSize() {
|
||||
return (_payload == null ? 0 : _payload.length);
|
||||
return (_payload == null ? 0 : _payload.getValid());
|
||||
}
|
||||
|
||||
/** is a particular flag set on this packet? */
|
||||
@ -340,12 +347,12 @@ public class Packet {
|
||||
|
||||
if (_payload != null) {
|
||||
try {
|
||||
System.arraycopy(_payload, 0, buffer, cur, _payload.length);
|
||||
System.arraycopy(_payload.getData(), _payload.getOffset(), buffer, cur, _payload.getValid());
|
||||
} catch (ArrayIndexOutOfBoundsException aioobe) {
|
||||
System.err.println("payload.length: " + _payload.length + " buffer.length: " + buffer.length + " cur: " + cur);
|
||||
System.err.println("payload.length: " + _payload.getValid() + " buffer.length: " + buffer.length + " cur: " + cur);
|
||||
throw aioobe;
|
||||
}
|
||||
cur += _payload.length;
|
||||
cur += _payload.getValid();
|
||||
}
|
||||
|
||||
return cur - offset;
|
||||
@ -382,7 +389,7 @@ public class Packet {
|
||||
size += 2; // option size
|
||||
|
||||
if (_payload != null) {
|
||||
size += _payload.length;
|
||||
size += _payload.getValid();
|
||||
}
|
||||
|
||||
return size;
|
||||
@ -445,8 +452,10 @@ public class Packet {
|
||||
throw new IllegalArgumentException("length: " + length + " offset: " + offset + " begin: " + payloadBegin);
|
||||
|
||||
// skip ahead to the payload
|
||||
_payload = new byte[payloadSize];
|
||||
System.arraycopy(buffer, payloadBegin, _payload, 0, payloadSize);
|
||||
_payload = _cache.acquire(); //new ByteArray(new byte[payloadSize]);
|
||||
System.arraycopy(buffer, payloadBegin, _payload.getData(), 0, payloadSize);
|
||||
_payload.setValid(payloadSize);
|
||||
_payload.setOffset(0);
|
||||
|
||||
// ok now lets go back and deal with the options
|
||||
if (isFlagSet(FLAG_DELAY_REQUESTED)) {
|
||||
@ -545,8 +554,8 @@ public class Packet {
|
||||
buf.append(" ").append(_nacks[i]);
|
||||
}
|
||||
}
|
||||
if ( (_payload != null) && (_payload.length > 0) )
|
||||
buf.append(" data: ").append(_payload.length);
|
||||
if ( (_payload != null) && (_payload.getValid() > 0) )
|
||||
buf.append(" data: ").append(_payload.getValid());
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
|
@ -3,8 +3,10 @@ package net.i2p.client.streaming;
|
||||
import java.util.Set;
|
||||
|
||||
import net.i2p.I2PAppContext;
|
||||
import net.i2p.data.ByteArray;
|
||||
import net.i2p.data.Destination;
|
||||
import net.i2p.data.SessionKey;
|
||||
import net.i2p.util.ByteCache;
|
||||
import net.i2p.util.Log;
|
||||
import net.i2p.util.SimpleTimer;
|
||||
|
||||
@ -26,6 +28,7 @@ public class PacketLocal extends Packet implements MessageOutputStream.WriteStat
|
||||
private long _ackOn;
|
||||
private long _cancelledOn;
|
||||
private SimpleTimer.TimedEvent _resendEvent;
|
||||
private ByteCache _cache = ByteCache.getInstance(128, MAX_PAYLOAD_SIZE);
|
||||
|
||||
public PacketLocal(I2PAppContext ctx, Destination to) {
|
||||
this(ctx, to, null);
|
||||
@ -80,21 +83,31 @@ public class PacketLocal extends Packet implements MessageOutputStream.WriteStat
|
||||
_lastSend = _context.clock().now();
|
||||
}
|
||||
public void ackReceived() {
|
||||
ByteArray ba = null;
|
||||
synchronized (this) {
|
||||
if (_ackOn <= 0)
|
||||
_ackOn = _context.clock().now();
|
||||
ba = getPayload();
|
||||
setPayload(null);
|
||||
notifyAll();
|
||||
}
|
||||
SimpleTimer.getInstance().removeEvent(_resendEvent);
|
||||
if (ba != null)
|
||||
_cache.release(ba);
|
||||
}
|
||||
public void cancelled() {
|
||||
ByteArray ba = null;
|
||||
synchronized (this) {
|
||||
_cancelledOn = _context.clock().now();
|
||||
ba = getPayload();
|
||||
setPayload(null);
|
||||
notifyAll();
|
||||
}
|
||||
SimpleTimer.getInstance().removeEvent(_resendEvent);
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug("Cancelled! " + toString(), new Exception("cancelled"));
|
||||
if (ba != null)
|
||||
_cache.release(ba);
|
||||
}
|
||||
|
||||
/** how long after packet creation was it acked? */
|
||||
|
@ -25,6 +25,7 @@ class PacketQueue {
|
||||
private I2PSession _session;
|
||||
private ConnectionManager _connectionManager;
|
||||
private ByteCache _cache = ByteCache.getInstance(64, 36*1024);
|
||||
private ByteCache _packetCache = ByteCache.getInstance(128, Packet.MAX_PAYLOAD_SIZE);
|
||||
|
||||
public PacketQueue(I2PAppContext context, I2PSession session, ConnectionManager mgr) {
|
||||
_context = context;
|
||||
@ -125,6 +126,11 @@ class PacketQueue {
|
||||
String suffix = (c != null ? "wsize " + c.getOptions().getWindowSize() : null);
|
||||
_connectionManager.getPacketHandler().displayPacket(packet, "SEND", suffix);
|
||||
}
|
||||
|
||||
if ( (packet.getSequenceNum() == 0) && (!packet.isFlagSet(Packet.FLAG_SYNCHRONIZE)) ) {
|
||||
// ack only, so release it asap
|
||||
_packetCache.release(packet.getPayload());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -6,6 +6,7 @@ import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
|
||||
import net.i2p.I2PAppContext;
|
||||
import net.i2p.data.ByteArray;
|
||||
import net.i2p.data.DataHelper;
|
||||
import net.i2p.util.Log;
|
||||
|
||||
@ -29,7 +30,7 @@ public class MessageInputStreamTest {
|
||||
for (int i = 0; i < orig.length / 1024; i++) {
|
||||
byte msg[] = new byte[1024];
|
||||
System.arraycopy(orig, i*1024, msg, 0, 1024);
|
||||
in.messageReceived(i, msg);
|
||||
in.messageReceived(i, new ByteArray(msg));
|
||||
}
|
||||
|
||||
byte read[] = new byte[orig.length];
|
||||
@ -59,7 +60,7 @@ public class MessageInputStreamTest {
|
||||
byte msg[] = new byte[1024];
|
||||
Integer cur = (Integer)order.get(i);
|
||||
System.arraycopy(orig, cur.intValue()*1024, msg, 0, 1024);
|
||||
in.messageReceived(cur.intValue(), msg);
|
||||
in.messageReceived(cur.intValue(), new ByteArray(msg));
|
||||
_log.debug("Injecting " + cur);
|
||||
}
|
||||
|
||||
@ -91,7 +92,7 @@ public class MessageInputStreamTest {
|
||||
byte msg[] = new byte[1024];
|
||||
Integer cur = (Integer)order.get(i);
|
||||
System.arraycopy(orig, cur.intValue()*1024, msg, 0, 1024);
|
||||
in.messageReceived(cur.intValue(), msg);
|
||||
in.messageReceived(cur.intValue(), new ByteArray(msg));
|
||||
_log.debug("Injecting " + cur);
|
||||
}
|
||||
}
|
||||
@ -126,7 +127,7 @@ public class MessageInputStreamTest {
|
||||
byte msg[] = new byte[1024];
|
||||
Integer cur = (Integer)order.get(i);
|
||||
System.arraycopy(orig, cur.intValue()*1024, msg, 0, 1024);
|
||||
in.messageReceived(cur.intValue(), msg);
|
||||
in.messageReceived(cur.intValue(), new ByteArray(msg));
|
||||
_log.debug("Injecting " + cur);
|
||||
|
||||
try {
|
||||
|
Reference in New Issue
Block a user