* Streaming:

- Fix infinite loop through the SYN queue caused by race,
        resulting in high CPU, OOMs, etc.
This commit is contained in:
zzz
2009-05-26 14:50:16 +00:00
parent 906482823c
commit 32dddac75b
2 changed files with 12 additions and 6 deletions

View File

@ -171,7 +171,9 @@ class ConnectionHandler {
// Send it through the packet handler again // Send it through the packet handler again
if (_log.shouldLog(Log.WARN)) if (_log.shouldLog(Log.WARN))
_log.warn("Found con for queued non-syn packet: " + packet); _log.warn("Found con for queued non-syn packet: " + packet);
_manager.getPacketHandler().receivePacket(packet); // false -> don't requeue, fixes a race where a SYN gets dropped
// between here and PacketHandler, causing the packet to loop forever....
_manager.getPacketHandler().receivePacketDirect(packet, false);
} else { } else {
// goodbye // goodbye
if (_log.shouldLog(Log.WARN)) if (_log.shouldLog(Log.WARN))

View File

@ -90,10 +90,10 @@ public class PacketHandler {
void receivePacket(Packet packet) { void receivePacket(Packet packet) {
//boolean ok = choke(packet); //boolean ok = choke(packet);
//if (ok) //if (ok)
receivePacketDirect(packet); receivePacketDirect(packet, true);
} }
private void receivePacketDirect(Packet packet) { void receivePacketDirect(Packet packet, boolean queueIfNoConn) {
//if (_log.shouldLog(Log.DEBUG)) //if (_log.shouldLog(Log.DEBUG))
// _log.debug("packet received: " + packet); // _log.debug("packet received: " + packet);
@ -105,7 +105,7 @@ public class PacketHandler {
if (_log.shouldLog(Log.INFO)) if (_log.shouldLog(Log.INFO))
displayPacket(packet, "RECV", "wsize " + con.getOptions().getWindowSize() + " rto " + con.getOptions().getRTO()); displayPacket(packet, "RECV", "wsize " + con.getOptions().getWindowSize() + " rto " + con.getOptions().getRTO());
} else { } else {
receiveUnknownCon(packet, sendId); receiveUnknownCon(packet, sendId, queueIfNoConn);
displayPacket(packet, "UNKN", null); displayPacket(packet, "UNKN", null);
} }
} }
@ -228,7 +228,7 @@ public class PacketHandler {
_manager.getPacketQueue().enqueue(reply); _manager.getPacketQueue().enqueue(reply);
} }
private void receiveUnknownCon(Packet packet, long sendId) { private void receiveUnknownCon(Packet packet, long sendId, boolean queueIfNoConn) {
if (packet.isFlagSet(Packet.FLAG_ECHO)) { if (packet.isFlagSet(Packet.FLAG_ECHO)) {
if (packet.getSendStreamId() > 0) { if (packet.getSendStreamId() > 0) {
receivePing(packet); receivePing(packet);
@ -262,7 +262,7 @@ public class PacketHandler {
if (packet.isFlagSet(Packet.FLAG_SYNCHRONIZE)) { if (packet.isFlagSet(Packet.FLAG_SYNCHRONIZE)) {
_manager.getConnectionHandler().receiveNewSyn(packet); _manager.getConnectionHandler().receiveNewSyn(packet);
} else { } else if (queueIfNoConn) {
// We can get here on the 2nd+ packet if the 1st (SYN) packet // We can get here on the 2nd+ packet if the 1st (SYN) packet
// is still on the _synQueue in the ConnectionHandler, and // is still on the _synQueue in the ConnectionHandler, and
// ConnectionManager.receiveConnection() hasn't run yet to put // ConnectionManager.receiveConnection() hasn't run yet to put
@ -287,6 +287,10 @@ public class PacketHandler {
} }
//packet.releasePayload(); //packet.releasePayload();
_manager.getConnectionHandler().receiveNewSyn(packet); _manager.getConnectionHandler().receiveNewSyn(packet);
} else {
// don't queue again (infinite loop!)
sendReset(packet);
packet.releasePayload();
} }
} }
} }