2004-11-02 jrandom
* Fixed up the configuration overrides for the streaming socket lib integration so that it properly honors env settings. * More memory usage streamlining (last major revamp for now, i promise)
This commit is contained in:
@ -4,6 +4,7 @@ import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.Iterator;
|
||||
import java.util.Properties;
|
||||
|
||||
import net.i2p.I2PAppContext;
|
||||
@ -81,6 +82,13 @@ public class I2PSocketManagerFactory {
|
||||
public static I2PSocketManager createManager(InputStream myPrivateKeyStream, String i2cpHost, int i2cpPort,
|
||||
Properties opts) {
|
||||
I2PClient client = I2PClientFactory.createClient();
|
||||
if (opts == null)
|
||||
opts = new Properties();
|
||||
for (Iterator iter = System.getProperties().keySet().iterator(); iter.hasNext(); ) {
|
||||
String name = (String)iter.next();
|
||||
if (!opts.containsKey(name))
|
||||
opts.setProperty(name, System.getProperty(name));
|
||||
}
|
||||
if (true) {
|
||||
// for the old streaming lib
|
||||
opts.setProperty(I2PClient.PROP_RELIABILITY, I2PClient.PROP_RELIABILITY_GUARANTEED);
|
||||
@ -88,11 +96,12 @@ public class I2PSocketManagerFactory {
|
||||
} else {
|
||||
// for new streaming lib:
|
||||
opts.setProperty(I2PClient.PROP_RELIABILITY, I2PClient.PROP_RELIABILITY_BEST_EFFORT);
|
||||
//opts.setProperty("tunnels.depthInbound", "0");
|
||||
//p.setProperty("tunnels.depthInbound", "0");
|
||||
}
|
||||
|
||||
opts.setProperty(I2PClient.PROP_TCP_HOST, i2cpHost);
|
||||
opts.setProperty(I2PClient.PROP_TCP_PORT, "" + i2cpPort);
|
||||
|
||||
try {
|
||||
I2PSession session = client.createSession(myPrivateKeyStream, opts);
|
||||
session.connect();
|
||||
|
@ -3,6 +3,7 @@ package net.i2p.client.streaming;
|
||||
import java.util.Arrays;
|
||||
import net.i2p.I2PAppContext;
|
||||
import net.i2p.data.Base64;
|
||||
import net.i2p.data.DataFormatException;
|
||||
import net.i2p.data.DataHelper;
|
||||
import net.i2p.data.Destination;
|
||||
import net.i2p.data.Signature;
|
||||
@ -439,7 +440,11 @@ public class Packet {
|
||||
}
|
||||
if (isFlagSet(FLAG_FROM_INCLUDED)) {
|
||||
_optionFrom = new Destination();
|
||||
cur += _optionFrom.readBytes(buffer, cur);
|
||||
try {
|
||||
cur += _optionFrom.readBytes(buffer, cur);
|
||||
} catch (DataFormatException dfe) {
|
||||
throw new IllegalArgumentException("Bad from field: " + dfe.getMessage());
|
||||
}
|
||||
}
|
||||
if (isFlagSet(FLAG_MAX_PACKET_SIZE_INCLUDED)) {
|
||||
_optionMaxSize = (int)DataHelper.fromLong(buffer, cur, 2);
|
||||
|
@ -104,13 +104,21 @@ public class Certificate extends DataStructureImpl {
|
||||
return cur - offset;
|
||||
}
|
||||
|
||||
public int readBytes(byte source[], int offset) {
|
||||
public int readBytes(byte source[], int offset) throws DataFormatException {
|
||||
if (source == null) throw new DataFormatException("Cert is null");
|
||||
if (source.length <= offset + 3)
|
||||
throw new DataFormatException("Cert is too small [" + source.length + " off=" + offset + "]");
|
||||
|
||||
int cur = offset;
|
||||
_type = (int)DataHelper.fromLong(source, cur, 1);
|
||||
cur++;
|
||||
int length = (int)DataHelper.fromLong(source, cur, 2);
|
||||
cur += 2;
|
||||
if (length > 0) {
|
||||
if (length + cur > source.length)
|
||||
throw new DataFormatException("Payload on the certificate is insufficient (len="
|
||||
+ source.length + " off=" + offset + " cur=" + cur
|
||||
+ " payloadLen=" + length);
|
||||
_payload = new byte[length];
|
||||
System.arraycopy(source, cur, _payload, 0, length);
|
||||
cur += length;
|
||||
|
@ -10,6 +10,7 @@ package net.i2p.data;
|
||||
*/
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
@ -255,8 +256,9 @@ public class DataHelper {
|
||||
public static void writeLong(OutputStream rawStream, int numBytes, long value)
|
||||
throws DataFormatException, IOException {
|
||||
try {
|
||||
UnsignedInteger i = new UnsignedInteger(value);
|
||||
rawStream.write(i.getBytes(numBytes));
|
||||
UnsignedInteger.writeBytes(rawStream, numBytes, value);
|
||||
//UnsignedInteger i = new UnsignedInteger(value);
|
||||
//rawStream.write(i.getBytes(numBytes));
|
||||
} catch (IllegalArgumentException iae) {
|
||||
throw new DataFormatException("Invalid value (must be positive)", iae);
|
||||
}
|
||||
@ -340,7 +342,7 @@ public class DataHelper {
|
||||
|
||||
return new Date(date);
|
||||
}
|
||||
|
||||
|
||||
/** Write out a date to the stream as specified by the I2P data structure spec.
|
||||
* @param out stream to write to
|
||||
* @param date date to write (can be null)
|
||||
@ -360,12 +362,18 @@ public class DataHelper {
|
||||
else
|
||||
return toLong(DATE_LENGTH, date.getTime());
|
||||
}
|
||||
public static Date fromDate(byte src[], int offset) throws IllegalArgumentException {
|
||||
long when = fromLong(src, offset, DATE_LENGTH);
|
||||
if (when <= 0)
|
||||
return null;
|
||||
else
|
||||
return new Date(when);
|
||||
public static Date fromDate(byte src[], int offset) throws DataFormatException {
|
||||
if ( (src == null) || (offset + DATE_LENGTH > src.length) )
|
||||
throw new DataFormatException("Not enough data to read a date");
|
||||
try {
|
||||
long when = fromLong(src, offset, DATE_LENGTH);
|
||||
if (when <= 0)
|
||||
return null;
|
||||
else
|
||||
return new Date(when);
|
||||
} catch (IllegalArgumentException iae) {
|
||||
throw new DataFormatException(iae.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public static final int DATE_LENGTH = 8;
|
||||
|
@ -90,7 +90,10 @@ public class Destination extends DataStructureImpl {
|
||||
return cur - offset;
|
||||
}
|
||||
|
||||
public int readBytes(byte source[], int offset) {
|
||||
public int readBytes(byte source[], int offset) throws DataFormatException {
|
||||
if (source == null) throw new DataFormatException("Null source");
|
||||
if (source.length <= offset + PublicKey.KEYSIZE_BYTES + SigningPublicKey.KEYSIZE_BYTES)
|
||||
throw new DataFormatException("Not enough data (len=" + source.length + " off=" + offset + ")");
|
||||
int cur = offset;
|
||||
|
||||
_publicKey = new PublicKey();
|
||||
|
@ -378,7 +378,11 @@ public class RouterInfo extends DataStructureImpl {
|
||||
public synchronized void readBytes(InputStream in) throws DataFormatException, IOException {
|
||||
_identity = new RouterIdentity();
|
||||
_identity.readBytes(in);
|
||||
_published = DataHelper.readDate(in).getTime();
|
||||
Date when = DataHelper.readDate(in);
|
||||
if (when == null)
|
||||
_published = 0;
|
||||
else
|
||||
_published = when.getTime();
|
||||
int numAddresses = (int) DataHelper.readLong(in, 1);
|
||||
for (int i = 0; i < numAddresses; i++) {
|
||||
RouterAddress address = new RouterAddress();
|
||||
@ -402,7 +406,7 @@ public class RouterInfo extends DataStructureImpl {
|
||||
|
||||
public synchronized void writeBytes(OutputStream out) throws DataFormatException, IOException {
|
||||
if (_identity == null) throw new DataFormatException("Missing identity");
|
||||
if (_published <= 0) throw new DataFormatException("Invalid published date: " + _published);
|
||||
if (_published < 0) throw new DataFormatException("Invalid published date: " + _published);
|
||||
if (_signature == null) throw new DataFormatException("Signature is null");
|
||||
//if (!isValid())
|
||||
// throw new DataFormatException("Data is not valid");
|
||||
|
@ -9,6 +9,8 @@ package net.i2p.data;
|
||||
*
|
||||
*/
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.math.BigInteger;
|
||||
|
||||
import net.i2p.util.Log;
|
||||
@ -189,6 +191,16 @@ public class UnsignedInteger {
|
||||
System.arraycopy(_data, 0, data, numBytes - _data.length, _data.length);
|
||||
return data;
|
||||
}
|
||||
|
||||
|
||||
public static void writeBytes(OutputStream rawStream, int numBytes, long value)
|
||||
throws DataFormatException, IOException {
|
||||
if (value < 0) throw new DataFormatException("Invalid value (" + value + ")");
|
||||
for (int i = numBytes - 1; i >= 0; i--) {
|
||||
byte cur = (byte)( (value >>> (i*8) ) & 0xFF);
|
||||
rawStream.write(cur);
|
||||
}
|
||||
}
|
||||
|
||||
public BigInteger getBigInteger() {
|
||||
return new BigInteger(1, _data);
|
||||
@ -238,6 +250,7 @@ public class UnsignedInteger {
|
||||
testNum(1024 * 1024 * 1024 * 4L + 1L);
|
||||
_log.debug("Testing MaxLong");
|
||||
testNum(Long.MAX_VALUE);
|
||||
testWrite();
|
||||
} catch (Throwable t) { t.printStackTrace(); }
|
||||
try {
|
||||
Thread.sleep(1000);
|
||||
@ -260,4 +273,18 @@ public class UnsignedInteger {
|
||||
BigInteger tbi = new BigInteger(1, calculateBytes(num));
|
||||
_log.debug(num + " As a shifted : 0x" + tbi.toString(16));
|
||||
}
|
||||
|
||||
private static void testWrite() throws Exception {
|
||||
java.io.ByteArrayOutputStream baos = new java.io.ByteArrayOutputStream(8);
|
||||
UnsignedInteger i = new UnsignedInteger(12345);
|
||||
baos.write(i.getBytes(8));
|
||||
byte v1[] = baos.toByteArray();
|
||||
baos.reset();
|
||||
UnsignedInteger.writeBytes(baos, 8, 12345);
|
||||
byte v2[] = baos.toByteArray();
|
||||
System.out.println("v1 len: " + v1.length + " v2 len: " + v2.length);
|
||||
System.out.println("v1: " + DataHelper.toHexString(v1));
|
||||
System.out.println("v2: " + DataHelper.toHexString(v2));
|
||||
|
||||
}
|
||||
}
|
@ -1,4 +1,9 @@
|
||||
$Id: history.txt,v 1.59 2004/10/30 18:44:01 jrandom Exp $
|
||||
$Id: history.txt,v 1.60 2004/11/01 08:31:31 jrandom Exp $
|
||||
|
||||
2004-11-02 jrandom
|
||||
* Fixed up the configuration overrides for the streaming socket lib
|
||||
integration so that it properly honors env settings.
|
||||
* More memory usage streamlining (last major revamp for now, i promise)
|
||||
|
||||
2004-11-01 jrandom
|
||||
* Increase the tunnel test timeout rapidly if our tunnels are failing.
|
||||
|
@ -48,7 +48,11 @@ public class DeliveryStatusMessage extends I2NPMessageImpl {
|
||||
|
||||
_id = DataHelper.fromLong(data, curIndex, 4);
|
||||
curIndex += 4;
|
||||
_arrival = DataHelper.fromDate(data, curIndex);
|
||||
try {
|
||||
_arrival = DataHelper.fromDate(data, curIndex);
|
||||
} catch (DataFormatException dfe) {
|
||||
throw new I2NPMessageException("Unable to read the arrival");
|
||||
}
|
||||
}
|
||||
|
||||
/** calculate the message body's length (not including the header and footer */
|
||||
|
@ -77,6 +77,34 @@ public class GarlicClove extends DataStructureImpl {
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug("Read cert: " + _certificate);
|
||||
}
|
||||
|
||||
public int readBytes(byte source[], int offset) throws DataFormatException {
|
||||
int cur = offset;
|
||||
_instructions = new DeliveryInstructions();
|
||||
cur += _instructions.readBytes(source, cur);
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug("Read instructions: " + _instructions);
|
||||
try {
|
||||
cur += _handler.readMessage(source, cur);
|
||||
_msg = _handler.lastRead();
|
||||
} catch (I2NPMessageException ime) {
|
||||
throw new DataFormatException("Unable to read the message from a garlic clove", ime);
|
||||
} catch (IOException ioe) {
|
||||
throw new DataFormatException("Not enough data to read the clove", ioe);
|
||||
}
|
||||
_cloveId = DataHelper.fromLong(source, cur, 4);
|
||||
cur += 4;
|
||||
_expiration = DataHelper.fromDate(source, cur);
|
||||
cur += DataHelper.DATE_LENGTH;
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug("CloveID read: " + _cloveId + " expiration read: " + _expiration);
|
||||
_certificate = new Certificate();
|
||||
cur += _certificate.readBytes(source, cur);
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug("Read cert: " + _certificate);
|
||||
return cur - offset;
|
||||
}
|
||||
|
||||
|
||||
public void writeBytes(OutputStream out) throws DataFormatException, IOException {
|
||||
StringBuffer error = new StringBuffer();
|
||||
|
@ -95,30 +95,36 @@ public abstract class I2NPMessageImpl extends DataStructureImpl implements I2NPM
|
||||
}
|
||||
}
|
||||
public int readBytes(byte data[], int type, int offset) throws I2NPMessageException, IOException {
|
||||
int cur = offset;
|
||||
if (type < 0) {
|
||||
type = (int)DataHelper.fromLong(data, offset, 1);
|
||||
offset++;
|
||||
type = (int)DataHelper.fromLong(data, cur, 1);
|
||||
cur++;
|
||||
}
|
||||
_uniqueId = DataHelper.fromLong(data, offset, 4);
|
||||
offset += 4;
|
||||
_expiration = DataHelper.fromDate(data, offset);
|
||||
offset += DataHelper.DATE_LENGTH;
|
||||
int size = (int)DataHelper.fromLong(data, offset, 2);
|
||||
offset += 2;
|
||||
_uniqueId = DataHelper.fromLong(data, cur, 4);
|
||||
cur += 4;
|
||||
try {
|
||||
_expiration = DataHelper.fromDate(data, cur);
|
||||
cur += DataHelper.DATE_LENGTH;
|
||||
} catch (DataFormatException dfe) {
|
||||
throw new I2NPMessageException("Unable to read the expiration", dfe);
|
||||
}
|
||||
int size = (int)DataHelper.fromLong(data, cur, 2);
|
||||
cur += 2;
|
||||
Hash h = new Hash();
|
||||
byte hdata[] = new byte[Hash.HASH_LENGTH];
|
||||
System.arraycopy(data, offset, hdata, 0, Hash.HASH_LENGTH);
|
||||
offset += Hash.HASH_LENGTH;
|
||||
System.arraycopy(data, cur, hdata, 0, Hash.HASH_LENGTH);
|
||||
cur += Hash.HASH_LENGTH;
|
||||
h.setData(hdata);
|
||||
|
||||
if (offset + size > data.length)
|
||||
if (cur + size > data.length)
|
||||
throw new I2NPMessageException("Payload is too short ["
|
||||
+ "data.len=" + data.length
|
||||
+ " offset=" + offset
|
||||
+ " offset=" + offset
|
||||
+ " cur=" + cur
|
||||
+ " wanted=" + size + "]");
|
||||
|
||||
SHA256EntryCache.CacheEntry cache = _context.sha().cache().acquire(size);
|
||||
Hash calc = _context.sha().calculateHash(data, offset, size, cache);
|
||||
Hash calc = _context.sha().calculateHash(data, cur, size, cache);
|
||||
boolean eq = calc.equals(h);
|
||||
_context.sha().cache().release(cache);
|
||||
if (!eq)
|
||||
@ -127,11 +133,12 @@ public abstract class I2NPMessageImpl extends DataStructureImpl implements I2NPM
|
||||
long start = _context.clock().now();
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug("Reading bytes: type = " + type + " / uniqueId : " + _uniqueId + " / expiration : " + _expiration);
|
||||
readMessage(data, offset, size, type);
|
||||
readMessage(data, cur, size, type);
|
||||
cur += size;
|
||||
long time = _context.clock().now() - start;
|
||||
if (time > 50)
|
||||
_context.statManager().addRateData("i2np.readTime", time, time);
|
||||
return size + Hash.HASH_LENGTH + 1 + 4 + DataHelper.DATE_LENGTH;
|
||||
return cur - offset;
|
||||
}
|
||||
|
||||
public void writeBytes(OutputStream out) throws DataFormatException, IOException {
|
||||
|
@ -15,9 +15,9 @@ import net.i2p.CoreVersion;
|
||||
*
|
||||
*/
|
||||
public class RouterVersion {
|
||||
public final static String ID = "$Revision: 1.65 $ $Date: 2004/10/30 18:44:01 $";
|
||||
public final static String ID = "$Revision: 1.66 $ $Date: 2004/11/01 08:31:30 $";
|
||||
public final static String VERSION = "0.4.1.3";
|
||||
public final static long BUILD = 6;
|
||||
public final static long BUILD = 7;
|
||||
public static void main(String args[]) {
|
||||
System.out.println("I2P Router version: " + VERSION);
|
||||
System.out.println("Router ID: " + RouterVersion.ID);
|
||||
|
@ -40,57 +40,57 @@ public class GarlicMessageParser {
|
||||
byte encData[] = message.getData();
|
||||
byte decrData[] = null;
|
||||
try {
|
||||
_log.debug("Decrypting with private key " + encryptionKey);
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug("Decrypting with private key " + encryptionKey);
|
||||
decrData = _context.elGamalAESEngine().decrypt(encData, encryptionKey);
|
||||
} catch (DataFormatException dfe) {
|
||||
_log.warn("Error decrypting", dfe);
|
||||
if (_log.shouldLog(Log.WARN))
|
||||
_log.warn("Error decrypting", dfe);
|
||||
}
|
||||
if (decrData == null) {
|
||||
if (_log.shouldLog(Log.WARN))
|
||||
_log.warn("Decryption of garlic message failed (data = " + encData + ")", new Exception("Decrypt fail"));
|
||||
return null;
|
||||
} else {
|
||||
return readCloveSet(decrData);
|
||||
try {
|
||||
return readCloveSet(decrData);
|
||||
} catch (DataFormatException dfe) {
|
||||
if (_log.shouldLog(Log.WARN))
|
||||
_log.warn("Unable to read cloveSet", dfe);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private CloveSet readCloveSet(byte data[]) {
|
||||
private CloveSet readCloveSet(byte data[]) throws DataFormatException {
|
||||
Set cloves = new HashSet();
|
||||
ByteArrayInputStream bais = new ByteArrayInputStream(data);
|
||||
try {
|
||||
CloveSet set = new CloveSet();
|
||||
|
||||
int numCloves = (int)DataHelper.readLong(bais, 1);
|
||||
int offset = 0;
|
||||
|
||||
CloveSet set = new CloveSet();
|
||||
|
||||
int numCloves = (int)DataHelper.fromLong(data, offset, 1);
|
||||
offset++;
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug("# cloves to read: " + numCloves);
|
||||
for (int i = 0; i < numCloves; i++) {
|
||||
for (int i = 0; i < numCloves; i++) {
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug("Reading clove " + i);
|
||||
try {
|
||||
GarlicClove clove = new GarlicClove(_context);
|
||||
clove.readBytes(bais);
|
||||
set.addClove(clove);
|
||||
} catch (DataFormatException dfe) {
|
||||
_log.warn("Unable to read clove " + i, dfe);
|
||||
} catch (IOException ioe) {
|
||||
_log.warn("Unable to read clove " + i, ioe);
|
||||
}
|
||||
GarlicClove clove = new GarlicClove(_context);
|
||||
offset += clove.readBytes(data, offset);
|
||||
set.addClove(clove);
|
||||
if (_log.shouldLog(Log.WARN))
|
||||
_log.debug("After reading clove " + i);
|
||||
}
|
||||
Certificate cert = new Certificate();
|
||||
cert.readBytes(bais);
|
||||
long msgId = DataHelper.readLong(bais, 4);
|
||||
Date expiration = DataHelper.readDate(bais);
|
||||
|
||||
set.setCertificate(cert);
|
||||
set.setMessageId(msgId);
|
||||
set.setExpiration(expiration.getTime());
|
||||
|
||||
return set;
|
||||
} catch (IOException ioe) {
|
||||
_log.error("Error reading clove set", ioe);
|
||||
return null;
|
||||
} catch (DataFormatException dfe) {
|
||||
_log.error("Error reading clove set", dfe);
|
||||
return null;
|
||||
}
|
||||
Certificate cert = new Certificate();
|
||||
offset += cert.readBytes(data, offset);
|
||||
long msgId = DataHelper.fromLong(data, offset, 4);
|
||||
offset += 4;
|
||||
Date expiration = DataHelper.fromDate(data, offset);
|
||||
offset += DataHelper.DATE_LENGTH;
|
||||
|
||||
set.setCertificate(cert);
|
||||
set.setMessageId(msgId);
|
||||
set.setExpiration(expiration.getTime());
|
||||
return set;
|
||||
}
|
||||
}
|
||||
|
@ -132,21 +132,24 @@ public class HandleGarlicMessageJob extends JobImpl {
|
||||
|
||||
private boolean isValid(GarlicClove clove) {
|
||||
if (isKnown(clove.getCloveId())) {
|
||||
_log.error("Duplicate garlic clove received - replay attack in progress? [cloveId = "
|
||||
+ clove.getCloveId() + " expiration = " + clove.getExpiration());
|
||||
if (_log.shouldLog(Log.ERROR))
|
||||
_log.error("Duplicate garlic clove received - replay attack in progress? [cloveId = "
|
||||
+ clove.getCloveId() + " expiration = " + clove.getExpiration());
|
||||
return false;
|
||||
} else {
|
||||
_log.debug("Clove " + clove.getCloveId() + " expiring on " + clove.getExpiration()
|
||||
+ " is not known");
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug("Clove " + clove.getCloveId() + " expiring on " + clove.getExpiration()
|
||||
+ " is not known");
|
||||
}
|
||||
long now = getContext().clock().now();
|
||||
if (clove.getExpiration().getTime() < now) {
|
||||
if (clove.getExpiration().getTime() < now + Router.CLOCK_FUDGE_FACTOR) {
|
||||
_log.warn("Expired garlic received, but within our fudge factor ["
|
||||
+ clove.getExpiration() + "]");
|
||||
if (_log.shouldLog(Log.WARN))
|
||||
_log.warn("Expired garlic received, but within our fudge factor ["
|
||||
+ clove.getExpiration() + "]");
|
||||
} else {
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.error("Expired garlic clove received - replay attack in progress? [cloveId = "
|
||||
_log.debug("Expired garlic clove received - replay attack in progress? [cloveId = "
|
||||
+ clove.getCloveId() + " expiration = " + clove.getExpiration()
|
||||
+ " now = " + (new Date(getContext().clock().now())));
|
||||
return false;
|
||||
|
@ -76,7 +76,7 @@ public class OutboundMessageRegistry {
|
||||
long continueTime = 0;
|
||||
int numMessages = messages.size();
|
||||
|
||||
StringBuffer slow = new StringBuffer(256);
|
||||
StringBuffer slow = null; // new StringBuffer(256);
|
||||
long afterSync1 = _context.clock().now();
|
||||
|
||||
ArrayList matchedRemove = null; // new ArrayList(32);
|
||||
@ -93,6 +93,7 @@ public class OutboundMessageRegistry {
|
||||
if (_log.shouldLog(Log.WARN))
|
||||
_log.warn("Matching with selector took too long (" + diff + "ms) : "
|
||||
+ selector.getClass().getName());
|
||||
if (slow == null) slow = new StringBuffer(256);
|
||||
slow.append(selector.getClass().getName()).append(": ");
|
||||
slow.append(diff).append(" ");
|
||||
}
|
||||
@ -152,7 +153,9 @@ public class OutboundMessageRegistry {
|
||||
buf.append(0);
|
||||
else
|
||||
buf.append(matchedRemove.size());
|
||||
buf.append(" removed, ").append(matches.size()).append(" matches: slow = ").append(slow.toString());
|
||||
buf.append(" removed, ").append(matches.size()).append(" matches: slow = ");
|
||||
if (slow != null)
|
||||
buf.append(slow.toString());
|
||||
_log.log(level, buf.toString());
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user