summaryrefslogtreecommitdiff
path: root/toxcore
diff options
context:
space:
mode:
authornotsecure <notsecure@marek.ca>2014-05-22 20:19:19 -0400
committernotsecure <notsecure@marek.ca>2014-05-22 20:19:19 -0400
commite3bc591b3b52a64d8dc47f0f02185577e729ff54 (patch)
treed81a5057e9c44e17d280c992249a41972931e351 /toxcore
parent1e4eb83880899f0e1d7c3bcc19f224c705194f25 (diff)
more conjestion control
needs testing
Diffstat (limited to 'toxcore')
-rw-r--r--toxcore/net_crypto.c73
-rw-r--r--toxcore/net_crypto.h3
2 files changed, 62 insertions, 14 deletions
diff --git a/toxcore/net_crypto.c b/toxcore/net_crypto.c
index 196dde4b..3dd8f885 100644
--- a/toxcore/net_crypto.c
+++ b/toxcore/net_crypto.c
@@ -2189,27 +2189,73 @@ static void send_crypto_packets(Net_Crypto *c)
2189 conn->packet_counter = 0; 2189 conn->packet_counter = 0;
2190 conn->packet_counter_set = temp_time; 2190 conn->packet_counter_set = temp_time;
2191 2191
2192 //most important constant, higher makes it less agressive (minimize packet loss) 2192 /* conjestion control
2193 //keep it >=0 2193 calculate a new value of conn->packet_send_rate based on some data
2194#define RATE_ADD_POWER 100.0 2194 notes: needs improvement but seems to work fine for packet loss <1%
2195 */
2196
2197 //hack to prevent 1 packet lost from affecting calculations at low send rates
2198 if (conn->packets_resent == 1) {
2199 conn->packets_resent = 0;
2200 }
2201
2202 //new "dropped" value: weighted average of previous value and packet drop rate measured by the number of packets which were resends of previous packets
2203 double dropped = (conn->dropped) * 0.5 + (conn->packets_resent / dt) * 0.5;
2204
2205 //since the "dropped" packets measure is delayed in time from the actual # of dropped packets,
2206 // ignore dropped packet measure for a second after it becomes high and the send rate is lowered as a result
2207 double drop_ignore_new;
2208
2209 if (conn->drop_ignore_start + 1000 < temp_time) {
2210 drop_ignore_new = 0.0;
2211
2212 if ((dropped * 1000.0) / conn->packet_send_rate >= 0.10) {
2213 conn->drop_ignore_start = temp_time;
2214 }
2215 } else {
2216 drop_ignore_new = (dropped > conn->drop_ignore) ? dropped : conn->drop_ignore;
2217 }
2195 2218
2196 double dropped = (conn->dropped + (double)conn->packets_resent / dt) / 2.0; 2219 //calculate the "real" send rate (send rate - drop rate)
2197 double realrate = (conn->packet_send_rate - dropped * 1000.0); 2220 double r = conn->packet_send_rate;
2221 double realrate = (r - (dropped - drop_ignore_new) * 1000.0);
2198 2222
2199 //newrate is reduced rate based on dropped packets 2223 if (dropped < drop_ignore_new) {
2200 double newrate = (realrate + conn->packet_send_rate) / 2.0; 2224 realrate = r;
2225 }
2201 2226
2202 //rate_add is rate increase (needs to be improved)
2203 double ratio = realrate / conn->packet_send_rate;
2204 double rate_add = (newrate / 40.0 + sqrt(newrate)) * pow(ratio, RATE_ADD_POWER);;
2205 2227
2206 conn->packet_send_rate = newrate + rate_add; 2228 //calculate exponential increase in rate, triggered when drop rate is below 5% for 5 seconds
2229 if ((dropped * 1000.0) / conn->packet_send_rate >= 0.05) {
2230 conn->rate_increase_stop_start = temp_time;
2231 }
2232
2233 if (conn->rate_increase_stop_start + 5000 < temp_time) {
2234 if (conn->rate_increase < 1.0) {
2235 conn->rate_increase = 1.0;
2236 }
2237
2238 conn->rate_increase *= pow(1.1, pow(realrate / r, 10.0));;
2239 } else {
2240 conn->rate_increase = 0.0;
2241 }
2242
2243
2244 //"constant" linear increase in rate
2245 double linear_increase = realrate * 0.0025 + 1.0;
2246
2247 //final send rate: average of "real" and previous send rates + increases
2248 conn->packet_send_rate = (realrate + conn->packet_send_rate) / 2.0 + conn->rate_increase + linear_increase;
2249
2207 2250
2208 conn->dropped = dropped; 2251 conn->dropped = dropped;
2252 conn->drop_ignore = drop_ignore_new;
2209 conn->packets_resent = 0; 2253 conn->packets_resent = 0;
2210 2254
2211 if (conn->packet_send_rate < CRYPTO_PACKET_MIN_RATE || !conn->sending) 2255 if (conn->packet_send_rate < CRYPTO_PACKET_MIN_RATE || !conn->sending) {
2256 conn->rate_increase = 0;
2212 conn->packet_send_rate = CRYPTO_PACKET_MIN_RATE; 2257 conn->packet_send_rate = CRYPTO_PACKET_MIN_RATE;
2258 }
2213 2259
2214 if (conn->packet_send_rate > CRYPTO_PACKET_BUFFER_SIZE * 2) 2260 if (conn->packet_send_rate > CRYPTO_PACKET_BUFFER_SIZE * 2)
2215 conn->packet_send_rate = CRYPTO_PACKET_BUFFER_SIZE * 2; 2261 conn->packet_send_rate = CRYPTO_PACKET_BUFFER_SIZE * 2;
@@ -2233,9 +2279,10 @@ static void send_crypto_packets(Net_Crypto *c)
2233 2279
2234 int ret = send_requested_packets(c, i, conn->packets_left); 2280 int ret = send_requested_packets(c, i, conn->packets_left);
2235 2281
2236 conn->packets_resent += ret; 2282
2237 2283
2238 if (ret != -1) { 2284 if (ret != -1) {
2285 conn->packets_resent += ret;
2239 conn->packets_left -= ret; 2286 conn->packets_left -= ret;
2240 } 2287 }
2241 2288
diff --git a/toxcore/net_crypto.h b/toxcore/net_crypto.h
index de6c9c7a..995b6f67 100644
--- a/toxcore/net_crypto.h
+++ b/toxcore/net_crypto.h
@@ -137,7 +137,8 @@ typedef struct {
137 uint32_t packets_left; 137 uint32_t packets_left;
138 uint64_t last_packets_left_set; 138 uint64_t last_packets_left_set;
139 139
140 double dropped; 140 double dropped, drop_ignore, rate_increase;
141 uint64_t drop_ignore_start, rate_increase_stop_start;
141 uint32_t packets_resent; 142 uint32_t packets_resent;
142 143
143 uint8_t sending; /* indicates if data is being sent or not. */ 144 uint8_t sending; /* indicates if data is being sent or not. */