I2P Address: [http://git.idk.i2p]

Skip to content
Snippets Groups Projects
Verified Commit aed1de84 authored by zzz's avatar zzz
Browse files

SSU: Fix bandwidth estimator deadlock (ticket #2798)

Fix logging in SBE (bytes not packets)
parent 51560a8e
No related branches found
No related tags found
No related merge requests found
2021-01-08 zzz
* i2ptunnel: Disable shared clients (DSA) (part 2)
* SSU: Fix bandwidth estimator deadlock (ticket #2798)
2021-01-07 zzz
* Router: Disable reseeding and NTP in vmCommSystem
* SSU: Implement fast retransmit (ticket #2427)
 
2021-01-05 zzz
......
......@@ -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 = 12;
public final static long BUILD = 13;
/** for example "-test" */
public final static String EXTRA = "";
......
......@@ -25,6 +25,7 @@ class SimpleBandwidthEstimator implements BandwidthEstimator {
private final I2PAppContext _context;
private final Log _log;
// access outside lock on SBE to avoid deadlock
private final PeerState _state;
private long _tAck;
......@@ -51,8 +52,14 @@ class SimpleBandwidthEstimator implements BandwidthEstimator {
* Records an arriving ack.
* @param acked how many bytes were acked with this ack
*/
public synchronized void addSample(int acked) {
public void addSample(int acked) {
long now = _context.clock().now();
// avoid deadlock
int rtt = _state.getRTT();
addSample(acked, now, rtt);
}
private synchronized void addSample(int acked, long now, int rtt) {
if (_acked < 0) {
// first sample
// use time since constructed as the RTT
......@@ -64,34 +71,38 @@ class SimpleBandwidthEstimator implements BandwidthEstimator {
_acked = 0;
_tAck = now;
if (_log.shouldDebug())
_log.debug("first sample packets: " + acked + " deltaT: " + deltaT + ' ' + this);
_log.debug("first sample bytes: " + acked + " deltaT: " + deltaT + ' ' + this);
} else {
_acked += acked;
// anti-aliasing filter
// As in kernel tcp_westwood.c
// and the Westwood+ paper
if (now - _tAck >= Math.max(_state.getRTT(), WESTWOOD_RTT_MIN))
computeBWE(now);
if (now - _tAck >= Math.max(rtt, WESTWOOD_RTT_MIN))
computeBWE(now, rtt);
}
}
/**
* @return the current bandwidth estimate in bytes/ms.
*/
public synchronized float getBandwidthEstimate() {
public float getBandwidthEstimate() {
long now = _context.clock().now();
// avoid deadlock
int rtt = _state.getRTT();
// anti-aliasing filter
// As in kernel tcp_westwood.c
// and the Westwood+ paper
if (now - _tAck >= Math.max(_state.getRTT(), WESTWOOD_RTT_MIN))
return computeBWE(now);
return _bKFiltered;
synchronized(this) {
if (now - _tAck >= Math.max(rtt, WESTWOOD_RTT_MIN))
return computeBWE(now, rtt);
return _bKFiltered;
}
}
private synchronized float computeBWE(final long now) {
private synchronized float computeBWE(final long now, final int rtt) {
if (_acked < 0)
return 0.0f; // nothing ever sampled
updateBK(now, _acked);
updateBK(now, _acked, rtt);
_acked = 0;
return _bKFiltered;
}
......@@ -110,11 +121,13 @@ class SimpleBandwidthEstimator implements BandwidthEstimator {
* time-varying filter, as in kernel tcp_westwood.c
*
* @param time the time of the measurement
* @param packets number of packets acked
* @param packets number of bytes acked
* @param rtt current rtt
*/
private void updateBK(long time, int packets) {
private void updateBK(long time, int packets, int rtt) {
long deltaT = time - _tAck;
int rtt = Math.max(_state.getRTT(), WESTWOOD_RTT_MIN);
if (rtt < WESTWOOD_RTT_MIN)
rtt = WESTWOOD_RTT_MIN;
if (deltaT > 2 * rtt) {
// Decay with virtual null samples as in the Westwood paper
int numrtts = Math.min((int) ((deltaT / rtt) - 1), 2 * DECAY_FACTOR);
......@@ -137,7 +150,7 @@ class SimpleBandwidthEstimator implements BandwidthEstimator {
}
_tAck = time;
if (_log.shouldDebug())
_log.debug("computeBWE packets: " + packets + " deltaT: " + deltaT +
_log.debug("computeBWE bytes: " + packets + " deltaT: " + deltaT +
" bk/deltaT: " + bkdt + " _bK_ns_est: " + _bK_ns_est + ' ' + this);
}
......@@ -153,7 +166,7 @@ class SimpleBandwidthEstimator implements BandwidthEstimator {
return "SBE[" +
" _bKFiltered " + _bKFiltered +
" _tAck " + _tAck + "; " +
DataHelper.formatSize2Decimal((long) (_bKFiltered * 1000 * _state.getMTU()), false) +
DataHelper.formatSize2Decimal((long) (_bKFiltered * 1000), false) +
"Bps]";
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment