I2P Address: [http://git.idk.i2p]

Skip to content
Snippets Groups Projects
Unverified Commit e71ba76d authored by zzz's avatar zzz
Browse files

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
parent 4aa6d159
No related branches found
No related tags found
No related merge requests found
...@@ -304,9 +304,14 @@ class PacketBuilder2 { ...@@ -304,9 +304,14 @@ class PacketBuilder2 {
packet.setPriority(priority); packet.setPriority(priority);
if (fragments.isEmpty()) { if (fragments.isEmpty()) {
SSU2Bitfield acked = peer.getAckedMessages(); SSU2Bitfield acked = peer.getAckedMessages();
if (acked != null) // null for PeerStateDestroyed if (acked != null) { // null for PeerStateDestroyed
acked.set(pktNum); // not ack-eliciting 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.markType(1);
packet.setFragmentCount(-1); packet.setFragmentCount(-1);
packet.setMessageType(TYPE_ACK); packet.setMessageType(TYPE_ACK);
...@@ -340,7 +345,11 @@ class PacketBuilder2 { ...@@ -340,7 +345,11 @@ class PacketBuilder2 {
encryptDataPacket(packet, peer.getSendCipher(), pktNum, peer.getSendHeaderEncryptKey1(), peer.getSendHeaderEncryptKey2()); encryptDataPacket(packet, peer.getSendCipher(), pktNum, peer.getSendHeaderEncryptKey1(), peer.getSendHeaderEncryptKey2());
setTo(packet, peer.getRemoteIPAddress(), peer.getRemotePort()); setTo(packet, peer.getRemoteIPAddress(), peer.getRemotePort());
packet.setPriority(PRIORITY_LOW); 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; return packet;
} }
......
...@@ -216,6 +216,14 @@ public class PeerState2 extends PeerState implements SSU2Payload.PayloadCallback ...@@ -216,6 +216,14 @@ public class PeerState2 extends PeerState implements SSU2Payload.PayloadCallback
if (now >= _sentMessagesLastExpired + SENT_MESSAGES_CLEAN_TIME) { if (now >= _sentMessagesLastExpired + SENT_MESSAGES_CLEAN_TIME) {
_sentMessagesLastExpired = now; _sentMessagesLastExpired = now;
if (!_sentMessages.isEmpty()) { 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()) if (_log.shouldDebug())
_log.debug("finishMessages() over " + _sentMessages.size() + " pending acks"); _log.debug("finishMessages() over " + _sentMessages.size() + " pending acks");
loop: loop:
...@@ -227,8 +235,8 @@ public class PeerState2 extends PeerState implements SSU2Payload.PayloadCallback ...@@ -227,8 +235,8 @@ public class PeerState2 extends PeerState implements SSU2Payload.PayloadCallback
continue loop; continue loop;
} }
iter.remove(); iter.remove();
if (_log.shouldWarn()) if (_log.shouldInfo())
_log.warn("Cleaned from sentMessages: " + frags); _log.info("Cleaned from sentMessages: " + frags);
} }
} }
} }
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment