Skip to content

Commit

Permalink
Router: check in dash4 and dash5 for testing
Browse files Browse the repository at this point in the history
  • Loading branch information
eyedeekay committed May 2, 2024
1 parent 9ef2687 commit d5ec4cf
Show file tree
Hide file tree
Showing 8 changed files with 88 additions and 24 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import net.i2p.data.router.RouterKeyGenerator;
import net.i2p.router.CommSystemFacade.Status;
import net.i2p.router.JobImpl;
import net.i2p.router.Router;
import net.i2p.router.RouterContext;
import net.i2p.util.Log;
import net.i2p.util.SystemVersion;
Expand Down Expand Up @@ -75,6 +76,8 @@ private int expireKeys() {
RouterKeyGenerator gen = getContext().routerKeyGenerator();
long now = getContext().clock().now();
long cutoff = now - 30*60*1000;
// for U routers
long ucutoff = now - 15*60*1000;
boolean almostMidnight = gen.getTimeTillMidnight() < FloodfillNetworkDatabaseFacade.NEXT_RKEY_RI_ADVANCE_TIME - 30*60*1000;
Hash us = getContext().routerHash();
boolean isFF = _facade.floodfillEnabled();
Expand All @@ -99,7 +102,9 @@ private int expireKeys() {
continue;
if (count > LIMIT_ROUTERS) {
// aggressive drop strategy
if (e.getDate() < cutoff) {
long pub = e.getDate();
if (pub < cutoff ||
(pub < ucutoff && ((RouterInfo) e).getCapabilities().indexOf(Router.CAPABILITY_UNREACHABLE) >= 0)) {
if (isFF) {
// don't drop very close to us
byte[] rkey = gen.getRoutingKey(key).getData();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,6 @@ List<Hash> selectFloodfillParticipants(Hash key, int maxNumRouters, KBucketSet<H
// before we can do this. Old profiles get deleted.
//private static final long HEARD_AGE = 48*60*60*1000L;
private static final long HEARD_AGE = 60*60*1000L;
private static final long INSTALL_AGE = HEARD_AGE + (60*60*1000L);

/**
* See above for description
Expand Down Expand Up @@ -220,11 +219,11 @@ private List<Hash> selectFloodfillParticipantsIncludingUs(Hash key, int howMany,

int found = 0;
long now = _context.clock().now();
long installed = _context.getProperty("router.firstInstalled", 0L);
boolean enforceHeard = installed > 0 && (now - installed) > INSTALL_AGE;
boolean enforceHeard;

double maxFailRate = 0.95;
if (_context.router().getUptime() > 60*60*1000) {
enforceHeard = true;
RateStat rs = _context.statManager().getRate("peer.failedLookupRate");
if (rs != null) {
Rate r = rs.getRate(60*60*1000);
Expand All @@ -233,6 +232,9 @@ private List<Hash> selectFloodfillParticipantsIncludingUs(Hash key, int howMany,
maxFailRate = Math.min(0.95d, Math.max(0.20d, 1.25d * currentFailRate));
}
}
} else {
long down = _context.router().getEstimatedDowntime();
enforceHeard = down > 0 && down < 30*60*60*1000L;
}

// 5 == FNDF.MAX_TO_FLOOD + 1
Expand Down Expand Up @@ -281,7 +283,9 @@ private List<Hash> selectFloodfillParticipantsIncludingUs(Hash key, int howMany,
maxGoodRespTime = 2 * tunnelTestTime.getAverageValue();
}
if (prof != null) {
if (enforceHeard && prof.getFirstHeardAbout() > now - HEARD_AGE) {
if (enforceHeard &&
(prof.getLastHeardFrom() <= 0 ||
prof.getFirstHeardAbout() > now - HEARD_AGE)) {
if (_log.shouldLog(Log.DEBUG))
_log.debug("Bad (new): " + entry);
badff.add(entry);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,10 @@ else if (_fromHash.equals(key))
// actually new
int count = _facade.getDataStore().size();
if (count > LIMIT_ROUTERS) {
String caps = ri.getCapabilities();
boolean isU = caps.indexOf(Router.CAPABILITY_UNREACHABLE) >= 0;
boolean isFF = caps.indexOf(FloodfillNetworkDatabaseFacade.CAPABILITY_FLOODFILL) >= 0;
boolean notFrom = !key.equals(_fromHash);
if (_facade.floodfillEnabled()) {
// determine if they're "close enough"
// we will still ack and flood by setting wasNew = true even if we don't store locally
Expand All @@ -278,7 +282,11 @@ else if (_fromHash.equals(key))
if (until > FloodfillNetworkDatabaseFacade.NEXT_RKEY_RI_ADVANCE_TIME) {
// appx. 90% max drop rate so even just-reseeded new routers will make it eventually
int pdrop = Math.min(110, (128 * count / LIMIT_ROUTERS) - 128);
if (ri.getCapabilities().indexOf(Router.CAPABILITY_UNREACHABLE) >= 0)
if (isU)
pdrop *= 3;
if (isFF)
pdrop *= 3;
if (notFrom)
pdrop *= 3;
if (pdrop > 0 && (pdrop >= 128 || getContext().random().nextInt(128) < pdrop)) {
if (_log.shouldWarn())
Expand All @@ -299,7 +307,11 @@ else if (_fromHash.equals(key))
((rkey[1] ^ ourRKey[1]) & 0xff);
if (distance >= 256) {
int pdrop = Math.min(110, (128 * count / LIMIT_ROUTERS) - 128);
if (ri.getCapabilities().indexOf(Router.CAPABILITY_UNREACHABLE) >= 0)
if (isU)
pdrop *= 3;
if (isFF)
pdrop *= 3;
if (notFrom)
pdrop *= 3;
if (pdrop > 0 && (pdrop >= 128 || getContext().random().nextInt(128) < pdrop)) {
if (_log.shouldWarn())
Expand All @@ -322,7 +334,11 @@ else if (_fromHash.equals(key))
// non-ff
// up to 100% drop rate
int pdrop = (128 * count / LIMIT_ROUTERS) - 128;
if (ri.getCapabilities().indexOf(Router.CAPABILITY_UNREACHABLE) >= 0)
if (isU)
pdrop *= 3;
if (isFF)
pdrop *= 3;
if (notFrom)
pdrop *= 3;
if (pdrop > 0 && (pdrop >= 128 || getContext().random().nextInt(128) < pdrop)) {
if (_log.shouldWarn())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1302,7 +1302,7 @@ String validate(RouterInfo routerInfo) throws IllegalArgumentException {
if (existing >= MIN_REMAINING_ROUTERS) {
if (_log.shouldLog(Log.INFO))
_log.info("Expired RI " + routerInfo.getIdentity().getHash(), new Exception());
return "Peer expired " + DataHelper.formatDuration(age) + " ago";
return "RI expired " + DataHelper.formatDuration(age) + " ago";
} else {
if (_log.shouldLog(Log.WARN))
_log.warn("Even though the peer is old, we have only " + existing
Expand All @@ -1313,35 +1313,42 @@ String validate(RouterInfo routerInfo) throws IllegalArgumentException {
if (age < 0 - 2*Router.CLOCK_FUDGE_FACTOR) {
String skewString = DataHelper.formatDuration(0 - age);
if (_log.shouldLog(Log.INFO))
_log.info("Peer " + routerInfo.getIdentity().getHash() + " published their routerInfo in the future?! ["
_log.info("RI " + routerInfo.getIdentity().getHash() + " published in the future?! ["
+ skewString + ']', new Exception());
if (upLongEnough && _context.commSystem().countActivePeers() >= 50) {
// we can be fairly confident that his clock is in the future,
// not that ours is in the past, so ban him for a while
_context.banlist().banlistRouter(routerInfo.getHash(), "Excessive clock skew: {0}", skewString, null, now + 60*60*1000);
}
return "Peer published " + skewString + " in the future?!";
return "RI published " + skewString + " in the future?!";
}
if (!routerInfo.isCurrent(ROUTER_INFO_EXPIRATION_INTRODUCED)) {
if (routerInfo.getAddresses().isEmpty())
return "Old peer with no addresses";
return "Old RI with no addresses";
// This should cover the introducers case below too
// And even better, catches the case where the router is unreachable but knows no introducers
if (routerInfo.getCapabilities().indexOf(Router.CAPABILITY_UNREACHABLE) >= 0)
return "Old peer and thinks it is unreachable";
return "Old RI and thinks it is unreachable";
// Just check all the addresses, faster than getting just the SSU ones
for (RouterAddress ra : routerInfo.getAddresses()) {
// Introducers change often, introducee will ping introducer for 2 hours
if (ra.getOption("itag0") != null)
return "Old peer with SSU Introducers";
return "Old RI with SSU Introducers";
}
}
if (upLongEnough && age > 2*24*60*60*1000l) {
return "Peer published " + DataHelper.formatDuration(age) + " ago";
return "RI published " + DataHelper.formatDuration(age) + " ago";
}
if (upLongEnough && !routerInfo.isCurrent(ROUTER_INFO_EXPIRATION_SHORT)) {
if (routerInfo.getTargetAddresses("NTCP", "NTCP2").isEmpty())
return "Peer published > 75m ago, SSU only without introducers";
return "RI published > 75m ago, SSU only without introducers";
}
for (RouterAddress ra : routerInfo.getTargetAddresses("NTCP2")) {
String i = ra.getOption("i");
if (i != null && i.length() != 24) {
_context.banlist().banlistRouter(routerInfo.getIdentity().calculateHash(), "Bad address", null, null, now + 15*60*1000L);
return "Bad NTCP2 address";
}
}
return null;
}
Expand Down Expand Up @@ -1395,7 +1402,7 @@ RouterInfo store(Hash key, RouterInfo routerInfo, boolean persist) throws Illega

String err = validate(key, routerInfo);
if (err != null)
throw new IllegalArgumentException("Invalid store attempt - " + err);
throw new IllegalArgumentException("Invalid store attempt of RI " + key.toBase64() + " - " + err);

//if (_log.shouldLog(Log.DEBUG))
// _log.debug("RouterInfo " + key.toBase64() + " is stored with "
Expand Down
10 changes: 5 additions & 5 deletions router/java/src/net/i2p/router/sybil/Analysis.java
Original file line number Diff line number Diff line change
Expand Up @@ -79,20 +79,20 @@ public class Analysis extends JobImpl implements RouterApp, Runnable {
public static final int PAIRMAX = 20;
public static final int MAX = 10;
// multiplied by size - 1, will also get POINTS24 added
private static final double POINTS32 = 5.0;
private static final double POINTS32 = 0; //5.0;
// multiplied by size - 1, will also get POINTS16 added
private static final double POINTS24 = 4.0;
private static final double POINTS24 = 0; //4.0;
// multiplied by size - 1
private static final double POINTS16 = 0.25;
private static final double POINTS16 = 0; //0.25;
private static final double POINTS_US32 = 25.0;
private static final double POINTS_US24 = 20.0;
private static final double POINTS_US16 = 10.0;

// IPv6 since 0.9.57, likely to be on top of IPv4, so make lower
private static final double POINTS_V6_US64 = 12.5;
private static final double POINTS_V6_US48 = 5.0;
private static final double POINTS64 = 2.0;
private static final double POINTS48 = 0.5;
private static final double POINTS64 = 0; //2.0;
private static final double POINTS48 = 0; //0.5;

private static final double POINTS_FAMILY = -10.0;
private static final double POINTS_FAMILY_VERIFIED = POINTS_FAMILY * 4;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -395,6 +395,7 @@ protected void outboundMessageReady() {
} catch (DataFormatException dfe) {
if (_log.shouldWarn())
_log.warn("bad address? " + target, dfe);
_context.banlist().banlistRouter(ih, "Bad address", null, null, _context.clock().now() + 15*60*1000L);
fail = true;
}
} else {
Expand All @@ -410,7 +411,7 @@ protected void outboundMessageReady() {
if (fail) {
// race, RI changed out from under us, maybe SSU can handle it
if (_log.shouldLog(Log.WARN))
_log.warn("we bid on a peer who doesn't have an ntcp address? " + target);
_log.warn("we bid on a peer with a bad address? " + target);
afterSend(msg, false);
return;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@
import net.i2p.router.OutNetMessage;
import net.i2p.router.Router;
import net.i2p.router.RouterContext;
import net.i2p.router.networkdb.kademlia.FloodfillNetworkDatabaseFacade;
import net.i2p.router.peermanager.PeerProfile;
import net.i2p.router.transport.Transport;
import static net.i2p.router.transport.Transport.AddressSource.*;
import net.i2p.router.transport.TransportBid;
Expand Down Expand Up @@ -2483,6 +2485,13 @@ public TransportBid bid(RouterInfo toAddress, int dataSize) {
if (isUnreachable(to))
return null;

// temp, let NTCP2 deal with him (prop. 165)
if (toAddress.getCapabilities().indexOf(FloodfillNetworkDatabaseFacade.CAPABILITY_FLOODFILL) >= 0) {
PeerProfile prof = _context.profileOrganizer().getProfileNonblocking(to);
if (prof == null || prof.getLastHeardFrom() <= 0)
return null;
}

// Validate his SSU address
RouterAddress addr = getTargetAddress(toAddress);
if (addr == null) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package net.i2p.router.tunnel;

import net.i2p.data.DatabaseEntry;
import net.i2p.data.Hash;
import net.i2p.data.TunnelId;
import net.i2p.data.i2np.DatabaseStoreMessage;
import net.i2p.data.i2np.I2NPMessage;
import net.i2p.data.i2np.TunnelDataMessage;
import net.i2p.router.OutNetMessage;
Expand Down Expand Up @@ -64,6 +66,26 @@ public void receiveComplete(I2NPMessage msg, Hash toRouter, TunnelId toTunnel) {
_log.warn("Dropping msg at OBEP with unsupported delivery instruction type LOCAL");
return;
}

int type = msg.getType();
if (type == DatabaseStoreMessage.MESSAGE_TYPE) {
DatabaseStoreMessage dsm = (DatabaseStoreMessage) msg;
DatabaseEntry entry = dsm.getEntry();
if (entry.getType() == DatabaseEntry.KEY_TYPE_ROUTERINFO) {
long now = _context.clock().now();
long date = entry.getDate();
if (date < now - 60*60*1000L) {
if (_log.shouldWarn())
_log.warn("Dropping DSM of old RI at OBEP, direct? " + (toTunnel == null) + " to router: " + toRouter.toBase64() + " key: " + dsm.getKey().toBase64());
return;
} else if (date > now + 2*60*1000L) {
if (_log.shouldWarn())
_log.warn("Dropping DSM of future RI at OBEP, direct? " + (toTunnel == null) + " to router: " + toRouter.toBase64() + " key: " + dsm.getKey().toBase64());
return;
}
}
}

if (_log.shouldLog(Log.DEBUG))
_log.debug("outbound tunnel " + _config + " received a full message: " + msg
+ " to be forwarded on to "
Expand All @@ -73,7 +95,7 @@ public void receiveComplete(I2NPMessage msg, Hash toRouter, TunnelId toTunnel) {
// don't drop it if we are the target
boolean toUs = _context.routerHash().equals(toRouter);
if ((!toUs) &&
_context.tunnelDispatcher().shouldDropParticipatingMessage(TunnelDispatcher.Location.OBEP, msg.getType(), size))
_context.tunnelDispatcher().shouldDropParticipatingMessage(TunnelDispatcher.Location.OBEP, type, size))
return;
// this overstates the stat somewhat, but ok for now
//int kb = (size + 1023) / 1024;
Expand Down

0 comments on commit d5ec4cf

Please sign in to comment.