forked from I2P_Developers/i2p.i2p
SSU2: Catch "shift too big" IAE from acked bitfield while sending termination
Add preliminary code to terminate session before there are too many unacked messages to cause the IAE (untested) log tweaks reported by drzed
This commit is contained in:
@@ -304,9 +304,14 @@ class PacketBuilder2 {
|
||||
|
||||
packet.setPriority(priority);
|
||||
if (fragments.isEmpty()) {
|
||||
SSU2Bitfield acked = peer.getAckedMessages();
|
||||
if (acked != null) // null for PeerStateDestroyed
|
||||
acked.set(pktNum); // not ack-eliciting
|
||||
SSU2Bitfield acked = peer.getAckedMessages();
|
||||
if (acked != null) { // null for PeerStateDestroyed
|
||||
try {
|
||||
acked.set(pktNum); // not ack-eliciting
|
||||
} catch (IndexOutOfBoundsException e) {
|
||||
// shift too big, ignore, we're dead or about to be
|
||||
}
|
||||
}
|
||||
packet.markType(1);
|
||||
packet.setFragmentCount(-1);
|
||||
packet.setMessageType(TYPE_ACK);
|
||||
@@ -340,7 +345,11 @@ class PacketBuilder2 {
|
||||
encryptDataPacket(packet, peer.getSendCipher(), pktNum, peer.getSendHeaderEncryptKey1(), peer.getSendHeaderEncryptKey2());
|
||||
setTo(packet, peer.getRemoteIPAddress(), peer.getRemotePort());
|
||||
packet.setPriority(PRIORITY_LOW);
|
||||
peer.getAckedMessages().set(pktNum); // not ack-eliciting
|
||||
try {
|
||||
peer.getAckedMessages().set(pktNum); // not ack-eliciting
|
||||
} catch (IndexOutOfBoundsException e) {
|
||||
// shift too big, ignore, we're dead or about to be
|
||||
}
|
||||
return packet;
|
||||
}
|
||||
|
||||
|
||||
@@ -216,6 +216,14 @@ public class PeerState2 extends PeerState implements SSU2Payload.PayloadCallback
|
||||
if (now >= _sentMessagesLastExpired + SENT_MESSAGES_CLEAN_TIME) {
|
||||
_sentMessagesLastExpired = now;
|
||||
if (!_sentMessages.isEmpty()) {
|
||||
// TODO is this the right place for this check?
|
||||
long ahead = _packetNumber.get() - _ackedMessages.getHighestSet();
|
||||
if (ahead > BITFIELD_SIZE) {
|
||||
if (_log.shouldWarn())
|
||||
_log.warn("Fail after " + ahead + "unacked packets on " + this);
|
||||
_transport.sendDestroy(this, REASON_FRAME_TIMEOUT);
|
||||
_transport.dropPeer(this, true, "Too many unacked packets");
|
||||
}
|
||||
if (_log.shouldDebug())
|
||||
_log.debug("finishMessages() over " + _sentMessages.size() + " pending acks");
|
||||
loop:
|
||||
@@ -227,8 +235,8 @@ public class PeerState2 extends PeerState implements SSU2Payload.PayloadCallback
|
||||
continue loop;
|
||||
}
|
||||
iter.remove();
|
||||
if (_log.shouldWarn())
|
||||
_log.warn("Cleaned from sentMessages: " + frags);
|
||||
if (_log.shouldInfo())
|
||||
_log.info("Cleaned from sentMessages: " + frags);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user