diff --git a/core/java/src/net/i2p/data/DataHelper.java b/core/java/src/net/i2p/data/DataHelper.java index 26a2cadfa7..af8b64cb6a 100644 --- a/core/java/src/net/i2p/data/DataHelper.java +++ b/core/java/src/net/i2p/data/DataHelper.java @@ -68,9 +68,9 @@ public class DataHelper { "cost", "host", "port", // SSU RouterAddress options "key", "mtu", - "ihost0", "iport0", "ikey0", "itag0", - "ihost1", "iport1", "ikey1", "itag1", - "ihost2", "iport2", "ikey2", "itag2", + "ihost0", "iport0", "ikey0", "itag0", "iexp0", + "ihost1", "iport1", "ikey1", "itag1", "iexp1", + "ihost2", "iport2", "ikey2", "itag2", "iexp2", // RouterInfo options "caps", "coreVersion", "netId", "router.version", "netdb.knownLeaseSets", "netdb.knownRouters", diff --git a/router/java/src/net/i2p/router/transport/udp/PacketBuilder.java b/router/java/src/net/i2p/router/transport/udp/PacketBuilder.java index 6c49e78ea9..efa408187c 100644 --- a/router/java/src/net/i2p/router/transport/udp/PacketBuilder.java +++ b/router/java/src/net/i2p/router/transport/udp/PacketBuilder.java @@ -1215,17 +1215,20 @@ class PacketBuilder { UDPAddress addr = state.getRemoteAddress(); int count = addr.getIntroducerCount(); List rv = new ArrayList(count); + long cutoff = _context.clock().now() + 5*60*1000L; for (int i = 0; i < count; i++) { InetAddress iaddr = addr.getIntroducerHost(i); int iport = addr.getIntroducerPort(i); byte ikey[] = addr.getIntroducerKey(i); long tag = addr.getIntroducerTag(i); + long exp = addr.getIntroducerExpiration(i); // let's not use an introducer on a privileged port, sounds like trouble if (ikey == null || !TransportUtil.isValidPort(iport) || iaddr == null || tag <= 0 || // must be IPv4 for now as we don't send Alice IP/port, see below iaddr.getAddress().length != 4 || (!_transport.isValid(iaddr.getAddress())) || + (exp > 0 && exp < cutoff) || (Arrays.equals(iaddr.getAddress(), _transport.getExternalIP()) && !_transport.allowLocal())) { if (_log.shouldLog(Log.WARN)) _log.warn("Cannot build a relay request to " + state.getRemoteIdentity().calculateHash() diff --git a/router/java/src/net/i2p/router/transport/udp/UDPTransport.java b/router/java/src/net/i2p/router/transport/udp/UDPTransport.java index e65cadd2a9..7df9246425 100644 --- a/router/java/src/net/i2p/router/transport/udp/UDPTransport.java +++ b/router/java/src/net/i2p/router/transport/udp/UDPTransport.java @@ -203,6 +203,7 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority private static final int MIN_PEERS_IF_HAVE_V6 = 30; /** minimum peers volunteering to be introducers if we need that */ private static final int MIN_INTRODUCER_POOL = 5; + private static final long INTRODUCER_EXPIRATION_MARGIN = 20*60*1000L; private static final int[] BID_VALUES = { 15, 20, 50, 65, 80, 95, 100, 115, TransportBid.TRANSIENT_FAIL }; private static final int FAST_PREFERRED_BID = 0; @@ -1558,17 +1559,21 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority RouterAddress addr = getCurrentAddress(false); if (introducersRequired()) { UDPAddress ua = new UDPAddress(addr); + long now = _context.clock().now(); int valid = 0; for (int i = 0; i < ua.getIntroducerCount(); i++) { // warning: this is only valid as long as we use the ident hash as their key. byte[] key = ua.getIntroducerKey(i); if (key.length != Hash.HASH_LENGTH) continue; + long exp = ua.getIntroducerExpiration(i); + if (exp > 0 && exp < now + INTRODUCER_EXPIRATION_MARGIN) + continue; PeerState peer = getPeerState(new Hash(key)); if (peer != null) valid++; } - long sinceSelected = _context.clock().now() - _introducersSelectedOn; + long sinceSelected = now - _introducersSelectedOn; if (valid >= PUBLIC_RELAY_COUNT) { // try to shift 'em around every 10 minutes or so if (sinceSelected > 17*60*1000) {