diff --git a/router/java/src/net/i2p/router/networkdb/kademlia/HandleFloodfillDatabaseStoreMessageJob.java b/router/java/src/net/i2p/router/networkdb/kademlia/HandleFloodfillDatabaseStoreMessageJob.java index 9ad1c5a0a..12140a9e4 100644 --- a/router/java/src/net/i2p/router/networkdb/kademlia/HandleFloodfillDatabaseStoreMessageJob.java +++ b/router/java/src/net/i2p/router/networkdb/kademlia/HandleFloodfillDatabaseStoreMessageJob.java @@ -156,23 +156,6 @@ public class HandleFloodfillDatabaseStoreMessageJob extends JobImpl { if (invalidMessage == null) { getContext().profileManager().dbStoreReceived(_fromHash, wasNew); getContext().statManager().addRateData("netDb.storeHandled", ackEnd-recvEnd, 0); - if (FloodfillNetworkDatabaseFacade.floodfillEnabled(getContext()) && (_message.getReplyToken() > 0) ) { - if (wasNew) { - long floodBegin = System.currentTimeMillis(); - if (_message.getValueType() == DatabaseStoreMessage.KEY_TYPE_LEASESET) - _facade.flood(_message.getLeaseSet()); - // ERR: see comment in HandleDatabaseLookupMessageJob regarding hidden mode - //else if (!_message.getRouterInfo().isHidden()) - else - _facade.flood(_message.getRouterInfo()); - long floodEnd = System.currentTimeMillis(); - getContext().statManager().addRateData("netDb.storeFloodNew", floodEnd-floodBegin, 0); - } else { - // don't flood it *again* - getContext().statManager().addRateData("netDb.storeFloodOld", 1, 0); - } - } - } else { // Should we record in the profile? if (_log.shouldLog(Log.WARN)) @@ -182,6 +165,26 @@ public class HandleFloodfillDatabaseStoreMessageJob extends JobImpl { if (_log.shouldLog(Log.WARN)) _log.warn("Unknown peer sent bad data: " + invalidMessage); } + + // flood it + if (invalidMessage == null && + FloodfillNetworkDatabaseFacade.floodfillEnabled(getContext()) && + _message.getReplyToken() > 0) { + if (wasNew) { + long floodBegin = System.currentTimeMillis(); + if (_message.getValueType() == DatabaseStoreMessage.KEY_TYPE_LEASESET) + _facade.flood(_message.getLeaseSet()); + // ERR: see comment in HandleDatabaseLookupMessageJob regarding hidden mode + //else if (!_message.getRouterInfo().isHidden()) + else + _facade.flood(_message.getRouterInfo()); + long floodEnd = System.currentTimeMillis(); + getContext().statManager().addRateData("netDb.storeFloodNew", floodEnd-floodBegin, 0); + } else { + // don't flood it *again* + getContext().statManager().addRateData("netDb.storeFloodOld", 1, 0); + } + } } private void sendAck() { diff --git a/router/java/src/net/i2p/router/networkdb/kademlia/StoreJob.java b/router/java/src/net/i2p/router/networkdb/kademlia/StoreJob.java index 9e3623639..f93b35947 100644 --- a/router/java/src/net/i2p/router/networkdb/kademlia/StoreJob.java +++ b/router/java/src/net/i2p/router/networkdb/kademlia/StoreJob.java @@ -30,6 +30,7 @@ import net.i2p.router.peermanager.PeerProfile; import net.i2p.stat.Rate; import net.i2p.stat.RateStat; import net.i2p.util.Log; +import net.i2p.util.VersionComparator; class StoreJob extends JobImpl { protected Log _log; @@ -431,26 +432,36 @@ class StoreJob extends JobImpl { Hash to = peer.getIdentity().getHash(); TunnelInfo outTunnel = getContext().tunnelManager().selectOutboundTunnel(client); if (outTunnel != null) { - // garlic encrypt - MessageWrapper.WrappedMessage wm = MessageWrapper.wrap(getContext(), msg, client, peer); - if (wm == null) { - if (_log.shouldLog(Log.WARN)) - _log.warn("Fail garlic encrypting from: " + client); - fail(); - return; + I2NPMessage sent; + boolean shouldEncrypt = supportsEncryption(peer); + if (shouldEncrypt) { + // garlic encrypt + MessageWrapper.WrappedMessage wm = MessageWrapper.wrap(getContext(), msg, client, peer); + if (wm == null) { + if (_log.shouldLog(Log.WARN)) + _log.warn("Fail garlic encrypting from: " + client); + fail(); + return; + } + sent = wm.getMessage(); + _state.addPending(to, wm); + } else { + sent = msg; + _state.addPending(to); } - I2NPMessage sent = wm.getMessage(); SendSuccessJob onReply = new SendSuccessJob(getContext(), peer, outTunnel, sent.getMessageSize()); FailedJob onFail = new FailedJob(getContext(), peer, getContext().clock().now()); StoreMessageSelector selector = new StoreMessageSelector(getContext(), getJobId(), peer, token, expiration); if (_log.shouldLog(Log.DEBUG)) { - _log.debug("sending encrypted store to " + peer.getIdentity().getHash() + " through " + outTunnel + ": " + sent); + if (shouldEncrypt) + _log.debug("sending encrypted store to " + peer.getIdentity().getHash() + " through " + outTunnel + ": " + sent); + else + _log.debug("sending store to " + peer.getIdentity().getHash() + " through " + outTunnel + ": " + sent); //_log.debug("Expiration is " + new Date(sent.getMessageExpiration())); } getContext().messageRegistry().registerPending(selector, onReply, onFail, (int)(expiration - getContext().clock().now())); - _state.addPending(to, wm); getContext().tunnelDispatcher().dispatchOutbound(sent, outTunnel.getSendTunnelId(0), null, to); } else { if (_log.shouldLog(Log.WARN)) @@ -480,6 +491,21 @@ class StoreJob extends JobImpl { public String getName() { return "Kademlia Store Send Delay"; } } + private static final String MIN_ENCRYPTION_VERSION = "0.7.10"; + + /** + * *sigh* + * sadly due to a bug in HandleFloodfillDatabaseStoreMessageJob, where + * a floodfill would not flood anything that arrived garlic-wrapped + * @since 0.7.10 + */ + private static boolean supportsEncryption(RouterInfo ri) { + String v = ri.getOption("router.version"); + if (v == null) + return false; + return (new VersionComparator()).compare(v, MIN_ENCRYPTION_VERSION) >= 0; + } + /** * Called after sending a dbStore to a peer successfully, * marking the store as successful