NetDB: Fix dup publish of RI at startup

Improve locking for checking address change
Publish RI after netdb is ready
log tweaks
This commit is contained in:
zzz
2019-02-25 14:40:59 +00:00
parent b76b2ef206
commit 7ce539a815
8 changed files with 57 additions and 21 deletions

View File

@ -837,11 +837,24 @@ public class Router implements RouterClock.ClockShiftListener {
* @since 0.9.18
*/
public void setNetDbReady() {
boolean changed = false;
synchronized(_stateLock) {
if (_state == State.STARTING_3)
if (_state == State.STARTING_3) {
changeState(State.NETDB_READY);
else if (_state == State.EXPL_TUNNELS_READY)
changed = true;
} else if (_state == State.EXPL_TUNNELS_READY) {
changeState(State.RUNNING);
changed = true;
}
}
if (changed) {
// any previous calls to netdb().publish() did not
// actually publish, because netdb init was not complete
Republish r = new Republish(_context);
// this is called from PersistentDataStore.ReadJob,
// so we probably don't need to throw it to the timer queue,
// but just to be safe
_context.simpleTimer2().addEvent(r, 0);
}
}
@ -905,7 +918,7 @@ public class Router implements RouterClock.ClockShiftListener {
*/
public void rebuildRouterInfo(boolean blockingRebuild) {
if (_log.shouldLog(Log.INFO))
_log.info("Rebuilding new routerInfo");
_log.info("Rebuilding new routerInfo, publish inline? " + blockingRebuild, new Exception("I did it"));
_routerInfoLock.writeLock().lock();
try {
locked_rebuildRouterInfo(blockingRebuild);

View File

@ -18,7 +18,7 @@ public class RouterVersion {
/** deprecated */
public final static String ID = "Monotone";
public final static String VERSION = CoreVersion.VERSION;
public final static long BUILD = 9;
public final static long BUILD = 10;
/** for example "-test" */
public final static String EXTRA = "";

View File

@ -49,10 +49,13 @@ public class PublishLocalRouterInfoJob extends JobImpl {
private static final long PUBLISH_DELAY = 52*60*1000;
/** this needs to be long enough to give us time to start up,
but less than 20m (when we start accepting tunnels and could be a IBGW)
Actually no, we need this soon if we are a new router or
other routers have forgotten about us, else
we can't build IB exploratory tunnels.
* but less than 20m (when we start accepting tunnels and could be a IBGW)
* Actually no, we need this soon if we are a new router or
* other routers have forgotten about us, else
* we can't build IB exploratory tunnels.
*
* First publish after netdb ready is now done via state machine
* in Router.setNetDbReady(), so we probably don't need this anymore
*/
private static final long FIRST_TIME_DELAY = 90*1000;
private volatile boolean _notFirstTime;
@ -142,6 +145,9 @@ public class PublishLocalRouterInfoJob extends JobImpl {
if (_notFirstTime) {
requeue(getDelay());
} else {
// First publish after netdb ready is now done via state machine
// in Router.setNetDbReady(), so we probably don't need this anymore
// but leave it in for now, a router may have trouble publishing right away
requeue(FIRST_TIME_DELAY);
_notFirstTime = true;
}

View File

@ -137,8 +137,11 @@ public class FloodfillNetworkDatabaseFacade extends KademliaNetworkDatabaseFacad
if (_context.router().isHidden()) return; // DE-nied!
super.publish(localRouterInfo);
// wait until we've read in the RI's so we can find the closest floodfill
if (!isInitialized())
if (!isInitialized()) {
if (_log.shouldWarn())
_log.warn("publish() before initialized: " + localRouterInfo, new Exception("I did it"));
return;
}
// no use sending if we have no addresses
// (unless maybe we used to have addresses? not worth it
if (localRouterInfo.getAddresses().isEmpty())

View File

@ -678,7 +678,11 @@ public abstract class KademliaNetworkDatabaseFacade extends NetworkDatabaseFacad
* @throws IllegalArgumentException if the leaseSet is not valid
*/
public void publish(LeaseSet localLeaseSet) throws IllegalArgumentException {
if (!_initialized) return;
if (!_initialized) {
if (_log.shouldWarn())
_log.warn("publish() before initialized: " + localLeaseSet, new Exception("I did it"));
return;
}
Hash h = localLeaseSet.getDestination().calculateHash();
try {
store(h, localLeaseSet);

View File

@ -8,6 +8,7 @@ package net.i2p.router.tasks;
*
*/
import net.i2p.data.router.RouterInfo;
import net.i2p.router.Router;
import net.i2p.router.RouterContext;
import net.i2p.util.SimpleTimer;
@ -27,7 +28,9 @@ public class Republish implements SimpleTimer.TimedEvent {
public void timeReached() {
try {
_context.netDb().publish(_context.router().getRouterInfo());
RouterInfo ri = _context.router().getRouterInfo();
if (ri != null)
_context.netDb().publish(ri);
} catch (IllegalArgumentException iae) {
Log log = _context.logManager().getLog(Router.class);
log.log(Log.CRIT, "Local router info is invalid? rebuilding a new identity", iae);

View File

@ -991,20 +991,21 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority
boolean fireTest = false;
boolean isIPv6 = ourIP.length == 16;
RouterAddress current = getCurrentExternalAddress(isIPv6);
byte[] externalListenHost = current != null ? current.getIP() : null;
int externalListenPort = current != null ? current.getPort() : getRequestedPort(isIPv6);
if (_log.shouldLog(Log.INFO))
_log.info("Change address? status = " + _reachabilityStatus +
synchronized (_rebuildLock) {
RouterAddress current = getCurrentExternalAddress(isIPv6);
byte[] externalListenHost = current != null ? current.getIP() : null;
int externalListenPort = current != null ? current.getPort() : getRequestedPort(isIPv6);
if (_log.shouldLog(Log.INFO))
_log.info("Change address? status = " + _reachabilityStatus +
" diff = " + (_context.clock().now() - _reachabilityStatusLastUpdated) +
" old = " + Addresses.toString(externalListenHost, externalListenPort) +
" new = " + Addresses.toString(ourIP, ourPort));
if ((fixedPort && externalListenPort > 0) || ourPort <= 0)
ourPort = externalListenPort;
if ((fixedPort && externalListenPort > 0) || ourPort <= 0)
ourPort = externalListenPort;
synchronized (this) {
if (ourPort > 0 &&
!eq(externalListenHost, externalListenPort, ourIP, ourPort)) {
// This prevents us from changing our IP when we are not firewalled
@ -1029,7 +1030,7 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority
if (_log.shouldLog(Log.INFO))
_log.info("Same address as the current one");
}
}
}
if (fireTest) {
// always false, commented out above
@ -1087,7 +1088,8 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority
_context.router().saveConfig(changes, null);
}
// deadlock thru here ticket #1699
_context.router().rebuildRouterInfo();
// this causes duplicate publish, REA() call above calls rebuildRouterInfo
//_context.router().rebuildRouterInfo();
_testEvent.forceRunImmediately(isIPv6);
}
return updated;