From 3ceb64db2e34c71358fec9601252f401dc71c88e Mon Sep 17 00:00:00 2001
From: Vort <vvort@yandex.ru>
Date: Wed, 6 Mar 2024 14:54:02 +0200
Subject: [PATCH] 1. Use EWMA for stream RTT estimation;

2. Drop window size by 10% instead of 50% in case of resend.

Change is based on code by onon.
---
 libi2pd/Streaming.cpp | 9 ++++++---
 libi2pd/Streaming.h   | 2 ++
 2 files changed, 8 insertions(+), 3 deletions(-)

diff --git a/libi2pd/Streaming.cpp b/libi2pd/Streaming.cpp
index fa809c19..f6518163 100644
--- a/libi2pd/Streaming.cpp
+++ b/libi2pd/Streaming.cpp
@@ -433,7 +433,10 @@ namespace stream
 					LogPrint(eLogError, "Streaming: Packet ", seqn, "sent from the future, sendTime=", sentPacket->sendTime);
 					rtt = 1;
 				}
-				m_RTT = std::round ((m_RTT*seqn + rtt)/(seqn + 1.0));
+				if (seqn)
+					m_RTT = std::round (RTT_EWMA_ALPHA * m_RTT + (1.0 - RTT_EWMA_ALPHA) * rtt);
+				else
+					m_RTT = rtt;
 				m_RTO = m_RTT*1.5; // TODO: implement it better
 				LogPrint (eLogDebug, "Streaming: Packet ", seqn, " acknowledged rtt=", rtt, " sentTime=", sentPacket->sendTime);
 				m_SentPackets.erase (it++);
@@ -998,8 +1001,8 @@ namespace stream
 				m_RTO *= 2;
 				switch (m_NumResendAttempts)
 				{
-					case 1: // congesion avoidance
-						m_WindowSize >>= 1; // /2
+					case 1: // congestion avoidance
+						m_WindowSize -= (m_WindowSize + WINDOW_SIZE_DROP_FRACTION) / WINDOW_SIZE_DROP_FRACTION; // adjustment >= 1
 						if (m_WindowSize < MIN_WINDOW_SIZE) m_WindowSize = MIN_WINDOW_SIZE;
 					break;
 					case 2:
diff --git a/libi2pd/Streaming.h b/libi2pd/Streaming.h
index ed79edc9..1980b6fd 100644
--- a/libi2pd/Streaming.h
+++ b/libi2pd/Streaming.h
@@ -56,6 +56,8 @@ namespace stream
 	const int WINDOW_SIZE = 6; // in messages
 	const int MIN_WINDOW_SIZE = 1;
 	const int MAX_WINDOW_SIZE = 128;
+	const int WINDOW_SIZE_DROP_FRACTION = 10; // 1/10
+	const double RTT_EWMA_ALPHA = 0.5;
 	const int INITIAL_RTT = 8000; // in milliseconds
 	const int INITIAL_RTO = 9000; // in milliseconds
 	const int MIN_SEND_ACK_TIMEOUT = 2; // in milliseconds