diff --git a/router/java/src/net/i2p/router/transport/udp/InboundEstablishState2.java b/router/java/src/net/i2p/router/transport/udp/InboundEstablishState2.java index 746d1e94e10419216e0c5fdee03c965b0ec466a8..0f262918c5addeb2d113efc720f5046e1618ae9e 100644 --- a/router/java/src/net/i2p/router/transport/udp/InboundEstablishState2.java +++ b/router/java/src/net/i2p/router/transport/udp/InboundEstablishState2.java @@ -54,7 +54,7 @@ class InboundEstablishState2 extends InboundEstablishState implements SSU2Payloa private PeerState2 _pstate; // testing - private static final boolean ENFORCE_TOKEN = false; + private static final boolean ENFORCE_TOKEN = true; private static final long MAX_SKEW = 2*60*1000L; diff --git a/router/java/src/net/i2p/router/transport/udp/OutboundMessageState.java b/router/java/src/net/i2p/router/transport/udp/OutboundMessageState.java index 8940f6606e7ddce7cea85e89c7e12e45669ea5fc..869af99900e20831e6f3eeb90279d4a1f59933fc 100644 --- a/router/java/src/net/i2p/router/transport/udp/OutboundMessageState.java +++ b/router/java/src/net/i2p/router/transport/udp/OutboundMessageState.java @@ -307,6 +307,9 @@ class OutboundMessageState implements CDPQEntry { return rv; } + /** + * @return true if the fragment has not been ACKed + */ public synchronized boolean needsSending(int fragment) { return (_fragmentAcks & mask(fragment)) != 0; } diff --git a/router/java/src/net/i2p/router/transport/udp/PeerState2.java b/router/java/src/net/i2p/router/transport/udp/PeerState2.java index 31fffcadf968bbcd2dcef71ab4fe3186e6fcddec..3533c98929bc1e1c5432e4e55e509f61f73d8e47 100644 --- a/router/java/src/net/i2p/router/transport/udp/PeerState2.java +++ b/router/java/src/net/i2p/router/transport/udp/PeerState2.java @@ -73,6 +73,7 @@ public class PeerState2 extends PeerState implements SSU2Payload.PayloadCallback public static final int MAX_MTU = 1500; public static final int DEFAULT_MTU = MAX_MTU; + private static final int BITFIELD_SIZE = 512; private static final int MAX_SESS_CONF_RETX = 6; private static final int SESS_CONF_RETX_TIME = 1000; @@ -94,8 +95,8 @@ public class PeerState2 extends PeerState implements SSU2Payload.PayloadCallback _rcvHeaderEncryptKey1 = transport.getSSU2StaticIntroKey(); _sendHeaderEncryptKey2 = sendHdrKey2; _rcvHeaderEncryptKey2 = rcvHdrKey2; - _receivedMessages = new SSU2Bitfield(256, 0); - _ackedMessages = new SSU2Bitfield(256, 0); + _receivedMessages = new SSU2Bitfield(BITFIELD_SIZE, 0); + _ackedMessages = new SSU2Bitfield(BITFIELD_SIZE, 0); _sentMessages = new ConcurrentHashMap<Long, List<PacketBuilder.Fragment>>(32); if (isInbound) { // Send immediate ack of Session Confirmed @@ -404,12 +405,9 @@ public class PeerState2 extends PeerState implements SSU2Payload.PayloadCallback public void gotACK(long ackThru, int acks, byte[] ranges) { SSU2Bitfield ackbf; - if (ranges != null) - ackbf = SSU2Bitfield.fromACKBlock(ackThru, acks, ranges, ranges.length / 2); - else - ackbf = SSU2Bitfield.fromACKBlock(ackThru, acks, null, 0); + ackbf = SSU2Bitfield.fromACKBlock(ackThru, acks, ranges, (ranges != null ? ranges.length / 2 : 0)); if (_log.shouldDebug()) - _log.debug("Got ACK block: " + ackbf); + _log.debug("Got ACK block: " + SSU2Bitfield.toString(ackThru, acks, ranges, (ranges != null ? ranges.length / 2 : 0))); // calls bitSet() below ackbf.forEachAndNot(_ackedMessages, this); } @@ -517,6 +515,12 @@ public class PeerState2 extends PeerState implements SSU2Payload.PayloadCallback continue; } int num = f.num; + if (!state.needsSending(num)) { + // will happen with retransmission as a different packet number + if (_log.shouldWarn()) + _log.warn("New ACK for fragment " + num + " but already acked? " + state); + continue; + } int ackedSize = state.getUnackedSize(); boolean complete = state.acked(f.num); if (complete) { @@ -596,17 +600,17 @@ public class PeerState2 extends PeerState implements SSU2Payload.PayloadCallback */ public void timeReached() { synchronized(PeerState2.this) { - long wanted = _wantACKSendSince; - if (wanted <= 0) { + if (_wantACKSendSince <= 0) { if (_log.shouldDebug()) _log.debug("Already acked:" + PeerState2.this); return; } - UDPPacket ack = _transport.getBuilder2().buildACK(PeerState2.this); - if (_log.shouldDebug()) - _log.debug("Sending acks to " + PeerState2.this); - _transport.send(ack); + _wantACKSendSince = 0; } + UDPPacket ack = _transport.getBuilder2().buildACK(PeerState2.this); + if (_log.shouldDebug()) + _log.debug("Sending acks to " + PeerState2.this); + _transport.send(ack); } } }