- Throttle outbound destroys on shutdown
   - Limit outbound introduction offers
This commit is contained in:
zzz
2012-10-06 13:44:57 +00:00
parent 97460e7d99
commit b07b9bf0b9
5 changed files with 62 additions and 36 deletions

View File

@ -1,3 +1,14 @@
2012-10-06 zzz
* configlogging.jsp: Fix IAE
* error500.jsp: Fix whitespace
* i2psnark:
- Add allocating and checking indications
- Add bandwidth message at startup
- More checks at torrent creation
* SSU:
- Throttle outbound destroys on shutdown
- Limit outbound introduction offers
2012-10-05 zzz
* configservice.jsp: Add GC button
* DataHelper: Sanity checks in storeProps(), use

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 = 7;
public final static long BUILD = 8;
/** for example "-test" */
public final static String EXTRA = "";

View File

@ -21,7 +21,6 @@ import net.i2p.data.i2np.I2NPMessage;
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.transport.crypto.DHSessionKeyBuilder;
import static net.i2p.router.transport.udp.InboundEstablishState.InboundState.*;
import static net.i2p.router.transport.udp.OutboundEstablishState.OutboundState.*;
@ -455,14 +454,9 @@ class EstablishmentManager {
}
if (isNew) {
// we don't expect inbound connections when hidden, but it could happen
// Don't offer if we are approaching max connections. While Relay Intros do not
// count as connections, we have to keep the connection to this peer up longer if
// we are offering introductions.
// Don't offer to relay to privileged ports.
if ((!_context.router().isHidden()) && (!_transport.introducersRequired()) && _transport.haveCapacity() &&
state.getSentPort() >= 1024 &&
!((FloodfillNetworkDatabaseFacade)_context.netDb()).floodfillEnabled()) {
// TODO if already we have their RI, only offer if they need it (no 'C' cap)
if (_transport.canIntroduce() && state.getSentPort() >= 1024) {
// ensure > 0
long tag = 1 + _context.random().nextLong(MAX_TAG_VALUE);
state.setSentRelayTag(tag);
@ -816,29 +810,10 @@ class EstablishmentManager {
/** the relay tag is a 4-byte field in the protocol */
public static final long MAX_TAG_VALUE = 0xFFFFFFFFl;
/**
* This may be called more than once
*/
private void sendCreated(InboundEstablishState state) {
long now = _context.clock().now();
// This is usually handled in receiveSessionRequest() above, except, I guess,
// if the session isn't new and we are going through again.
// Don't offer if we are approaching max connections (see comments above)
// Also don't offer if we are floodfill, as this extends the max idle time
// and we will have lots of incoming conns
if ((!_context.router().isHidden()) && (!_transport.introducersRequired()) && _transport.haveCapacity() &&
!((FloodfillNetworkDatabaseFacade)_context.netDb()).floodfillEnabled()) {
// offer to relay
// (perhaps we should check our bw usage and/or how many peers we are
// already offering introducing?)
if (state.getSentRelayTag() == 0) {
// ensure > 0
state.setSentRelayTag(1 + _context.random().nextLong(MAX_TAG_VALUE));
} else {
// don't change it, since we've already prepared our sig
}
} else {
// don't offer to relay
state.setSentRelayTag(0);
}
if (_log.shouldLog(Log.DEBUG))
_log.debug("Send created to: " + state);

View File

@ -43,10 +43,10 @@ class IntroductionManager {
private static final int MAX_INBOUND = 20;
/**
* TODO this should be enforced in EstablishmentManager, it isn't now.
* This is enforced in EstablishmentManager
* @since 0.8.11
*/
private static final int MAX_OUTBOUND = 100;
public static final int MAX_OUTBOUND = 100;
/** Max one per target in this time */
private static final long PUNCH_CLEAN_TIME = 5*1000;
@ -209,6 +209,14 @@ class IntroductionManager {
return _inbound.size();
}
/**
* @return number of peers we have volunteered to introduce
* @since 0.9.3
*/
int introducedCount() {
return _outbound.size();
}
/**
* We are Charlie and we got this from Bob.
* Send a HolePunch to Alice, who will soon be sending us a RelayRequest.

View File

@ -32,6 +32,7 @@ import net.i2p.router.CommSystemFacade;
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.transport.Transport;
import net.i2p.router.transport.TransportBid;
import net.i2p.router.transport.TransportImpl;
@ -1214,20 +1215,33 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority
}
/**
* Send a session destroy message to everybody
* BLOCKING if OB queue is full.
* Send a session destroy message to everybody.
* BLOCKING for at least 1 sec per 1K peers, more if BW is very low or if OB queue is full.
*
* @since 0.8.9
*/
private void destroyAll() {
_endpoint.clearOutbound();
int howMany = _peersByIdent.size();
// use no more than 1/4 of configured bandwidth
final int burst = 8;
int pps = Math.max(48, (_context.bandwidthLimiter().getOutboundKBytesPerSecond() * 1000 / 4) / 48);
int burstps = pps / burst;
// max of 1000 pps
int toSleep = Math.max(8, (1000 / burstps));
int count = 0;
if (_log.shouldLog(Log.WARN))
_log.warn("Sending destroy to : " + howMany + " peers");
for (PeerState peer : _peersByIdent.values()) {
sendDestroy(peer);
// 1000 per second * 48 bytes = 400 KBps
if ((++count) % burst == 0) {
try {
Thread.sleep(toSleep);
} catch (InterruptedException ie) {}
}
}
int toSleep = Math.min(howMany / 3, 750);
toSleep = Math.min(howMany / 3, 750);
if (toSleep > 0) {
try {
Thread.sleep(toSleep);
@ -1595,6 +1609,24 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority
}
}
/**
* For EstablishmentManager
* @since 0.9.3
*/
boolean canIntroduce() {
// we don't expect inbound connections when hidden, but it could happen
// Don't offer if we are approaching max connections. While Relay Intros do not
// count as connections, we have to keep the connection to this peer up longer if
// we are offering introductions.
return
(!_context.router().isHidden()) &&
(!introducersRequired()) &&
haveCapacity() &&
(!((FloodfillNetworkDatabaseFacade)_context.netDb()).floodfillEnabled()) &&
_introManager.introducedCount() < IntroductionManager.MAX_OUTBOUND &&
_introManager.introducedCount() < getMaxConnections() / 4;
}
/** default true */
private boolean allowDirectUDP() {
return _context.getBooleanPropertyDefaultTrue(PROP_ALLOW_DIRECT);