forked from I2P_Developers/i2p.i2p
2005-07-19 jrandom
* Further preparation for removing I2CP crypto * Added some validation to the DH key agreement (thanks $anon) * Validate tunnel data message expirations (though not really a problem, since tunnels expire) * Minor PRNG threading cleanup
This commit is contained in:
@ -54,8 +54,7 @@ public class DeliveryStatusMessage extends I2NPMessageImpl {
|
||||
protected int writeMessageBody(byte out[], int curIndex) throws I2NPMessageException {
|
||||
if ( (_id < 0) || (_arrival <= 0) ) throw new I2NPMessageException("Not enough data to write out");
|
||||
|
||||
byte id[] = DataHelper.toLong(4, _id);
|
||||
System.arraycopy(id, 0, out, curIndex, 4);
|
||||
DataHelper.toLong(out, curIndex, 4, _id);
|
||||
curIndex += 4;
|
||||
DataHelper.toLong(out, curIndex, DataHelper.DATE_LENGTH, _arrival);
|
||||
curIndex += DataHelper.DATE_LENGTH;
|
||||
|
@ -51,6 +51,7 @@ public interface I2NPMessage extends DataStructure {
|
||||
* @throws IOException if there is a problem reading from the stream
|
||||
*/
|
||||
public void readMessage(byte data[], int offset, int dataSize, int type) throws I2NPMessageException, IOException;
|
||||
public void readMessage(byte data[], int offset, int dataSize, int type, I2NPMessageHandler handler) throws I2NPMessageException, IOException;
|
||||
|
||||
/**
|
||||
* Return the unique identifier for this type of I2NP message, as defined in
|
||||
|
@ -268,7 +268,16 @@ public abstract class I2NPMessageImpl extends DataStructureImpl implements I2NPM
|
||||
}
|
||||
}
|
||||
|
||||
public void readMessage(byte data[], int offset, int dataSize, int type, I2NPMessageHandler handler) throws I2NPMessageException, IOException {
|
||||
// ignore the handler (overridden in subclasses if necessary
|
||||
readMessage(data, offset, dataSize, type);
|
||||
}
|
||||
|
||||
|
||||
public static I2NPMessage fromRawByteArray(I2PAppContext ctx, byte buffer[], int offset, int len) throws I2NPMessageException {
|
||||
return fromRawByteArray(ctx, buffer, offset, len, new I2NPMessageHandler(ctx));
|
||||
}
|
||||
public static I2NPMessage fromRawByteArray(I2PAppContext ctx, byte buffer[], int offset, int len, I2NPMessageHandler handler) throws I2NPMessageException {
|
||||
int type = (int)DataHelper.fromLong(buffer, offset, 1);
|
||||
offset++;
|
||||
I2NPMessage msg = createMessage(ctx, type);
|
||||
@ -287,7 +296,7 @@ public abstract class I2NPMessageImpl extends DataStructureImpl implements I2NPM
|
||||
offset += 4;
|
||||
int dataSize = len - 1 - 4;
|
||||
try {
|
||||
msg.readMessage(buffer, offset, dataSize, type);
|
||||
msg.readMessage(buffer, offset, dataSize, type, handler);
|
||||
msg.setMessageExpiration(expiration);
|
||||
return msg;
|
||||
} catch (IOException ioe) {
|
||||
|
@ -81,6 +81,10 @@ public class TunnelGatewayMessage extends I2NPMessageImpl {
|
||||
|
||||
|
||||
public void readMessage(byte data[], int offset, int dataSize, int type) throws I2NPMessageException, IOException {
|
||||
I2NPMessageHandler h = new I2NPMessageHandler(_context);
|
||||
readMessage(data, offset, dataSize, type, h);
|
||||
}
|
||||
public void readMessage(byte data[], int offset, int dataSize, int type, I2NPMessageHandler handler) throws I2NPMessageException, IOException {
|
||||
if (type != MESSAGE_TYPE) throw new I2NPMessageException("Message type is incorrect for this message");
|
||||
int curIndex = offset;
|
||||
|
||||
@ -92,9 +96,8 @@ public class TunnelGatewayMessage extends I2NPMessageImpl {
|
||||
|
||||
int size = (int)DataHelper.fromLong(data, curIndex, 2);
|
||||
curIndex += 2;
|
||||
I2NPMessageHandler h = new I2NPMessageHandler(_context);
|
||||
curIndex = h.readMessage(data, curIndex);
|
||||
_msg = h.lastRead();
|
||||
curIndex = handler.readMessage(data, curIndex);
|
||||
_msg = handler.lastRead();
|
||||
if (_msg == null)
|
||||
throw new I2NPMessageException("wtf, message read has no payload?");
|
||||
}
|
||||
|
@ -113,30 +113,35 @@ public class InNetMessagePool implements Service {
|
||||
// _context.statManager().getStatLog().addData(fromRouterHash.toBase64().substring(0,6), "udp.floodDataReceived", 1, 0);
|
||||
// return 0;
|
||||
//}
|
||||
|
||||
String invalidReason = null;
|
||||
if (messageBody instanceof TunnelDataMessage) {
|
||||
// do not validate the message with the validator - the IV validator is sufficient
|
||||
} else {
|
||||
String invalidReason = _context.messageValidator().validateMessage(messageBody.getUniqueId(), exp);
|
||||
if (invalidReason != null) {
|
||||
int level = Log.WARN;
|
||||
if (messageBody instanceof TunnelCreateMessage)
|
||||
level = Log.INFO;
|
||||
if (_log.shouldLog(level))
|
||||
_log.log(level, "Duplicate message received [" + messageBody.getUniqueId()
|
||||
+ " expiring on " + exp + "]: " + messageBody.getClass().getName() + ": " + invalidReason
|
||||
+ ": " + messageBody);
|
||||
_context.statManager().addRateData("inNetPool.dropped", 1, 0);
|
||||
_context.statManager().addRateData("inNetPool.duplicate", 1, 0);
|
||||
_context.messageHistory().droppedOtherMessage(messageBody);
|
||||
_context.messageHistory().messageProcessingError(messageBody.getUniqueId(),
|
||||
messageBody.getClass().getName(),
|
||||
"Duplicate/expired");
|
||||
return -1;
|
||||
} else {
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug("Message received [" + messageBody.getUniqueId()
|
||||
+ " expiring on " + exp + "] is NOT a duplicate or exipired");
|
||||
}
|
||||
// the IV validator is sufficient for dup detection on tunnel messages, so
|
||||
// just validate the expiration
|
||||
invalidReason = _context.messageValidator().validateMessage(exp);
|
||||
} else {
|
||||
invalidReason = _context.messageValidator().validateMessage(messageBody.getUniqueId(), exp);
|
||||
}
|
||||
|
||||
if (invalidReason != null) {
|
||||
int level = Log.WARN;
|
||||
if (messageBody instanceof TunnelCreateMessage)
|
||||
level = Log.INFO;
|
||||
if (_log.shouldLog(level))
|
||||
_log.log(level, "Duplicate message received [" + messageBody.getUniqueId()
|
||||
+ " expiring on " + exp + "]: " + messageBody.getClass().getName() + ": " + invalidReason
|
||||
+ ": " + messageBody);
|
||||
_context.statManager().addRateData("inNetPool.dropped", 1, 0);
|
||||
_context.statManager().addRateData("inNetPool.duplicate", 1, 0);
|
||||
_context.messageHistory().droppedOtherMessage(messageBody);
|
||||
_context.messageHistory().messageProcessingError(messageBody.getUniqueId(),
|
||||
messageBody.getClass().getName(),
|
||||
"Duplicate/expired");
|
||||
return -1;
|
||||
} else {
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug("Message received [" + messageBody.getUniqueId()
|
||||
+ " expiring on " + exp + "] is NOT a duplicate or exipired");
|
||||
}
|
||||
|
||||
boolean jobFound = false;
|
||||
|
@ -443,13 +443,13 @@ public class MessageHistory {
|
||||
addEntry(buf.toString());
|
||||
}
|
||||
|
||||
public void receiveTunnelFragment(long messageId, int fragmentId, String status) {
|
||||
public void receiveTunnelFragment(long messageId, int fragmentId, Object status) {
|
||||
if (!_doLog) return;
|
||||
if (messageId == -1) throw new IllegalArgumentException("why are you -1?");
|
||||
StringBuffer buf = new StringBuffer(48);
|
||||
buf.append(getPrefix());
|
||||
buf.append("Receive fragment ").append(fragmentId).append(" in ").append(messageId);
|
||||
buf.append(" status: ").append(status);
|
||||
buf.append(" status: ").append(status.toString());
|
||||
addEntry(buf.toString());
|
||||
}
|
||||
public void receiveTunnelFragmentComplete(long messageId) {
|
||||
|
@ -34,18 +34,9 @@ public class MessageValidator {
|
||||
* @return reason why the message is invalid (or null if the message is valid)
|
||||
*/
|
||||
public String validateMessage(long messageId, long expiration) {
|
||||
long now = _context.clock().now();
|
||||
if (now - Router.CLOCK_FUDGE_FACTOR >= expiration) {
|
||||
if (_log.shouldLog(Log.WARN))
|
||||
_log.warn("Rejecting message " + messageId + " because it expired " + (now-expiration) + "ms ago");
|
||||
_context.statManager().addRateData("router.invalidMessageTime", (now-expiration), 0);
|
||||
return "expired " + (now-expiration) + "ms ago";
|
||||
} else if (now + 4*Router.CLOCK_FUDGE_FACTOR < expiration) {
|
||||
if (_log.shouldLog(Log.WARN))
|
||||
_log.warn("Rejecting message " + messageId + " because it will expire too far in the future (" + (expiration-now) + "ms)");
|
||||
_context.statManager().addRateData("router.invalidMessageTime", (now-expiration), 0);
|
||||
return "expire too far in the future (" + (expiration-now) + "ms)";
|
||||
}
|
||||
String msg = validateMessage(expiration);
|
||||
if (msg != null)
|
||||
return msg;
|
||||
|
||||
boolean isDuplicate = noteReception(messageId, expiration);
|
||||
if (isDuplicate) {
|
||||
@ -59,6 +50,24 @@ public class MessageValidator {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Only check the expiration for the message
|
||||
*/
|
||||
public String validateMessage(long expiration) {
|
||||
long now = _context.clock().now();
|
||||
if (now - Router.CLOCK_FUDGE_FACTOR >= expiration) {
|
||||
if (_log.shouldLog(Log.WARN))
|
||||
_log.warn("Rejecting message because it expired " + (now-expiration) + "ms ago");
|
||||
_context.statManager().addRateData("router.invalidMessageTime", (now-expiration), 0);
|
||||
return "expired " + (now-expiration) + "ms ago";
|
||||
} else if (now + 4*Router.CLOCK_FUDGE_FACTOR < expiration) {
|
||||
if (_log.shouldLog(Log.WARN))
|
||||
_log.warn("Rejecting message because it will expire too far in the future (" + (expiration-now) + "ms)");
|
||||
_context.statManager().addRateData("router.invalidMessageTime", (now-expiration), 0);
|
||||
return "expire too far in the future (" + (expiration-now) + "ms)";
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static final long TIME_MASK = 0xFFFFFC00;
|
||||
|
||||
|
@ -15,9 +15,9 @@ import net.i2p.CoreVersion;
|
||||
*
|
||||
*/
|
||||
public class RouterVersion {
|
||||
public final static String ID = "$Revision: 1.203 $ $Date: 2005/07/13 15:07:32 $";
|
||||
public final static String ID = "$Revision: 1.204 $ $Date: 2005/07/16 07:52:36 $";
|
||||
public final static String VERSION = "0.5.0.7";
|
||||
public final static long BUILD = 15;
|
||||
public final static long BUILD = 16;
|
||||
public static void main(String args[]) {
|
||||
System.out.println("I2P Router version: " + VERSION);
|
||||
System.out.println("Router ID: " + RouterVersion.ID);
|
||||
|
@ -100,6 +100,7 @@ public class CommSystemFacadeImpl extends CommSystemFacade {
|
||||
|
||||
private final static String PROP_I2NP_TCP_HOSTNAME = "i2np.tcp.hostname";
|
||||
private final static String PROP_I2NP_TCP_PORT = "i2np.tcp.port";
|
||||
private final static String PROP_I2NP_TCP_DISABLED = "i2np.tcp.disable";
|
||||
|
||||
private RouterAddress createTCPAddress() {
|
||||
RouterAddress addr = new RouterAddress();
|
||||
@ -108,6 +109,10 @@ public class CommSystemFacadeImpl extends CommSystemFacade {
|
||||
Properties props = new Properties();
|
||||
String name = _context.router().getConfigSetting(PROP_I2NP_TCP_HOSTNAME);
|
||||
String port = _context.router().getConfigSetting(PROP_I2NP_TCP_PORT);
|
||||
String disabledStr = _context.router().getConfigSetting(PROP_I2NP_TCP_DISABLED);
|
||||
boolean disabled = false;
|
||||
if ( (disabledStr != null) && ("true".equalsIgnoreCase(disabledStr)) )
|
||||
return null;
|
||||
if ( (name == null) || (port == null) ) {
|
||||
//_log.info("TCP Host/Port not specified in config file - skipping TCP transport");
|
||||
return null;
|
||||
|
@ -5,6 +5,7 @@ import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
|
||||
import net.i2p.crypto.DHSessionKeyBuilder;
|
||||
import net.i2p.data.RouterAddress;
|
||||
import net.i2p.data.RouterIdentity;
|
||||
import net.i2p.data.SessionKey;
|
||||
@ -286,7 +287,16 @@ public class EstablishmentManager {
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug("Send created to: " + state.getRemoteHostId().toString());
|
||||
|
||||
state.generateSessionKey();
|
||||
try {
|
||||
state.generateSessionKey();
|
||||
} catch (DHSessionKeyBuilder.InvalidPublicParameterException ippe) {
|
||||
if (_log.shouldLog(Log.ERROR))
|
||||
_log.error("Peer " + state.getRemoteHostId() + " sent us an invalid DH parameter (or were spoofed)", ippe);
|
||||
synchronized (_inboundStates) {
|
||||
_inboundStates.remove(state.getRemoteHostId());
|
||||
}
|
||||
return;
|
||||
}
|
||||
_transport.send(_builder.buildSessionCreatedPacket(state, _transport.getExternalPort(), _transport.getIntroKey()));
|
||||
// if they haven't advanced to sending us confirmed packets in 5s,
|
||||
// repeat
|
||||
|
@ -99,7 +99,7 @@ public class InboundEstablishState {
|
||||
public synchronized byte[] getReceivedX() { return _receivedX; }
|
||||
public synchronized byte[] getReceivedOurIP() { return _bobIP; }
|
||||
|
||||
public synchronized void generateSessionKey() {
|
||||
public synchronized void generateSessionKey() throws DHSessionKeyBuilder.InvalidPublicParameterException {
|
||||
if (_sessionKey != null) return;
|
||||
_keyBuilder = new DHSessionKeyBuilder();
|
||||
_keyBuilder.setPeerPublicValue(_receivedX);
|
||||
|
@ -9,6 +9,7 @@ import net.i2p.data.DataFormatException;
|
||||
import net.i2p.data.i2np.I2NPMessage;
|
||||
import net.i2p.data.i2np.I2NPMessageImpl;
|
||||
import net.i2p.data.i2np.I2NPMessageException;
|
||||
import net.i2p.data.i2np.I2NPMessageHandler;
|
||||
import net.i2p.router.RouterContext;
|
||||
import net.i2p.util.ByteCache;
|
||||
import net.i2p.util.I2PThread;
|
||||
@ -27,6 +28,7 @@ public class MessageReceiver implements Runnable {
|
||||
private List _completeMessages;
|
||||
private boolean _alive;
|
||||
private ByteCache _cache;
|
||||
private I2NPMessageHandler _handler;
|
||||
|
||||
public MessageReceiver(RouterContext ctx, UDPTransport transport) {
|
||||
_context = ctx;
|
||||
@ -34,6 +36,7 @@ public class MessageReceiver implements Runnable {
|
||||
_transport = transport;
|
||||
_completeMessages = new ArrayList(16);
|
||||
_cache = ByteCache.getInstance(64, I2NPMessage.MAX_SIZE);
|
||||
_handler = new I2NPMessageHandler(ctx);
|
||||
_alive = true;
|
||||
}
|
||||
|
||||
@ -60,6 +63,8 @@ public class MessageReceiver implements Runnable {
|
||||
|
||||
public void run() {
|
||||
InboundMessageState message = null;
|
||||
ByteArray buf = _cache.acquire();
|
||||
|
||||
while (_alive) {
|
||||
try {
|
||||
synchronized (_completeMessages) {
|
||||
@ -74,16 +79,18 @@ public class MessageReceiver implements Runnable {
|
||||
int size = message.getCompleteSize();
|
||||
if (_log.shouldLog(Log.INFO))
|
||||
_log.info("Full message received (" + message.getMessageId() + ") after " + message.getLifetime());
|
||||
I2NPMessage msg = readMessage(message);
|
||||
I2NPMessage msg = readMessage(buf, message);
|
||||
if (msg != null)
|
||||
_transport.messageReceived(msg, null, message.getFrom(), message.getLifetime(), size);
|
||||
message = null;
|
||||
}
|
||||
}
|
||||
|
||||
// no need to zero it out, as these buffers are only used with an explicit getCompleteSize
|
||||
_cache.release(buf, false);
|
||||
}
|
||||
|
||||
private I2NPMessage readMessage(InboundMessageState state) {
|
||||
ByteArray buf = _cache.acquire();
|
||||
private I2NPMessage readMessage(ByteArray buf, InboundMessageState state) {
|
||||
try {
|
||||
//byte buf[] = new byte[state.getCompleteSize()];
|
||||
ByteArray fragments[] = state.getFragments();
|
||||
@ -102,7 +109,7 @@ public class MessageReceiver implements Runnable {
|
||||
_log.error("Hmm, offset of the fragments = " + off + " while the state says " + state.getCompleteSize());
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug("Raw byte array for " + state.getMessageId() + ": " + Base64.encode(buf.getData(), 0, state.getCompleteSize()));
|
||||
I2NPMessage m = I2NPMessageImpl.fromRawByteArray(_context, buf.getData(), 0, state.getCompleteSize());
|
||||
I2NPMessage m = I2NPMessageImpl.fromRawByteArray(_context, buf.getData(), 0, state.getCompleteSize(), _handler);
|
||||
m.setUniqueId(state.getMessageId());
|
||||
return m;
|
||||
} catch (I2NPMessageException ime) {
|
||||
@ -114,7 +121,6 @@ public class MessageReceiver implements Runnable {
|
||||
return null;
|
||||
} finally {
|
||||
state.releaseResources();
|
||||
_cache.release(buf);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -163,10 +163,18 @@ public class OutboundEstablishState {
|
||||
return true;
|
||||
}
|
||||
|
||||
generateSessionKey();
|
||||
decryptSignature();
|
||||
boolean valid = true;
|
||||
try {
|
||||
generateSessionKey();
|
||||
} catch (DHSessionKeyBuilder.InvalidPublicParameterException ippe) {
|
||||
if (_log.shouldLog(Log.ERROR))
|
||||
_log.error("Peer " + getRemoteHostId() + " sent us an invalid DH parameter (or were spoofed)", ippe);
|
||||
valid = false;
|
||||
}
|
||||
if (valid)
|
||||
decryptSignature();
|
||||
|
||||
if (verifySessionCreated()) {
|
||||
if (valid && verifySessionCreated()) {
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug("Session created passed validation");
|
||||
return true;
|
||||
@ -191,7 +199,7 @@ public class OutboundEstablishState {
|
||||
}
|
||||
}
|
||||
|
||||
private void generateSessionKey() {
|
||||
private void generateSessionKey() throws DHSessionKeyBuilder.InvalidPublicParameterException {
|
||||
if (_sessionKey != null) return;
|
||||
_keyBuilder.setPeerPublicValue(_receivedY);
|
||||
_sessionKey = _keyBuilder.getSessionKey();
|
||||
|
@ -509,7 +509,8 @@ public class PeerState {
|
||||
synchronized (_currentACKs) {
|
||||
rv = new ArrayList(_currentACKs.size());
|
||||
while ( (bytesRemaining >= 4) && (_currentACKs.size() > 0) ) {
|
||||
rv.add(new FullACKBitfield((Long)_currentACKs.remove(0)));
|
||||
long id = ((Long)_currentACKs.remove(0)).longValue();
|
||||
rv.add(new FullACKBitfield(id));
|
||||
bytesRemaining -= 4;
|
||||
}
|
||||
if (_currentACKs.size() <= 0)
|
||||
@ -576,9 +577,9 @@ public class PeerState {
|
||||
}
|
||||
|
||||
/** represent a full ACK of a message */
|
||||
private class FullACKBitfield implements ACKBitfield {
|
||||
private static class FullACKBitfield implements ACKBitfield {
|
||||
private long _msgId;
|
||||
public FullACKBitfield(Long id) { _msgId = id.longValue(); }
|
||||
public FullACKBitfield(long id) { _msgId = id; }
|
||||
public int fragmentCount() { return 0; }
|
||||
public long getMessageId() { return _msgId; }
|
||||
public boolean received(int fragmentNum) { return true; }
|
||||
|
@ -310,9 +310,10 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority
|
||||
boolean addRemotePeerState(PeerState peer) {
|
||||
if (_log.shouldLog(Log.INFO))
|
||||
_log.info("Add remote peer state: " + peer);
|
||||
PeerState oldPeer = null;
|
||||
if (peer.getRemotePeer() != null) {
|
||||
synchronized (_peersByIdent) {
|
||||
PeerState oldPeer = (PeerState)_peersByIdent.put(peer.getRemotePeer(), peer);
|
||||
oldPeer = (PeerState)_peersByIdent.put(peer.getRemotePeer(), peer);
|
||||
if ( (oldPeer != null) && (oldPeer != peer) ) {
|
||||
// should we transfer the oldPeer's RTT/RTO/etc? nah
|
||||
// or perhaps reject the new session? nah,
|
||||
@ -321,17 +322,24 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority
|
||||
}
|
||||
}
|
||||
|
||||
if ( (oldPeer != null) && (_log.shouldLog(Log.WARN)) )
|
||||
_log.warn("Peer already connected: old=" + oldPeer + " new=" + peer, new Exception("dup"));
|
||||
oldPeer = null;
|
||||
|
||||
RemoteHostId remoteId = peer.getRemoteHostId();
|
||||
if (remoteId == null) return false;
|
||||
|
||||
synchronized (_peersByRemoteHost) {
|
||||
PeerState oldPeer = (PeerState)_peersByRemoteHost.put(remoteId, peer);
|
||||
oldPeer = (PeerState)_peersByRemoteHost.put(remoteId, peer);
|
||||
if ( (oldPeer != null) && (oldPeer != peer) ) {
|
||||
//_peersByRemoteHost.put(remoteString, oldPeer);
|
||||
//return false;
|
||||
}
|
||||
}
|
||||
|
||||
if ( (oldPeer != null) && (_log.shouldLog(Log.WARN)) )
|
||||
_log.warn("Peer already connected: old=" + oldPeer + " new=" + peer, new Exception("dup"));
|
||||
|
||||
_activeThrottle.unchoke(peer.getRemotePeer());
|
||||
_context.shitlist().unshitlistRouter(peer.getRemotePeer());
|
||||
|
||||
@ -348,7 +356,7 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority
|
||||
}
|
||||
private void dropPeer(PeerState peer, boolean shouldShitlist) {
|
||||
if (_log.shouldLog(Log.INFO))
|
||||
_log.info("Dropping remote peer: " + peer);
|
||||
_log.info("Dropping remote peer: " + peer + " shitlist? " + shouldShitlist, new Exception("Dropped by"));
|
||||
if (peer.getRemotePeer() != null) {
|
||||
if (shouldShitlist) {
|
||||
long now = _context.clock().now();
|
||||
|
@ -264,7 +264,7 @@ public class FragmentHandler {
|
||||
SimpleTimer.getInstance().removeEvent(msg.getExpireEvent());
|
||||
receiveComplete(msg);
|
||||
} else {
|
||||
noteReception(msg.getMessageId(), 0, msg.toString());
|
||||
noteReception(msg.getMessageId(), 0, msg);
|
||||
}
|
||||
|
||||
if (isNew && fragmented && !msg.isComplete()) {
|
||||
@ -326,7 +326,7 @@ public class FragmentHandler {
|
||||
_context.statManager().addRateData("tunnel.fragmentedComplete", msg.getFragmentCount(), msg.getLifetime());
|
||||
receiveComplete(msg);
|
||||
} else {
|
||||
noteReception(msg.getMessageId(), fragmentNum, msg.toString());
|
||||
noteReception(msg.getMessageId(), fragmentNum, msg);
|
||||
}
|
||||
|
||||
if (isNew && !msg.isComplete()) {
|
||||
@ -360,7 +360,7 @@ public class FragmentHandler {
|
||||
}
|
||||
}
|
||||
|
||||
protected void noteReception(long messageId, int fragmentId, String status) {}
|
||||
protected void noteReception(long messageId, int fragmentId, Object status) {}
|
||||
protected void noteCompletion(long messageId) {}
|
||||
protected void noteFailure(long messageId, String status) {}
|
||||
|
||||
|
@ -16,7 +16,7 @@ public class RouterFragmentHandler extends FragmentHandler {
|
||||
_log = context.logManager().getLog(RouterFragmentHandler.class);
|
||||
}
|
||||
|
||||
protected void noteReception(long messageId, int fragmentId, String status) {
|
||||
protected void noteReception(long messageId, int fragmentId, Object status) {
|
||||
if (_log.shouldLog(Log.INFO))
|
||||
_log.info("Received fragment " + fragmentId + " for message " + messageId + ": " + status);
|
||||
_routerContext.messageHistory().receiveTunnelFragment(messageId, fragmentId, status);
|
||||
|
Reference in New Issue
Block a user