diff --git a/apps/streaming/java/src/net/i2p/client/streaming/ConnectionHandler.java b/apps/streaming/java/src/net/i2p/client/streaming/ConnectionHandler.java index 30d849ba4..d989a2367 100644 --- a/apps/streaming/java/src/net/i2p/client/streaming/ConnectionHandler.java +++ b/apps/streaming/java/src/net/i2p/client/streaming/ConnectionHandler.java @@ -171,7 +171,9 @@ class ConnectionHandler { // Send it through the packet handler again if (_log.shouldLog(Log.WARN)) _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 { // goodbye if (_log.shouldLog(Log.WARN)) diff --git a/apps/streaming/java/src/net/i2p/client/streaming/PacketHandler.java b/apps/streaming/java/src/net/i2p/client/streaming/PacketHandler.java index 1f2b35902..1d26d7b8c 100644 --- a/apps/streaming/java/src/net/i2p/client/streaming/PacketHandler.java +++ b/apps/streaming/java/src/net/i2p/client/streaming/PacketHandler.java @@ -90,10 +90,10 @@ public class PacketHandler { void receivePacket(Packet packet) { //boolean ok = choke(packet); //if (ok) - receivePacketDirect(packet); + receivePacketDirect(packet, true); } - private void receivePacketDirect(Packet packet) { + void receivePacketDirect(Packet packet, boolean queueIfNoConn) { //if (_log.shouldLog(Log.DEBUG)) // _log.debug("packet received: " + packet); @@ -105,7 +105,7 @@ public class PacketHandler { if (_log.shouldLog(Log.INFO)) displayPacket(packet, "RECV", "wsize " + con.getOptions().getWindowSize() + " rto " + con.getOptions().getRTO()); } else { - receiveUnknownCon(packet, sendId); + receiveUnknownCon(packet, sendId, queueIfNoConn); displayPacket(packet, "UNKN", null); } } @@ -228,7 +228,7 @@ public class PacketHandler { _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.getSendStreamId() > 0) { receivePing(packet); @@ -262,7 +262,7 @@ public class PacketHandler { if (packet.isFlagSet(Packet.FLAG_SYNCHRONIZE)) { _manager.getConnectionHandler().receiveNewSyn(packet); - } else { + } else if (queueIfNoConn) { // We can get here on the 2nd+ packet if the 1st (SYN) packet // is still on the _synQueue in the ConnectionHandler, and // ConnectionManager.receiveConnection() hasn't run yet to put @@ -287,6 +287,10 @@ public class PacketHandler { } //packet.releasePayload(); _manager.getConnectionHandler().receiveNewSyn(packet); + } else { + // don't queue again (infinite loop!) + sendReset(packet); + packet.releasePayload(); } } }