Changeset 54ec878


Ignore:
Timestamp:
Jul 19, 2013 12:18:08 AM (8 years ago)
Author:
str4d <str4d@…>
Branches:
master
Children:
8505e8a
Parents:
e93beb7 (diff), ea4606f (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

merge of '90720c051863f44c6386493f3d5df546d988a663'

and 'fa509893effa9445a0833115160aed8fe6fed268'

Files:
5 edited

Legend:

Unmodified
Added
Removed
  • apps/ministreaming/java/src/net/i2p/client/streaming/I2PSocketOptionsImpl.java

    re93beb7 r54ec878  
    9494    }
    9595   
     96    protected static double getDouble(Properties opts, String name, double defaultVal) {
     97        if (opts == null) return defaultVal;
     98        String val = opts.getProperty(name);
     99        if (val == null) {
     100            return defaultVal;
     101        } else {
     102            try {
     103                return Double.parseDouble(val);
     104            } catch (NumberFormatException nfe) {
     105                return defaultVal;
     106            }
     107        }
     108    }
     109   
    96110    /**
    97111     * How long we will wait for the ACK from a SYN, in milliseconds.
  • apps/streaming/java/src/net/i2p/client/streaming/ConnectionOptions.java

    re93beb7 r54ec878  
    2828    private int _rtt;
    2929    private int _rttDev;
    30     private int _rto;
     30    private int _rto = INITIAL_RTO;
    3131    private int _resendDelay;
    3232    private int _sendAckDelay;
     
    5252    private int _maxConns;
    5353    private boolean _disableRejectLog;
    54 
     54   
     55    /** state of a connection */
     56    private enum AckInit {
     57        INIT, // just created
     58        FIRST, // first received ack
     59        STEADY
     60    }
     61   
     62    /** LOCKING: this */
     63    private AckInit _initState = AckInit.INIT;
     64   
    5565    // NOTE - almost all the options are below, but see
    5666    // I2PSocketOptions in ministreaming for a few more
     
    6676    public static final int INACTIVITY_ACTION_SEND = 2;
    6777   
     78    /*
     79     * These values are specified in RFC 6298
     80     * Do not change unless you know what you're doing
     81     */
     82    private static final double TCP_ALPHA = 1.0/8;
     83    private static final double TCP_BETA = 1.0/4;
     84    private static final double TCP_KAPPA = 4;
     85   
     86    private static final String PROP_INITIAL_RTO = "i2p.streaming.initialRTO";
     87    private static final int INITIAL_RTO = 12000;
     88   
    6889    public static final String PROP_CONNECT_DELAY = "i2p.streaming.connectDelay";
    6990    public static final String PROP_PROFILE = "i2p.streaming.profile";
    7091    public static final String PROP_MAX_MESSAGE_SIZE = "i2p.streaming.maxMessageSize";
    7192    public static final String PROP_MAX_RESENDS = "i2p.streaming.maxResends";
    72     public static final String PROP_INITIAL_RTT = "i2p.streaming.initialRTT";
    7393    public static final String PROP_INITIAL_RESEND_DELAY = "i2p.streaming.initialResendDelay";
    7494    public static final String PROP_INITIAL_ACK_DELAY = "i2p.streaming.initialAckDelay";
     
    296316            setConnectDelay(opts.getConnectDelay());
    297317            setProfile(opts.getProfile());
     318            setRTTDev(opts.getRTTDev());
    298319            setRTT(opts.getRTT());
    299320            setRequireFullySigned(opts.getRequireFullySigned());
     
    333354        setProfile(getInt(opts, PROP_PROFILE, PROFILE_BULK));
    334355        setMaxMessageSize(getInt(opts, PROP_MAX_MESSAGE_SIZE, DEFAULT_MAX_MESSAGE_SIZE));
    335         setRTT(getInt(opts, PROP_INITIAL_RTT, DEFAULT_INITIAL_RTT));
    336356        setReceiveWindow(getInt(opts, PROP_INITIAL_RECEIVE_WINDOW, 1));
    337357        setResendDelay(getInt(opts, PROP_INITIAL_RESEND_DELAY, 1000));
     
    361381        _maxTotalConnsPerDay = getInt(opts, PROP_MAX_TOTAL_CONNS_DAY, 0);
    362382        _maxConns = getInt(opts, PROP_MAX_STREAMS, 0);
     383       
     384        _rto = getInt(opts, PROP_INITIAL_RTO, INITIAL_RTO);
    363385    }
    364386   
     
    378400        if (opts.containsKey(PROP_MAX_MESSAGE_SIZE))
    379401            setMaxMessageSize(getInt(opts, PROP_MAX_MESSAGE_SIZE, Packet.MAX_PAYLOAD_SIZE));
    380         if (opts.containsKey(PROP_INITIAL_RTT))
    381             setRTT(getInt(opts, PROP_INITIAL_RTT, DEFAULT_INITIAL_RTT));
    382402        if (opts.containsKey(PROP_INITIAL_RECEIVE_WINDOW))
    383403            setReceiveWindow(getInt(opts, PROP_INITIAL_RECEIVE_WINDOW, 1));
     
    428448        if (opts.containsKey(PROP_MAX_STREAMS))
    429449            _maxConns = getInt(opts, PROP_MAX_STREAMS, 0);
     450       
     451        _rto = getInt(opts, PROP_INITIAL_RTO, INITIAL_RTO);
    430452    }
    431453   
     
    516538     * @return round trip time estimate in ms
    517539     */
    518     public int getRTT() { return _rtt; }
     540    public synchronized int getRTT() { return _rtt; }
    519541    public void setRTT(int ms) {
    520         if (_rto == 0) {
    521             _rttDev = ms / 2;
    522             _rto = ms + ms / 2;
    523         }
    524542        synchronized (_trend) {
    525543            _trend[0] = _trend[1];
     
    533551        }
    534552       
    535         _rtt = ms;
    536         if (_rtt > 60*1000)
    537             _rtt = 60*1000;
    538     }
    539 
    540     public int getRTO() { return _rto; }
    541 
    542     /** for debugging @since 0.7.13 */
    543     int getRTTDev() { return _rttDev; }
     553        synchronized(this) {
     554            _rtt = ms;
     555            if (_rtt > 60*1000)
     556                _rtt = 60*1000;
     557        }
     558    }
     559
     560    public synchronized int getRTO() { return _rto; }
     561
     562    /** used in TCB @since 0.9.8 */
     563    synchronized int getRTTDev() { return _rttDev; }
     564    private synchronized void setRTTDev(int rttDev) { _rttDev = rttDev; }
     565   
     566    /**
     567     * Loads options from TCB cache.
     568     */
     569    synchronized void loadFromCache(int rtt, int rttDev, int wdw) {
     570        _initState = AckInit.STEADY;
     571        setRTT(rtt);
     572        setRTTDev(rttDev);
     573        setWindowSize(wdw);
     574        computeRTO();
     575    }
     576   
     577    /**
     578     * computes RTO based on formula in RFC
     579     */
     580    private synchronized void computeRTO() {
     581        switch(_initState) {
     582        case INIT :
     583            throw new IllegalStateException();
     584        case FIRST :
     585            _rto = _rtt + _rtt / 2;
     586            break;
     587        case STEADY :
     588            _rto = _rtt + (int) (_rttDev * TCP_KAPPA);
     589            break;
     590        }
     591       
     592        if (_rto < Connection.MIN_RESEND_DELAY)
     593            _rto = (int)Connection.MIN_RESEND_DELAY;
     594        else if (_rto > Connection.MAX_RESEND_DELAY)
     595            _rto = (int)Connection.MAX_RESEND_DELAY;
     596    }
    544597   
    545598    /**
     
    559612    }
    560613   
    561     /** rtt = rtt*RTT_DAMPENING + (1-RTT_DAMPENING)*currentPacketRTT */
    562     /** This is the value specified in RFC 2988, let's try it */
    563     private static final double RTT_DAMPENING = 0.875;
    564    
    565     public void updateRTT(int measuredValue) {
    566         // the rttDev calculation matches that recommended in RFC 2988 (beta = 1/4)
    567         _rttDev = _rttDev + (int)(0.25d*(Math.abs(measuredValue-_rtt)-_rttDev));
    568         int smoothed = (int)(RTT_DAMPENING*_rtt + (1-RTT_DAMPENING)*measuredValue);       
    569         // K = 4
    570         _rto = smoothed + (_rttDev<<2);
    571         if (_rto < Connection.MIN_RESEND_DELAY)
    572             _rto = (int)Connection.MIN_RESEND_DELAY;
    573         else if (_rto > Connection.MAX_RESEND_DELAY)
    574             _rto = (int)Connection.MAX_RESEND_DELAY;
    575 
    576         setRTT(smoothed);
     614    public synchronized void updateRTT(int measuredValue) {
     615        switch(_initState) {
     616        case INIT:
     617            _initState = AckInit.FIRST;
     618            setRTT(measuredValue); // no smoothing first sample
     619            _rttDev = _rtt / 2;
     620            break;
     621        case FIRST:
     622            _initState = AckInit.STEADY; // fall through
     623        case STEADY:
     624            // calculation matches that recommended in RFC 6298
     625            _rttDev = (int) ((1-TCP_BETA) *_rttDev  + TCP_BETA * Math.abs(measuredValue-_rtt));
     626            int smoothed = (int)((1-TCP_ALPHA)*_rtt + TCP_ALPHA*measuredValue);       
     627            setRTT(smoothed);
     628        }
     629        computeRTO();
    577630    }
    578631   
  • apps/streaming/java/src/net/i2p/client/streaming/TCBShare.java

    re93beb7 r54ec878  
    33import java.util.Iterator;
    44import java.util.Map;
     5import java.util.Properties;
    56import java.util.concurrent.ConcurrentHashMap;
    67
     
    910import net.i2p.util.Log;
    1011import net.i2p.util.SimpleTimer2;
     12
     13import static net.i2p.client.streaming.I2PSocketOptionsImpl.getDouble;
    1114
    1215/**
     
    2629    private final Map<Destination, Entry> _cache;
    2730    private final CleanEvent _cleaner;
     31    private final double _rttDampening, _wdwDampening, _rttDevDampening;
    2832
    2933    private static final long EXPIRE_TIME = 30*60*1000;
    3034    private static final long CLEAN_TIME = 10*60*1000;
     35    ///// constants defined in rfc 2140
     36    ///// do not change unless you know what you're doing
    3137    private static final double RTT_DAMPENING = 0.75;
     38    private static final double RTTDEV_DAMPENING = 0.75;
    3239    private static final double WDW_DAMPENING = 0.75;
     40    private static final String RTT_DAMP_PROP="i2p.streaming.tcbcache.rttDampening";
     41    private static final String WDW_DAMP_PROP="i2p.streaming.tcbcache.wdwDampening";
     42    private static final String RTTDEV_DAMP_PROP="i2p.streaming.tcbcache.rttDampening";
     43    /////
    3344    private static final int MAX_RTT = ((int) Connection.MAX_RESEND_DELAY) / 2;
     45    private static final int MAX_RTT_DEV = (int) (MAX_RTT * 1.5);
    3446    private static final int MAX_WINDOW_SIZE = ConnectionPacketHandler.MAX_SLOW_START_WINDOW;
    3547   
     
    3749        _context = ctx;
    3850        _log = ctx.logManager().getLog(TCBShare.class);
     51       
     52        final Properties props = ctx.getProperties();
     53        _rttDampening = getDouble(props, RTT_DAMP_PROP, RTT_DAMPENING);
     54        _wdwDampening = getDouble(props, WDW_DAMP_PROP, WDW_DAMPENING);
     55        _rttDevDampening = getDouble(props, RTTDEV_DAMP_PROP, RTTDEV_DAMPENING);
     56       
    3957        _cache = new ConcurrentHashMap<Destination,Entry>(4);
    4058        _cleaner = new CleanEvent(timer);
    4159        _cleaner.schedule(CLEAN_TIME);
     60       
     61        if (_log.shouldLog(Log.DEBUG)) {
     62            String log = "Creating TCBCache with rttDamp=%s, rttDevDamp=%s, wdwDamp=%s, "+
     63                    "expire=%d, clean=%d";
     64            log = String.format(log,_rttDampening,_rttDevDampening,_wdwDampening,
     65                    EXPIRE_TIME,CLEAN_TIME);
     66             _log.debug(log);
     67        }
    4268    }
    4369
     
    6187        if (e == null || e.isExpired())
    6288            return;
    63         if (_log.shouldLog(Log.DEBUG))
     89        final int rtt, rttDev, wdw;
     90        synchronized(e) {
     91            rtt = e.getRTT();
     92            rttDev = e.getRTTDev();
     93            wdw = e.getWindowSize();
     94        }
     95        if (_log.shouldLog(Log.DEBUG)) {
    6496            _log.debug("From cache: " +
    6597                       con.getSession().getMyDestination().calculateHash().toBase64().substring(0, 4) +
    6698                       '-' +
    6799                       dest.calculateHash().toBase64().substring(0, 4) +
    68                        " RTT: " + e.getRTT() + " wdw: " + e.getWindowSize());
    69         opts.setRTT(e.getRTT());
    70         opts.setWindowSize(e.getWindowSize());
     100                       " RTT: " + rtt +
     101                       " RTTDev: "+ rttDev +
     102                       " wdw: " + wdw );
     103        }
     104        opts.loadFromCache(rtt,rttDev,wdw);
    71105    }
    72106
     
    83117        int old = -1;
    84118        int oldw = -1;
     119        int oldDev = -1;
    85120        Entry e = _cache.get(dest);
    86121        if (e == null || e.isExpired()) {
    87             e = new Entry(opts.getRTT(), opts.getWindowSize());
     122            e = new Entry(opts.getRTT(), opts.getWindowSize(), opts.getRTTDev());
    88123            _cache.put(dest, e);
    89124        } else {
     
    91126                old = e.getRTT();
    92127                oldw = e.getWindowSize();
     128                oldDev = e.getRTTDev();
    93129                e.setRTT(opts.getRTT());
    94130                e.setWindowSize(opts.getWindowSize());
     131                e.setRTTDev(opts.getRTTDev());
    95132            }
    96133        }
    97         if (_log.shouldLog(Log.DEBUG))
     134        if (_log.shouldLog(Log.DEBUG)) {
    98135            _log.debug("To cache: " +
    99136                       con.getSession().getMyDestination().calculateHash().toBase64().substring(0, 4) +
     
    101138                       dest.calculateHash().toBase64().substring(0, 4) +
    102139                       " old: " + old + " con: " + opts.getRTT() + " new: " + e.getRTT() +
     140                       " oldDev: " + oldDev + " conDev: " + opts.getRTTDev() + " newDev: " + e.getRTTDev() +
    103141                       " oldw: " + oldw + " conw: " + opts.getWindowSize() + " neww: " + e.getWindowSize());
     142        }
    104143    }
    105144
     
    107146        int _rtt;
    108147        int _wdw;
     148        int _rttDev;
    109149        long _updated;
    110150
    111         public Entry(int ms, int wdw) {
     151        public Entry(int ms, int wdw, int rttDev) {
    112152            _rtt = ms;
    113153            _wdw = wdw;
     154            _rttDev = rttDev;
    114155            _updated = _context.clock().now();
    115156        }
    116157        public synchronized int getRTT() { return _rtt; }
    117158        public synchronized void setRTT(int ms) {
    118             _rtt = (int)(RTT_DAMPENING*_rtt + (1-RTT_DAMPENING)*ms);       
     159            _rtt = (int)(_rttDampening*_rtt + (1-_rttDampening)*ms);       
    119160            if (_rtt > MAX_RTT)
    120161                _rtt = MAX_RTT;
    121162            _updated = _context.clock().now();
    122163        }
     164        public synchronized int getRTTDev() { return _rttDev; }
     165        public synchronized void setRTTDev(int count) {
     166            _rttDev = (int)(_rttDevDampening*_rttDev + (1-_rttDevDampening)*count);       
     167            if (_rttDev > MAX_RTT_DEV)
     168                _rttDev = MAX_RTT_DEV;
     169            _updated = _context.clock().now();
     170        }
    123171        public synchronized int getWindowSize() { return _wdw; }
    124172        public synchronized void setWindowSize(int wdw) {
    125             _wdw = (int)(0.5 + WDW_DAMPENING*_wdw + (1-WDW_DAMPENING)*wdw);       
     173            _wdw = (int)(0.5 + _wdwDampening*_wdw + (1-_wdwDampening)*wdw);       
    126174            if (_wdw > MAX_WINDOW_SIZE)
    127175                _wdw = MAX_WINDOW_SIZE;
  • history.txt

    re93beb7 r54ec878  
     12012-07-19 zab
     2* Streaming:
     3  - initialize streaming RTT from sample, trac #979, RFC 6298
     4  - store rttDev in TCBCache
     5
    16* 2013-07-15 0.9.7 released
    27
  • router/java/src/net/i2p/router/RouterVersion.java

    re93beb7 r54ec878  
    1919    public final static String ID = "Monotone";
    2020    public final static String VERSION = CoreVersion.VERSION;
    21     public final static long BUILD = 0;
     21    public final static long BUILD = 1;
    2222
    2323    /** for example "-test" */
Note: See TracChangeset for help on using the changeset viewer.