Changeset 855293d6


Ignore:
Timestamp:
Oct 10, 2008 5:34:25 PM (12 years ago)
Author:
zzz <zzz@…>
Branches:
master
Children:
f3f7537
Parents:
4c2d414
Message:
  • Tunnels: Implement random discard to enforce share limit
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • core/java/src/net/i2p/stat/StatManager.java

    r4c2d414 r855293d6  
    5454        "tunnel.decryptRequestTime,tunnel.fragmentedDropped,tunnel.participatingMessageCount,"+
    5555        "tunnel.participatingTunnels,tunnel.testFailedTime,tunnel.testSuccessTime," +
    56         "udp.sendPacketSize,udp.packetsRetransmitted" ;
     56        "tunnel.participatingBandwidth,udp.sendPacketSize,udp.packetsRetransmitted" ;
    5757   
    5858    /**
  • history.txt

    r4c2d414 r855293d6  
     12008-10-10 zzz
     2    * Profiles: Reduce reject penalty in
     3      capacity calculation to avoid a congestion collapse
     4    * Throttle: Change reject to BANDWIDTH from CRIT on shutdown
     5      for improved anonymity
     6    * Tunnels: Implement random discard to enforce share limit
     7    * Tunnel Tests: Add time for outbound delay, to avoid
     8      congestion collapse
     9    * UDPPacketReader: Adjust logging
     10    * build files: Change to source=1.5, target=1.5
     11    * configpeer.jsp: Table cleanup
     12    * i2psnark: Change default tunnel length from 1+1 to 2+0
     13    * peers.jsp: Change <,> to in,out for UDP
     14
    1152008-10-09 sponge
    216    * Update version to -3
  • router/java/src/net/i2p/router/RouterVersion.java

    r4c2d414 r855293d6  
    1818    public final static String ID = "$Revision: 1.548 $ $Date: 2008-06-07 23:00:00 $";
    1919    public final static String VERSION = "0.6.4";
    20     public final static long BUILD = 3;
     20    public final static long BUILD = 4;
    2121    public static void main(String args[]) {
    2222        System.out.println("I2P Router version: " + VERSION + "-" + BUILD);
  • router/java/src/net/i2p/router/tunnel/HopConfig.java

    r4c2d414 r855293d6  
    2929    private long _messagesProcessed;
    3030    private long _oldMessagesProcessed;
     31    private long _messagesSent;
     32    private long _oldMessagesSent;
    3133   
    3234    /** IV length for {@link #getReplyIV} */
     
    4547        _messagesProcessed = 0;
    4648        _oldMessagesProcessed = 0;
     49        _messagesSent = 0;
     50        _oldMessagesSent = 0;
    4751    }
    4852   
     
    116120   
    117121    /** take note of a message being pumped through this tunnel */
     122    /** "processed" is for incoming and "sent" is for outgoing (could be dropped in between) */
    118123    public void incrementProcessedMessages() { _messagesProcessed++; }
    119124    public long getProcessedMessagesCount() { return _messagesProcessed; }
     
    121126        long rv = _messagesProcessed - _oldMessagesProcessed;
    122127        _oldMessagesProcessed = _messagesProcessed;
     128        return rv;
     129    }
     130    public void incrementSentMessages() { _messagesSent++; }
     131    public long getSentMessagesCount() { return _messagesSent; }
     132    public long getRecentSentMessagesCount() {
     133        long rv = _messagesSent - _oldMessagesSent;
     134        _oldMessagesSent = _messagesSent;
    123135        return rv;
    124136    }
  • router/java/src/net/i2p/router/tunnel/InboundGatewayReceiver.java

    r4c2d414 r855293d6  
    2323    }
    2424    public long receiveEncrypted(byte[] encrypted, boolean alreadySearched) {
     25        if (!alreadySearched)
     26            _config.incrementProcessedMessages();
    2527        if (_target == null) {
    2628            _target = _context.netDb().lookupRouterInfoLocally(_config.getSendTo());
     
    3436        }
    3537       
    36         _config.incrementProcessedMessages();
     38        if (_context.tunnelDispatcher().shouldDropParticipatingMessage())
     39            return -1;
     40        _config.incrementSentMessages();
    3741        TunnelDataMessage msg = new TunnelDataMessage(_context);
    3842        msg.setData(encrypted);
  • router/java/src/net/i2p/router/tunnel/OutboundTunnelEndpoint.java

    r4c2d414 r855293d6  
    4242                           + (toRouter != null ? toRouter.toBase64().substring(0,4) : "")
    4343                           + (toTunnel != null ? toTunnel.getTunnelId() + "" : ""));
     44            // don't drop it if we are the target
     45            if ((!_context.routerHash().equals(toRouter)) &&
     46                _context.tunnelDispatcher().shouldDropParticipatingMessage())
     47                return;
     48            _config.incrementSentMessages();
    4449            _outDistributor.distribute(msg, toRouter, toTunnel);
    4550        }
  • router/java/src/net/i2p/router/tunnel/TunnelDispatcher.java

    r4c2d414 r855293d6  
    1919import net.i2p.router.Service;
    2020import net.i2p.router.peermanager.PeerProfile;
     21import net.i2p.stat.Rate;
     22import net.i2p.stat.RateStat;
    2123import net.i2p.util.Log;
    2224
     
    111113                                         "Participating traffic", "Tunnels",
    112114                                         new long[] { 60*1000l, 60*10*1000l });
     115        ctx.statManager().createRateStat("tunnel.participatingBandwidthOut",
     116                                         "Participating traffic", "Tunnels",
     117                                         new long[] { 60*1000l, 60*10*1000l });
     118        ctx.statManager().createRateStat("tunnel.participatingMessageDropped",
     119                                         "Dropped for exceeding share limit", "Tunnels",
     120                                         new long[] { 60*1000l, 60*10*1000l });
    113121        ctx.statManager().createRateStat("tunnel.participatingMessageCount",
    114122                                         "How many messages are sent through a participating tunnel?", "Tunnels",
     
    551559        long count = 0;
    552560        long bw = 0;
     561        long bwOut = 0;
    553562        long tcount = 0;
    554563        long tooYoung = _context.clock().now() - 60*1000;
     
    558567            long c = cfg.getRecentMessagesCount();
    559568            bw += c;
     569            bwOut += cfg.getRecentSentMessagesCount();
    560570            long created = cfg.getCreation();
    561571            if (created > tooYoung || created < tooOld)
     
    568578        _context.statManager().addRateData("tunnel.participatingMessageCount", count, 20*1000);
    569579        _context.statManager().addRateData("tunnel.participatingBandwidth", bw*1024/20, 20*1000);
     580        _context.statManager().addRateData("tunnel.participatingBandwidthOut", bwOut*1024/20, 20*1000);
    570581        _context.statManager().addRateData("tunnel.participatingTunnels", size, 0);
     582    }
     583
     584    /**
     585     * Implement random early discard (RED) to enforce the share bandwidth limit.
     586     * For now, this does not enforce the available bandwidth,
     587     * we leave that to Throttle.
     588     * This is similar to the code in ../RouterThrottleImpl.java
     589     * We drop in proportion to how far over the limit we are.
     590     * Perhaps an exponential function would be better?
     591     */
     592    public boolean shouldDropParticipatingMessage() {
     593        RateStat rs = _context.statManager().getRate("tunnel.participatingBandwidth");
     594        if (rs == null)
     595            return false;
     596        Rate r = rs.getRate(60*1000);
     597        if (r == null)
     598            return false;
     599        // weight current period higher
     600        long count = r.getLastEventCount() + (3 * r.getCurrentEventCount());
     601        int bw = 0;
     602        if (count > 0)
     603            bw = (int) ((r.getLastTotalValue() + (3 * r.getCurrentTotalValue())) / count);
     604        else
     605            bw = (int) r.getLifetimeAverageValue();
     606
     607        int usedIn = Math.min(_context.router().get1sRateIn(), _context.router().get15sRateIn());
     608        usedIn = Math.min(usedIn, bw);
     609        if (usedIn <= 0)
     610            return false;
     611        int usedOut = Math.min(_context.router().get1sRate(true), _context.router().get15sRate(true));
     612        usedOut = Math.min(usedOut, bw);
     613        if (usedOut <= 0)
     614            return false;
     615        int used = Math.min(usedIn, usedOut);
     616        int maxKBps = Math.min(_context.bandwidthLimiter().getInboundKBytesPerSecond(),
     617                               _context.bandwidthLimiter().getOutboundKBytesPerSecond());
     618        float share = (float) _context.router().getSharePercentage();
     619
     620        // start dropping at 95% of the limit
     621        float maxBps = maxKBps * share * 1024f * 0.95f;
     622        float pctDrop = (used - maxBps) / used;
     623        if (pctDrop <= 0)
     624            return false;
     625        float rand = _context.random().nextFloat();
     626        boolean reject = rand <= pctDrop;
     627        if (reject) {
     628            if (_log.shouldLog(Log.WARN)) {
     629                int availBps = (int) (((maxKBps*1024)*share) - used);
     630                _log.warn("Drop part. msg. avail/max/used " + availBps + "/" + (int) maxBps + "/"
     631                          + used + " %Drop = " + pctDrop);
     632            }
     633            _context.statManager().addRateData("tunnel.participatingMessageDropped", 1, 0);
     634        }
     635        return reject;
    571636    }
    572637
     
    686751                }
    687752            }
    688             if (_log.shouldLog(Log.INFO)) {
     753            if (_log.shouldLog(Log.DEBUG)) {
    689754                long now = getContext().clock().now();
    690                 _log.info("Scheduling leave in " + DataHelper.formatDuration(dropTime.longValue()-now) +": " + cfg);
     755                _log.debug("Scheduling leave in " + DataHelper.formatDuration(dropTime.longValue()-now) +": " + cfg);
    691756            }
    692757        }
  • router/java/src/net/i2p/router/tunnel/TunnelParticipant.java

    r4c2d414 r855293d6  
    7676       
    7777        if ( (_config != null) && (_config.getSendTo() != null) ) {
     78            _config.incrementProcessedMessages();
    7879            RouterInfo ri = _nextHopCache;
    7980            if (ri == null)
     
    8384                    _log.debug("Send off to nextHop directly (" + _config.getSendTo().toBase64().substring(0,4)
    8485                              + " for " + msg);
    85                 _config.incrementProcessedMessages();
    8686                send(_config, msg, ri);
    87                 if (_config != null)
    88                     incrementThroughput(_config.getReceiveFrom());
     87                // see comments below
     88                //if (_config != null)
     89                //    incrementThroughput(_config.getReceiveFrom());
    8990            } else {
    9091                if (_log.shouldLog(Log.WARN))
     
    110111     * now.
    111112     */
     113/****
    112114    private void incrementThroughput(Hash prev) {
    113115        if (true) return;
     
    124126        }
    125127    }
     128****/
    126129   
    127130    public int getCompleteCount() {
     
    148151
    149152    private void send(HopConfig config, TunnelDataMessage msg, RouterInfo ri) {
     153        if (_context.tunnelDispatcher().shouldDropParticipatingMessage())
     154            return;
     155        _config.incrementSentMessages();
    150156        long oldId = msg.getUniqueId();
    151157        long newId = _context.random().nextLong(I2NPMessage.MAX_ID_VALUE);
Note: See TracChangeset for help on using the changeset viewer.