forked from I2P_Developers/i2p.i2p
SSU2: Track recently-closed sessions (gitlab #370)
and drop packets received on them, to prevent SSU1 fallback processing
This commit is contained in:
@@ -1,3 +1,6 @@
|
|||||||
|
2022-10-10 zzz
|
||||||
|
* SSU2: Track recently-closed sessions (gitlab #370)
|
||||||
|
|
||||||
2022-09-28 zzz
|
2022-09-28 zzz
|
||||||
* Installer: Fix error on Windows when username contains a space (gitlab #367)
|
* Installer: Fix error on Windows when username contains a space (gitlab #367)
|
||||||
* SSU2: Enable by default
|
* SSU2: Enable by default
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ public class RouterVersion {
|
|||||||
/** deprecated */
|
/** deprecated */
|
||||||
public final static String ID = "Git";
|
public final static String ID = "Git";
|
||||||
public final static String VERSION = CoreVersion.VERSION;
|
public final static String VERSION = CoreVersion.VERSION;
|
||||||
public final static long BUILD = 11;
|
public final static long BUILD = 12;
|
||||||
|
|
||||||
/** for example "-test" */
|
/** for example "-test" */
|
||||||
public final static String EXTRA = "";
|
public final static String EXTRA = "";
|
||||||
|
|||||||
@@ -359,11 +359,24 @@ class PacketHandler {
|
|||||||
// For now, try SSU2 Session/Token Request processing here.
|
// For now, try SSU2 Session/Token Request processing here.
|
||||||
// After we've migrated the majority of the network over to SSU2,
|
// After we've migrated the majority of the network over to SSU2,
|
||||||
// we can try SSU2 first.
|
// we can try SSU2 first.
|
||||||
if (_enableSSU2 && peerType == PeerType.NEW_PEER &&
|
if (_enableSSU2 && peerType == PeerType.NEW_PEER) {
|
||||||
packet.getPacket().getLength() >= SSU2Util.MIN_TOKEN_REQUEST_LEN) {
|
int len = packet.getPacket().getLength();
|
||||||
|
if (len >= SSU2Util.MIN_TOKEN_REQUEST_LEN) {
|
||||||
boolean handled = receiveSSU2Packet(remoteHost, packet, (InboundEstablishState2) null);
|
boolean handled = receiveSSU2Packet(remoteHost, packet, (InboundEstablishState2) null);
|
||||||
if (handled)
|
if (handled)
|
||||||
return;
|
return;
|
||||||
|
} else if (len >= SSU2Util.MIN_DATA_LEN) {
|
||||||
|
byte[] k1 = _transport.getSSU2StaticIntroKey();
|
||||||
|
long id = SSU2Header.decryptDestConnID(packet.getPacket(), k1);
|
||||||
|
if (_transport.wasRecentlyClosed(id)) {
|
||||||
|
// Probably termination ack.
|
||||||
|
// Prevent attempted SSU1 fallback processing and adding to fail cache
|
||||||
|
if (_log.shouldDebug())
|
||||||
|
_log.debug("Dropping " + len + " byte packet from " + remoteHost +
|
||||||
|
" for recently closed ID " + id);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
if (_log.shouldDebug())
|
if (_log.shouldDebug())
|
||||||
_log.debug("Continuing with SSU1 fallback processing, wasn't an SSU2 packet from " + remoteHost);
|
_log.debug("Continuing with SSU1 fallback processing, wasn't an SSU2 packet from " + remoteHost);
|
||||||
}
|
}
|
||||||
@@ -827,6 +840,14 @@ class PacketHandler {
|
|||||||
ps2.receivePacket(from, packet);
|
ps2.receivePacket(from, packet);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
if (_transport.wasRecentlyClosed(id)) {
|
||||||
|
// Probably termination ack.
|
||||||
|
// Prevent attempted SSU1 fallback processing and adding to fail cache
|
||||||
|
if (_log.shouldDebug())
|
||||||
|
_log.debug("Dropping " + packet.getPacket().getLength() + " byte packet from " + from +
|
||||||
|
" for recently closed ID " + id);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -57,6 +57,7 @@ import net.i2p.router.util.EventLog;
|
|||||||
import net.i2p.router.util.RandomIterator;
|
import net.i2p.router.util.RandomIterator;
|
||||||
import net.i2p.util.Addresses;
|
import net.i2p.util.Addresses;
|
||||||
import net.i2p.util.ConcurrentHashSet;
|
import net.i2p.util.ConcurrentHashSet;
|
||||||
|
import net.i2p.util.LHMCache;
|
||||||
import net.i2p.util.Log;
|
import net.i2p.util.Log;
|
||||||
import net.i2p.util.OrderedProperties;
|
import net.i2p.util.OrderedProperties;
|
||||||
import net.i2p.util.SimpleTimer;
|
import net.i2p.util.SimpleTimer;
|
||||||
@@ -76,6 +77,7 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority
|
|||||||
/** RemoteHostId to PeerState */
|
/** RemoteHostId to PeerState */
|
||||||
private final Map<RemoteHostId, PeerState> _peersByRemoteHost;
|
private final Map<RemoteHostId, PeerState> _peersByRemoteHost;
|
||||||
private final Map<Long, PeerState2> _peersByConnID;
|
private final Map<Long, PeerState2> _peersByConnID;
|
||||||
|
private final Map<Long, Object> _recentlyClosedConnIDs;
|
||||||
private PacketHandler _handler;
|
private PacketHandler _handler;
|
||||||
private EstablishmentManager _establisher;
|
private EstablishmentManager _establisher;
|
||||||
private final MessageQueue _outboundMessages;
|
private final MessageQueue _outboundMessages;
|
||||||
@@ -166,6 +168,7 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority
|
|||||||
private static final int DROPLIST_PERIOD = 10*60*1000;
|
private static final int DROPLIST_PERIOD = 10*60*1000;
|
||||||
public static final String STYLE = "SSU";
|
public static final String STYLE = "SSU";
|
||||||
public static final String PROP_INTERNAL_PORT = "i2np.udp.internalPort";
|
public static final String PROP_INTERNAL_PORT = "i2np.udp.internalPort";
|
||||||
|
private static final Object DUMMY = Integer.valueOf(0);
|
||||||
|
|
||||||
/** now unused, we pick a random port
|
/** now unused, we pick a random port
|
||||||
* @deprecated unused
|
* @deprecated unused
|
||||||
@@ -338,6 +341,7 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority
|
|||||||
_peersByIdent = new ConcurrentHashMap<Hash, PeerState>(128);
|
_peersByIdent = new ConcurrentHashMap<Hash, PeerState>(128);
|
||||||
_peersByRemoteHost = new ConcurrentHashMap<RemoteHostId, PeerState>(128);
|
_peersByRemoteHost = new ConcurrentHashMap<RemoteHostId, PeerState>(128);
|
||||||
_peersByConnID = (xdh != null) ? new ConcurrentHashMap<Long, PeerState2>(32) : null;
|
_peersByConnID = (xdh != null) ? new ConcurrentHashMap<Long, PeerState2>(32) : null;
|
||||||
|
_recentlyClosedConnIDs = (xdh != null) ? new LHMCache<Long, Object>(24) : null;
|
||||||
_dropList = new ConcurrentHashSet<RemoteHostId>(2);
|
_dropList = new ConcurrentHashSet<RemoteHostId>(2);
|
||||||
_endpoints = new CopyOnWriteArrayList<UDPEndpoint>();
|
_endpoints = new CopyOnWriteArrayList<UDPEndpoint>();
|
||||||
|
|
||||||
@@ -856,6 +860,11 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority
|
|||||||
_peersByIdent.clear();
|
_peersByIdent.clear();
|
||||||
if (_peersByConnID != null)
|
if (_peersByConnID != null)
|
||||||
_peersByConnID.clear();
|
_peersByConnID.clear();
|
||||||
|
if (_recentlyClosedConnIDs != null) {
|
||||||
|
synchronized(_addDropLock) {
|
||||||
|
_recentlyClosedConnIDs.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
_dropList.clear();
|
_dropList.clear();
|
||||||
_introManager.reset();
|
_introManager.reset();
|
||||||
UDPPacket.clearCache();
|
UDPPacket.clearCache();
|
||||||
@@ -1651,6 +1660,17 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority
|
|||||||
return _peersByConnID.get(Long.valueOf(rcvConnID));
|
return _peersByConnID.get(Long.valueOf(rcvConnID));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Was the state for this SSU2 receive connection ID recently closed?
|
||||||
|
* @since 0.9.56
|
||||||
|
*/
|
||||||
|
boolean wasRecentlyClosed(long rcvConnID) {
|
||||||
|
Long id = Long.valueOf(rcvConnID);
|
||||||
|
synchronized(_addDropLock) {
|
||||||
|
return _recentlyClosedConnIDs.get(id) != null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* For /peers UI only. Not a public API, not for external use.
|
* For /peers UI only. Not a public API, not for external use.
|
||||||
*
|
*
|
||||||
@@ -1824,7 +1844,9 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority
|
|||||||
}
|
}
|
||||||
if (oldPeer != peer && oldPeer.getVersion() == 2) {
|
if (oldPeer != peer && oldPeer.getVersion() == 2) {
|
||||||
PeerState2 state2 = (PeerState2) oldPeer;
|
PeerState2 state2 = (PeerState2) oldPeer;
|
||||||
_peersByConnID.remove(Long.valueOf(state2.getRcvConnID()));
|
Long id = Long.valueOf(state2.getRcvConnID());
|
||||||
|
_recentlyClosedConnIDs.put(id, DUMMY);
|
||||||
|
_peersByConnID.remove(id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2028,7 +2050,11 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority
|
|||||||
|
|
||||||
if (peer.getVersion() == 2) {
|
if (peer.getVersion() == 2) {
|
||||||
PeerState2 state2 = (PeerState2) peer;
|
PeerState2 state2 = (PeerState2) peer;
|
||||||
_peersByConnID.remove(Long.valueOf(state2.getRcvConnID()));
|
Long id = Long.valueOf(state2.getRcvConnID());
|
||||||
|
// for now, we don't save the PeerState2 for doing termination retransmissions,
|
||||||
|
// but we may in the future
|
||||||
|
_recentlyClosedConnIDs.put(id, DUMMY);
|
||||||
|
_peersByConnID.remove(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
RemoteHostId remoteId = peer.getRemoteHostId();
|
RemoteHostId remoteId = peer.getRemoteHostId();
|
||||||
|
|||||||
Reference in New Issue
Block a user