diff options
Diffstat (limited to 'toxcore')
-rw-r--r-- | toxcore/net_crypto.c | 73 | ||||
-rw-r--r-- | toxcore/net_crypto.h | 3 |
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. */ |