* Streaming:
- Fix infinite loop through the SYN queue caused by race, resulting in high CPU, OOMs, etc.
This commit is contained in:
@ -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))
|
||||||
|
@ -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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user