diff --git a/apps/i2psnark/java/src/org/klomp/snark/web/I2PSnarkServlet.java b/apps/i2psnark/java/src/org/klomp/snark/web/I2PSnarkServlet.java
index ec5e2b8db..85497d4f7 100644
--- a/apps/i2psnark/java/src/org/klomp/snark/web/I2PSnarkServlet.java
+++ b/apps/i2psnark/java/src/org/klomp/snark/web/I2PSnarkServlet.java
@@ -512,7 +512,8 @@ public class I2PSnarkServlet extends HttpServlet {
Map.Entry entry = (Map.Entry)iter.next();
String name = (String)entry.getKey();
String baseURL = (String)entry.getValue();
- if (!baseURL.startsWith(announce))
+ if (!(baseURL.startsWith(announce) || // vvv hack for non-b64 announce in list vvv
+ (announce.startsWith("http://lnQ6yoBT") && baseURL.startsWith("http://tracker2.postman.i2p/"))))
continue;
int e = baseURL.indexOf('=');
if (e < 0)
diff --git a/apps/routerconsole/java/src/net/i2p/router/web/CSSHelper.java b/apps/routerconsole/java/src/net/i2p/router/web/CSSHelper.java
index 643c8c45c..6b3916883 100644
--- a/apps/routerconsole/java/src/net/i2p/router/web/CSSHelper.java
+++ b/apps/routerconsole/java/src/net/i2p/router/web/CSSHelper.java
@@ -9,12 +9,17 @@ public class CSSHelper extends HelperBase {
public static final String PROP_THEME_NAME = "routerconsole.theme";
private static final String BASE = "/themes/console/";
+ private static final String FORCE = "classic";
- public String getTheme() {
+ public String getTheme(String userAgent) {
String url = BASE;
- String theme = _context.getProperty(PROP_THEME_NAME);
- if (theme != null)
- url += theme + "/";
+ if (userAgent != null && userAgent.contains("MSIE")) {
+ url += FORCE + "/";
+ } else {
+ String theme = _context.getProperty(PROP_THEME_NAME);
+ if (theme != null)
+ url += theme + "/";
+ }
return url;
}
}
diff --git a/apps/routerconsole/jsp/css.jsp b/apps/routerconsole/jsp/css.jsp
index 1e47f34d4..60db06835 100644
--- a/apps/routerconsole/jsp/css.jsp
+++ b/apps/routerconsole/jsp/css.jsp
@@ -17,4 +17,4 @@
%>
As a note, you can change this page by editing the file "docs/readme.html"
- \ No newline at end of file + diff --git a/readme_de.html b/readme_de.html index 60d8aeabe..885ac923a 100644 --- a/readme_de.html +++ b/readme_de.html @@ -72,5 +72,3 @@ chatten auf #i2p or #i2p-chat beim IRC auf irc.freenode.net, irc.postman.i2p oder irc.freshcoffee.i2p (die verbunden sind). - -Übrigens, diese Seite kannst Du ändern indem Du "docs/readme_de.html" editierst
diff --git a/readme_fr.html b/readme_fr.html index 9ab143e4a..f5112970d 100644 --- a/readme_fr.html +++ b/readme_fr.html @@ -37,5 +37,3 @@Soyez patient - i2p peut s'avérer lent à démarrer la première fois car il recherche des pairs. Si, après 30 minutes, votre Actives: connecté/récent compte moins de 10 pairs connectés, vous devez ouvrir le port 8887 sur votre pare-feu pour avoir une meilleure connection. Si vous ne pouvez accéder à aucun eepsite (même www.i2p2.i2p), soyez sûr que votre navigateur utilise bien le proxy localhost sur le port 4444. Vous pouvez aussi faire part de votre démarche sur le site web I2P, poster des message sur le forum de discussion, ou passer par #i2p ou #i2p-chat sur IRC sur le serveur irc.freenode.net, irc.postman.i2p ou irc.freshcoffee.i2p (ils sont liés).
- -Comme vous pouvez le remarquer, il suffit d'éditer la page "docs/readme.html" pour changer la page d'acceuil
diff --git a/readme_nl.html b/readme_nl.html index 7ff79e89d..296e2c496 100644 --- a/readme_nl.html +++ b/readme_nl.html @@ -56,5 +56,3 @@ Je zou best ook de informatie controleren op de I2P website, of plaats een bericht op het I2P discussie forum, of kom langs bij #i2p of #i2p-chat op IRC bij de kanalen irc.freenode.net, irc.postman.i2p of irc.freshcoffee.i2p (ze linken allemaal door naar elkaar). - -Als extra informatie, je kan deze pagina wijzigen door het bestand "docs/readme_nl.html" aan te passen.
diff --git a/readme_sv.html b/readme_sv.html index ef68ea14e..7d738aa12 100644 --- a/readme_sv.html +++ b/readme_sv.html @@ -98,6 +98,3 @@ förbi #i2p eller #i2p-chat på IRC på irc.freenode.net, irc.postman.i2p eller irc.freshcoffee.i2p (de är alla sammankopplade). - -Du kan förändra denhär sidan genom att ändra i filen -"docs/readme_sv.html"
diff --git a/readme_zh.html b/readme_zh.html index 6f2a0394c..bb7dc314a 100644 --- a/readme_zh.html +++ b/readme_zh.html @@ -24,5 +24,3 @@±£³ÖÄÍÐÄ - I2P µÚÒ»´ÎÆô¶¯Ê±ÐèÒªËÑË÷½Úµã£¬¿ÉÄܱȽϻºÂý¡£Èç¹û30·ÖÖÓºó£¬ÄúµÄ»î¶¯½Úµã(Active:ÒÑÁ¬½Ó/нüÁ¬½Ó) ¼ÆÊýÈÔÔÚ 10 ¸ö½ÚµãÒÔÏÂ, ÇëÔÚ·À»ðǽÖдò¿ª 8887 ¶Ë¿Ú¸ÄÉÆÁ¬½ÓÐÔÄÜ¡£Èç¹ûÄú¸ù±¾ÎÞ·¨´ò¿ªÈκÎEEPSITE(ÉõÖÁ www.i2p2.i2p)£¬¼ì²éÄúµÄä¯ÀÀÆ÷´úÀíÉèÖÃÊÇ·ñΪ±¾µØµÄ localhost:4444¡£ÄãÒ²¿ÉÒԲ鿴 I2P ÍøÕ¾ ÉϵÄÐÅÏ¢, ÔÚ I2P ÂÛ̳ Öз¢Ìû, À´ irc.freenode.net , irc.postman.i2p »ò irc.freshcoffee.i2p É쵀 #i2p »ò #i2p-chat Á½¸öIRCƵµÀ×ø×ø¡£ (ÕâЩ·þÎñÆ÷ÉϵÄÕâÁ½¸öƵµÀÊÇÏàͨµÄ)¡£
- -Ìáʾ£¬Äú¿ÉÒÔͨ¹ý±à¼ "docs/readme_zh.html" Ð޸ı¾Ò³Ãæ¡£
diff --git a/router/java/src/net/i2p/router/CommSystemFacade.java b/router/java/src/net/i2p/router/CommSystemFacade.java index c26d9efbf..e8a45724e 100644 --- a/router/java/src/net/i2p/router/CommSystemFacade.java +++ b/router/java/src/net/i2p/router/CommSystemFacade.java @@ -34,8 +34,8 @@ public abstract class CommSystemFacade implements Service { public int countActivePeers() { return 0; } public int countActiveSendPeers() { return 0; } - public boolean haveInboundCapacity() { return true; } - public boolean haveOutboundCapacity() { return true; } + public boolean haveInboundCapacity(int pct) { return true; } + public boolean haveOutboundCapacity(int pct) { return true; } public boolean haveHighOutboundCapacity() { return true; } public List getMostRecentErrorMessages() { return Collections.EMPTY_LIST; } diff --git a/router/java/src/net/i2p/router/networkdb/reseed/ReseedChecker.java b/router/java/src/net/i2p/router/networkdb/reseed/ReseedChecker.java index aa38be5e7..dd11c4ae2 100644 --- a/router/java/src/net/i2p/router/networkdb/reseed/ReseedChecker.java +++ b/router/java/src/net/i2p/router/networkdb/reseed/ReseedChecker.java @@ -15,8 +15,7 @@ import net.i2p.util.Log; * * Also, as this is now called from PersistentDataStore, not from the * routerconsole, we can get started as soon as the netdb has read - * the netDb/ directory, not when the console starts, -router/java/src/net/i2p/router/networkdb/eseed/ReseedChecker.java + * the netDb/ directory, not when the console starts. */ public class ReseedChecker { diff --git a/router/java/src/net/i2p/router/peermanager/ProfileOrganizer.java b/router/java/src/net/i2p/router/peermanager/ProfileOrganizer.java index 90792571e..504c56703 100644 --- a/router/java/src/net/i2p/router/peermanager/ProfileOrganizer.java +++ b/router/java/src/net/i2p/router/peermanager/ProfileOrganizer.java @@ -541,9 +541,11 @@ public class ProfileOrganizer { l.add(peer); else { RouterAddress ra = info.getTargetAddress("SSU"); - // Definitely don't want peers with no SSU address at all + // peers with no SSU address at all are fine. + // as long as they have NTCP if (ra == null) { - l.add(peer); + if (info.getTargetAddress("NTCP") == null) + l.add(peer); continue; } // This is the quick way of doing UDPAddress.getIntroducerCount() > 0 diff --git a/router/java/src/net/i2p/router/transport/CommSystemFacadeImpl.java b/router/java/src/net/i2p/router/transport/CommSystemFacadeImpl.java index 9067aad93..60e2af05c 100644 --- a/router/java/src/net/i2p/router/transport/CommSystemFacadeImpl.java +++ b/router/java/src/net/i2p/router/transport/CommSystemFacadeImpl.java @@ -70,9 +70,9 @@ public class CommSystemFacadeImpl extends CommSystemFacade { @Override public int countActiveSendPeers() { return (_manager == null ? 0 : _manager.countActiveSendPeers()); } @Override - public boolean haveInboundCapacity() { return (_manager == null ? false : _manager.haveInboundCapacity()); } + public boolean haveInboundCapacity(int pct) { return (_manager == null ? false : _manager.haveInboundCapacity(pct)); } @Override - public boolean haveOutboundCapacity() { return (_manager == null ? false : _manager.haveOutboundCapacity()); } + public boolean haveOutboundCapacity(int pct) { return (_manager == null ? false : _manager.haveOutboundCapacity(pct)); } @Override public boolean haveHighOutboundCapacity() { return (_manager == null ? false : _manager.haveHighOutboundCapacity()); } diff --git a/router/java/src/net/i2p/router/transport/Transport.java b/router/java/src/net/i2p/router/transport/Transport.java index d0ec7267b..339c33f7b 100644 --- a/router/java/src/net/i2p/router/transport/Transport.java +++ b/router/java/src/net/i2p/router/transport/Transport.java @@ -44,10 +44,11 @@ public interface Transport { public void setListener(TransportEventListener listener); public String getStyle(); + public int countPeers(); public int countActivePeers(); public int countActiveSendPeers(); public boolean haveCapacity(); - public boolean haveHighCapacity(); + public boolean haveCapacity(int pct); public Vector getClockSkews(); public List getMostRecentErrorMessages(); diff --git a/router/java/src/net/i2p/router/transport/TransportImpl.java b/router/java/src/net/i2p/router/transport/TransportImpl.java index 7f27766a7..29318bb60 100644 --- a/router/java/src/net/i2p/router/transport/TransportImpl.java +++ b/router/java/src/net/i2p/router/transport/TransportImpl.java @@ -78,8 +78,13 @@ public abstract class TransportImpl implements Transport { } /** - * How many peers can we talk to right now? - * + * How many peers are we connected to? + * For NTCP, this is the same as active, + * but SSU actually looks at idle time for countActivePeers() + */ + public int countPeers() { return countActivePeers(); } + /** + * How many peers active in the last few minutes? */ public int countActivePeers() { return 0; } /** @@ -108,14 +113,22 @@ public abstract class TransportImpl implements Transport { } // increase limit for SSU, for now if (style.equals("udp")) - def = def * 4 / 3; + def = def * 3 / 2; return _context.getProperty("i2np." + style + ".maxConnections", def); } + private static final int DEFAULT_CAPACITY_PCT = 75; /** * Can we initiate or accept a connection to another peer, saving some margin */ - public boolean haveCapacity() { return true; } + public boolean haveCapacity() { + return haveCapacity(DEFAULT_CAPACITY_PCT); + } + + /** @param pct are we under x% 0-100 */ + public boolean haveCapacity(int pct) { + return countPeers() < getMaxConnections() * pct / 100; + } /** * Return our peer clock skews on a transport. diff --git a/router/java/src/net/i2p/router/transport/TransportManager.java b/router/java/src/net/i2p/router/transport/TransportManager.java index d432f80fd..f9d495cea 100644 --- a/router/java/src/net/i2p/router/transport/TransportManager.java +++ b/router/java/src/net/i2p/router/transport/TransportManager.java @@ -206,15 +206,18 @@ public class TransportManager implements TransportEventListener { /** * Is at least one transport below its outbound connection limit + some margin * Use for throttling in the router. + * + * @param pct percent of limit 0-100 */ - public boolean haveOutboundCapacity() { + public boolean haveOutboundCapacity(int pct) { for (int i = 0; i < _transports.size(); i++) { - if (((Transport)_transports.get(i)).haveCapacity()) + if (((Transport)_transports.get(i)).haveCapacity(pct)) return true; } return false; } + private static final int HIGH_CAPACITY_PCT = 50; /** * Are all transports well below their outbound connection limit * Use for throttling in the router. @@ -223,7 +226,7 @@ public class TransportManager implements TransportEventListener { if (_transports.size() <= 0) return false; for (int i = 0; i < _transports.size(); i++) { - if (!((Transport)_transports.get(i)).haveHighCapacity()) + if (!((Transport)_transports.get(i)).haveCapacity(HIGH_CAPACITY_PCT)) return false; } return true; @@ -232,10 +235,12 @@ public class TransportManager implements TransportEventListener { /** * Is at least one transport below its inbound connection limit + some margin * Use for throttling in the router. + * + * @param pct percent of limit 0-100 */ - public boolean haveInboundCapacity() { + public boolean haveInboundCapacity(int pct) { for (int i = 0; i < _transports.size(); i++) { - if (_transports.get(i).getCurrentAddress() != null && _transports.get(i).haveCapacity()) + if (_transports.get(i).getCurrentAddress() != null && _transports.get(i).haveCapacity(pct)) return true; } return false; diff --git a/router/java/src/net/i2p/router/transport/ntcp/NTCPTransport.java b/router/java/src/net/i2p/router/transport/ntcp/NTCPTransport.java index 5fa10b310..bd300112b 100644 --- a/router/java/src/net/i2p/router/transport/ntcp/NTCPTransport.java +++ b/router/java/src/net/i2p/router/transport/ntcp/NTCPTransport.java @@ -321,15 +321,6 @@ public class NTCPTransport extends TransportImpl { return countActivePeers() < getMaxConnections(); } - @Override - public boolean haveCapacity() { - return countActivePeers() < getMaxConnections() * 4 / 5; - } - - public boolean haveHighCapacity() { - return countActivePeers() < getMaxConnections() / 2; - } - /** queue up afterSend call, which can take some time w/ jobs, etc */ void sendComplete(OutNetMessage msg) { _finisher.add(msg); } 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 47edd62c3..97d1e3ba4 100644 --- a/router/java/src/net/i2p/router/transport/udp/UDPTransport.java +++ b/router/java/src/net/i2p/router/transport/udp/UDPTransport.java @@ -1334,6 +1334,13 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority super.afterSend(m, true); } + @Override + public int countPeers() { + synchronized (_peersByIdent) { + return _peersByIdent.size(); + } + } + @Override public int countActivePeers() { long now = _context.clock().now(); @@ -1379,19 +1386,6 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority } } - @Override - public boolean haveCapacity() { - synchronized (_peersByIdent) { - return _peersByIdent.size() < getMaxConnections() * 4 / 5; - } - } - - public boolean haveHighCapacity() { - synchronized (_peersByIdent) { - return _peersByIdent.size() < getMaxConnections() / 2; - } - } - /** * Return our peer clock skews on this transport. * Vector composed of Long, each element representing a peer skew in seconds. diff --git a/router/java/src/net/i2p/router/tunnel/TunnelDispatcher.java b/router/java/src/net/i2p/router/tunnel/TunnelDispatcher.java index de29a9540..3da777076 100644 --- a/router/java/src/net/i2p/router/tunnel/TunnelDispatcher.java +++ b/router/java/src/net/i2p/router/tunnel/TunnelDispatcher.java @@ -253,6 +253,12 @@ public class TunnelDispatcher implements Service { return _participatingConfig.size(); } + /******* may be used for congestion control later... + public int getParticipatingInboundGatewayCount() { + return _inboundGateways.size(); + } + *******/ + /** what is the date/time on which the last non-locally-created tunnel expires? */ public long getLastParticipatingExpiration() { return _lastParticipatingExpiration; } diff --git a/router/java/src/net/i2p/router/tunnel/pool/BuildHandler.java b/router/java/src/net/i2p/router/tunnel/pool/BuildHandler.java index 0583c73b1..ae17622e8 100644 --- a/router/java/src/net/i2p/router/tunnel/pool/BuildHandler.java +++ b/router/java/src/net/i2p/router/tunnel/pool/BuildHandler.java @@ -65,6 +65,7 @@ class BuildHandler { _context.statManager().createRateStat("tunnel.rejectOverloaded", "How long we had to wait before processing the request (when it was rejected)", "Tunnels", new long[] { 60*1000, 10*60*1000 }); _context.statManager().createRateStat("tunnel.acceptLoad", "Delay before processing the accepted request", "Tunnels", new long[] { 60*1000, 10*60*1000 }); + _context.statManager().createRateStat("tunnel.dropConnLimits", "Drop instead of reject due to conn limits", "Tunnels", new long[] { 60*1000, 10*60*1000 }); _context.statManager().createRateStat("tunnel.dropLoad", "How long we had to wait before finally giving up on an inbound request (period is queue count)?", "Tunnels", new long[] { 60*1000, 10*60*1000 }); _context.statManager().createRateStat("tunnel.dropLoadDelay", "How long we had to wait before finally giving up on an inbound request?", "Tunnels", new long[] { 60*1000, 10*60*1000 }); _context.statManager().createRateStat("tunnel.dropLoadBacklog", "How many requests were pending when they were so lagged that we had to drop a new inbound request??", "Tunnels", new long[] { 60*1000, 10*60*1000 }); @@ -466,7 +467,6 @@ class BuildHandler { return 0; } - private static final String PROP_REJECT_NONPARTICIPANT = "router.participantOnly"; private void handleReq(RouterInfo nextPeerInfo, BuildMessageState state, BuildRequestRecord req, Hash nextPeer) { long ourId = req.readReceiveTunnelId(); long nextId = req.readNextTunnelId(); @@ -510,8 +510,8 @@ class BuildHandler { * reject this request. */ if (response == 0 && - ((isInGW && ! _context.commSystem().haveInboundCapacity()) || - (isOutEnd && ! _context.commSystem().haveOutboundCapacity()))) { + ((isInGW && ! _context.commSystem().haveInboundCapacity(87)) || + (isOutEnd && ! _context.commSystem().haveOutboundCapacity(87)))) { _context.throttle().setTunnelStatus("Rejecting tunnels: Connection limit"); response = TunnelHistory.TUNNEL_REJECT_BANDWIDTH; } @@ -569,6 +569,17 @@ class BuildHandler { (isOutEnd ? "outbound endpoint" : isInGW ? "inbound gw" : "participant")); } + // Connection congestion control: + // If we rejected the request, are near our conn limits, and aren't connected to the next hop, + // just drop it. + if (response != 0 && + (! _context.routerHash().equals(nextPeer)) && + (! _context.commSystem().haveOutboundCapacity(75)) && + (! _context.commSystem().isEstablished(nextPeer))) { + _context.statManager().addRateData("tunnel.dropConnLimits", 1, 0); + return; + } + BuildResponseRecord resp = new BuildResponseRecord(); byte reply[] = resp.create(_context, response, req.readReplyKey(), req.readReplyIV(), state.msg.getUniqueId()); for (int j = 0; j < TunnelBuildMessage.RECORD_COUNT; j++) {