├── .gitignore ├── Cargo.lock ├── Cargo.toml └── src ├── agg_measurement.rs ├── bin └── copa.rs ├── delta_manager.rs ├── lib.rs └── rtt_window.rs /.gitignore: -------------------------------------------------------------------------------- 1 | target 2 | *.rustfmt 3 | -------------------------------------------------------------------------------- /Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | [[package]] 4 | name = "aho-corasick" 5 | version = "0.7.13" 6 | source = "registry+https://github.com/rust-lang/crates.io-index" 7 | dependencies = [ 8 | "memchr 2.3.3 (registry+https://github.com/rust-lang/crates.io-index)", 9 | ] 10 | 11 | [[package]] 12 | name = "ansi_term" 13 | version = "0.11.0" 14 | source = "registry+https://github.com/rust-lang/crates.io-index" 15 | dependencies = [ 16 | "winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", 17 | ] 18 | 19 | [[package]] 20 | name = "arrayref" 21 | version = "0.3.6" 22 | source = "registry+https://github.com/rust-lang/crates.io-index" 23 | 24 | [[package]] 25 | name = "arrayvec" 26 | version = "0.5.1" 27 | source = "registry+https://github.com/rust-lang/crates.io-index" 28 | 29 | [[package]] 30 | name = "atty" 31 | version = "0.2.14" 32 | source = "registry+https://github.com/rust-lang/crates.io-index" 33 | dependencies = [ 34 | "hermit-abi 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)", 35 | "libc 0.2.74 (registry+https://github.com/rust-lang/crates.io-index)", 36 | "winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", 37 | ] 38 | 39 | [[package]] 40 | name = "autocfg" 41 | version = "1.0.0" 42 | source = "registry+https://github.com/rust-lang/crates.io-index" 43 | 44 | [[package]] 45 | name = "base64" 46 | version = "0.11.0" 47 | source = "registry+https://github.com/rust-lang/crates.io-index" 48 | 49 | [[package]] 50 | name = "bitflags" 51 | version = "0.9.1" 52 | source = "registry+https://github.com/rust-lang/crates.io-index" 53 | 54 | [[package]] 55 | name = "bitflags" 56 | version = "1.2.1" 57 | source = "registry+https://github.com/rust-lang/crates.io-index" 58 | 59 | [[package]] 60 | name = "blake2b_simd" 61 | version = "0.5.10" 62 | source = "registry+https://github.com/rust-lang/crates.io-index" 63 | dependencies = [ 64 | "arrayref 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", 65 | "arrayvec 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", 66 | "constant_time_eq 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", 67 | ] 68 | 69 | [[package]] 70 | name = "byteorder" 71 | version = "1.3.4" 72 | source = "registry+https://github.com/rust-lang/crates.io-index" 73 | 74 | [[package]] 75 | name = "bytes" 76 | version = "0.4.12" 77 | source = "registry+https://github.com/rust-lang/crates.io-index" 78 | dependencies = [ 79 | "byteorder 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)", 80 | "iovec 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", 81 | ] 82 | 83 | [[package]] 84 | name = "cc" 85 | version = "1.0.59" 86 | source = "registry+https://github.com/rust-lang/crates.io-index" 87 | 88 | [[package]] 89 | name = "ccp_copa" 90 | version = "0.1.1" 91 | dependencies = [ 92 | "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", 93 | "portus 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)", 94 | "slog 2.5.2 (registry+https://github.com/rust-lang/crates.io-index)", 95 | "slog-async 2.5.0 (registry+https://github.com/rust-lang/crates.io-index)", 96 | "slog-term 2.6.0 (registry+https://github.com/rust-lang/crates.io-index)", 97 | "time 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)", 98 | ] 99 | 100 | [[package]] 101 | name = "cfg-if" 102 | version = "0.1.10" 103 | source = "registry+https://github.com/rust-lang/crates.io-index" 104 | 105 | [[package]] 106 | name = "chrono" 107 | version = "0.4.15" 108 | source = "registry+https://github.com/rust-lang/crates.io-index" 109 | dependencies = [ 110 | "num-integer 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)", 111 | "num-traits 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)", 112 | "time 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)", 113 | ] 114 | 115 | [[package]] 116 | name = "clap" 117 | version = "2.33.3" 118 | source = "registry+https://github.com/rust-lang/crates.io-index" 119 | dependencies = [ 120 | "ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", 121 | "atty 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)", 122 | "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", 123 | "strsim 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", 124 | "textwrap 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", 125 | "unicode-width 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", 126 | "vec_map 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", 127 | ] 128 | 129 | [[package]] 130 | name = "colored" 131 | version = "1.9.3" 132 | source = "registry+https://github.com/rust-lang/crates.io-index" 133 | dependencies = [ 134 | "atty 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)", 135 | "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", 136 | "winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", 137 | ] 138 | 139 | [[package]] 140 | name = "constant_time_eq" 141 | version = "0.1.5" 142 | source = "registry+https://github.com/rust-lang/crates.io-index" 143 | 144 | [[package]] 145 | name = "crossbeam" 146 | version = "0.7.3" 147 | source = "registry+https://github.com/rust-lang/crates.io-index" 148 | dependencies = [ 149 | "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", 150 | "crossbeam-channel 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", 151 | "crossbeam-deque 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", 152 | "crossbeam-epoch 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", 153 | "crossbeam-queue 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", 154 | "crossbeam-utils 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", 155 | ] 156 | 157 | [[package]] 158 | name = "crossbeam-channel" 159 | version = "0.4.3" 160 | source = "registry+https://github.com/rust-lang/crates.io-index" 161 | dependencies = [ 162 | "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", 163 | "crossbeam-utils 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", 164 | ] 165 | 166 | [[package]] 167 | name = "crossbeam-deque" 168 | version = "0.7.3" 169 | source = "registry+https://github.com/rust-lang/crates.io-index" 170 | dependencies = [ 171 | "crossbeam-epoch 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", 172 | "crossbeam-utils 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", 173 | "maybe-uninit 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)", 174 | ] 175 | 176 | [[package]] 177 | name = "crossbeam-epoch" 178 | version = "0.8.2" 179 | source = "registry+https://github.com/rust-lang/crates.io-index" 180 | dependencies = [ 181 | "autocfg 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", 182 | "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", 183 | "crossbeam-utils 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", 184 | "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", 185 | "maybe-uninit 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)", 186 | "memoffset 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)", 187 | "scopeguard 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", 188 | ] 189 | 190 | [[package]] 191 | name = "crossbeam-queue" 192 | version = "0.2.3" 193 | source = "registry+https://github.com/rust-lang/crates.io-index" 194 | dependencies = [ 195 | "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", 196 | "crossbeam-utils 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", 197 | "maybe-uninit 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)", 198 | ] 199 | 200 | [[package]] 201 | name = "crossbeam-utils" 202 | version = "0.7.2" 203 | source = "registry+https://github.com/rust-lang/crates.io-index" 204 | dependencies = [ 205 | "autocfg 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", 206 | "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", 207 | "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", 208 | ] 209 | 210 | [[package]] 211 | name = "dirs" 212 | version = "2.0.2" 213 | source = "registry+https://github.com/rust-lang/crates.io-index" 214 | dependencies = [ 215 | "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", 216 | "dirs-sys 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", 217 | ] 218 | 219 | [[package]] 220 | name = "dirs-sys" 221 | version = "0.3.5" 222 | source = "registry+https://github.com/rust-lang/crates.io-index" 223 | dependencies = [ 224 | "libc 0.2.74 (registry+https://github.com/rust-lang/crates.io-index)", 225 | "redox_users 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", 226 | "winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", 227 | ] 228 | 229 | [[package]] 230 | name = "either" 231 | version = "1.6.0" 232 | source = "registry+https://github.com/rust-lang/crates.io-index" 233 | 234 | [[package]] 235 | name = "fnv" 236 | version = "1.0.7" 237 | source = "registry+https://github.com/rust-lang/crates.io-index" 238 | 239 | [[package]] 240 | name = "getrandom" 241 | version = "0.1.14" 242 | source = "registry+https://github.com/rust-lang/crates.io-index" 243 | dependencies = [ 244 | "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", 245 | "libc 0.2.74 (registry+https://github.com/rust-lang/crates.io-index)", 246 | "wasi 0.9.0+wasi-snapshot-preview1 (registry+https://github.com/rust-lang/crates.io-index)", 247 | ] 248 | 249 | [[package]] 250 | name = "heck" 251 | version = "0.3.1" 252 | source = "registry+https://github.com/rust-lang/crates.io-index" 253 | dependencies = [ 254 | "unicode-segmentation 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)", 255 | ] 256 | 257 | [[package]] 258 | name = "hermit-abi" 259 | version = "0.1.15" 260 | source = "registry+https://github.com/rust-lang/crates.io-index" 261 | dependencies = [ 262 | "libc 0.2.74 (registry+https://github.com/rust-lang/crates.io-index)", 263 | ] 264 | 265 | [[package]] 266 | name = "iovec" 267 | version = "0.1.4" 268 | source = "registry+https://github.com/rust-lang/crates.io-index" 269 | dependencies = [ 270 | "libc 0.2.74 (registry+https://github.com/rust-lang/crates.io-index)", 271 | ] 272 | 273 | [[package]] 274 | name = "itertools" 275 | version = "0.8.2" 276 | source = "registry+https://github.com/rust-lang/crates.io-index" 277 | dependencies = [ 278 | "either 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)", 279 | ] 280 | 281 | [[package]] 282 | name = "lazy_static" 283 | version = "1.4.0" 284 | source = "registry+https://github.com/rust-lang/crates.io-index" 285 | 286 | [[package]] 287 | name = "libc" 288 | version = "0.2.74" 289 | source = "registry+https://github.com/rust-lang/crates.io-index" 290 | 291 | [[package]] 292 | name = "libloading" 293 | version = "0.5.2" 294 | source = "registry+https://github.com/rust-lang/crates.io-index" 295 | dependencies = [ 296 | "cc 1.0.59 (registry+https://github.com/rust-lang/crates.io-index)", 297 | "winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", 298 | ] 299 | 300 | [[package]] 301 | name = "maybe-uninit" 302 | version = "2.0.0" 303 | source = "registry+https://github.com/rust-lang/crates.io-index" 304 | 305 | [[package]] 306 | name = "memchr" 307 | version = "2.3.3" 308 | source = "registry+https://github.com/rust-lang/crates.io-index" 309 | 310 | [[package]] 311 | name = "memoffset" 312 | version = "0.5.5" 313 | source = "registry+https://github.com/rust-lang/crates.io-index" 314 | dependencies = [ 315 | "autocfg 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", 316 | ] 317 | 318 | [[package]] 319 | name = "nix" 320 | version = "0.9.0" 321 | source = "registry+https://github.com/rust-lang/crates.io-index" 322 | dependencies = [ 323 | "bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)", 324 | "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", 325 | "libc 0.2.74 (registry+https://github.com/rust-lang/crates.io-index)", 326 | "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", 327 | ] 328 | 329 | [[package]] 330 | name = "nom" 331 | version = "4.2.3" 332 | source = "registry+https://github.com/rust-lang/crates.io-index" 333 | dependencies = [ 334 | "memchr 2.3.3 (registry+https://github.com/rust-lang/crates.io-index)", 335 | "version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", 336 | ] 337 | 338 | [[package]] 339 | name = "num-integer" 340 | version = "0.1.43" 341 | source = "registry+https://github.com/rust-lang/crates.io-index" 342 | dependencies = [ 343 | "autocfg 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", 344 | "num-traits 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)", 345 | ] 346 | 347 | [[package]] 348 | name = "num-traits" 349 | version = "0.2.12" 350 | source = "registry+https://github.com/rust-lang/crates.io-index" 351 | dependencies = [ 352 | "autocfg 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", 353 | ] 354 | 355 | [[package]] 356 | name = "portus" 357 | version = "0.5.5" 358 | source = "registry+https://github.com/rust-lang/crates.io-index" 359 | dependencies = [ 360 | "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", 361 | "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", 362 | "colored 1.9.3 (registry+https://github.com/rust-lang/crates.io-index)", 363 | "crossbeam 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", 364 | "fnv 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)", 365 | "itertools 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", 366 | "libc 0.2.74 (registry+https://github.com/rust-lang/crates.io-index)", 367 | "libloading 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", 368 | "nix 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", 369 | "nom 4.2.3 (registry+https://github.com/rust-lang/crates.io-index)", 370 | "portus_export 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", 371 | "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", 372 | "quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", 373 | "regex 1.3.9 (registry+https://github.com/rust-lang/crates.io-index)", 374 | "slog 2.5.2 (registry+https://github.com/rust-lang/crates.io-index)", 375 | "slog-async 2.5.0 (registry+https://github.com/rust-lang/crates.io-index)", 376 | "slog-term 2.6.0 (registry+https://github.com/rust-lang/crates.io-index)", 377 | "structopt 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", 378 | "syn 0.15.44 (registry+https://github.com/rust-lang/crates.io-index)", 379 | "time 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)", 380 | "toml 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", 381 | "walkdir 2.3.1 (registry+https://github.com/rust-lang/crates.io-index)", 382 | ] 383 | 384 | [[package]] 385 | name = "portus_export" 386 | version = "0.1.0" 387 | source = "registry+https://github.com/rust-lang/crates.io-index" 388 | dependencies = [ 389 | "quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", 390 | "syn 0.15.44 (registry+https://github.com/rust-lang/crates.io-index)", 391 | ] 392 | 393 | [[package]] 394 | name = "proc-macro2" 395 | version = "0.4.30" 396 | source = "registry+https://github.com/rust-lang/crates.io-index" 397 | dependencies = [ 398 | "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", 399 | ] 400 | 401 | [[package]] 402 | name = "quote" 403 | version = "0.6.13" 404 | source = "registry+https://github.com/rust-lang/crates.io-index" 405 | dependencies = [ 406 | "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", 407 | ] 408 | 409 | [[package]] 410 | name = "redox_syscall" 411 | version = "0.1.57" 412 | source = "registry+https://github.com/rust-lang/crates.io-index" 413 | 414 | [[package]] 415 | name = "redox_users" 416 | version = "0.3.4" 417 | source = "registry+https://github.com/rust-lang/crates.io-index" 418 | dependencies = [ 419 | "getrandom 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)", 420 | "redox_syscall 0.1.57 (registry+https://github.com/rust-lang/crates.io-index)", 421 | "rust-argon2 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", 422 | ] 423 | 424 | [[package]] 425 | name = "regex" 426 | version = "1.3.9" 427 | source = "registry+https://github.com/rust-lang/crates.io-index" 428 | dependencies = [ 429 | "aho-corasick 0.7.13 (registry+https://github.com/rust-lang/crates.io-index)", 430 | "memchr 2.3.3 (registry+https://github.com/rust-lang/crates.io-index)", 431 | "regex-syntax 0.6.18 (registry+https://github.com/rust-lang/crates.io-index)", 432 | "thread_local 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", 433 | ] 434 | 435 | [[package]] 436 | name = "regex-syntax" 437 | version = "0.6.18" 438 | source = "registry+https://github.com/rust-lang/crates.io-index" 439 | 440 | [[package]] 441 | name = "rust-argon2" 442 | version = "0.7.0" 443 | source = "registry+https://github.com/rust-lang/crates.io-index" 444 | dependencies = [ 445 | "base64 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", 446 | "blake2b_simd 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)", 447 | "constant_time_eq 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", 448 | "crossbeam-utils 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", 449 | ] 450 | 451 | [[package]] 452 | name = "same-file" 453 | version = "1.0.6" 454 | source = "registry+https://github.com/rust-lang/crates.io-index" 455 | dependencies = [ 456 | "winapi-util 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", 457 | ] 458 | 459 | [[package]] 460 | name = "scopeguard" 461 | version = "1.1.0" 462 | source = "registry+https://github.com/rust-lang/crates.io-index" 463 | 464 | [[package]] 465 | name = "serde" 466 | version = "1.0.115" 467 | source = "registry+https://github.com/rust-lang/crates.io-index" 468 | 469 | [[package]] 470 | name = "slog" 471 | version = "2.5.2" 472 | source = "registry+https://github.com/rust-lang/crates.io-index" 473 | 474 | [[package]] 475 | name = "slog-async" 476 | version = "2.5.0" 477 | source = "registry+https://github.com/rust-lang/crates.io-index" 478 | dependencies = [ 479 | "crossbeam-channel 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", 480 | "slog 2.5.2 (registry+https://github.com/rust-lang/crates.io-index)", 481 | "take_mut 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", 482 | "thread_local 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", 483 | ] 484 | 485 | [[package]] 486 | name = "slog-term" 487 | version = "2.6.0" 488 | source = "registry+https://github.com/rust-lang/crates.io-index" 489 | dependencies = [ 490 | "atty 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)", 491 | "chrono 0.4.15 (registry+https://github.com/rust-lang/crates.io-index)", 492 | "slog 2.5.2 (registry+https://github.com/rust-lang/crates.io-index)", 493 | "term 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", 494 | "thread_local 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", 495 | ] 496 | 497 | [[package]] 498 | name = "strsim" 499 | version = "0.8.0" 500 | source = "registry+https://github.com/rust-lang/crates.io-index" 501 | 502 | [[package]] 503 | name = "structopt" 504 | version = "0.2.18" 505 | source = "registry+https://github.com/rust-lang/crates.io-index" 506 | dependencies = [ 507 | "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", 508 | "structopt-derive 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", 509 | ] 510 | 511 | [[package]] 512 | name = "structopt-derive" 513 | version = "0.2.18" 514 | source = "registry+https://github.com/rust-lang/crates.io-index" 515 | dependencies = [ 516 | "heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", 517 | "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", 518 | "quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", 519 | "syn 0.15.44 (registry+https://github.com/rust-lang/crates.io-index)", 520 | ] 521 | 522 | [[package]] 523 | name = "syn" 524 | version = "0.15.44" 525 | source = "registry+https://github.com/rust-lang/crates.io-index" 526 | dependencies = [ 527 | "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", 528 | "quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", 529 | "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", 530 | ] 531 | 532 | [[package]] 533 | name = "take_mut" 534 | version = "0.2.2" 535 | source = "registry+https://github.com/rust-lang/crates.io-index" 536 | 537 | [[package]] 538 | name = "term" 539 | version = "0.6.1" 540 | source = "registry+https://github.com/rust-lang/crates.io-index" 541 | dependencies = [ 542 | "dirs 2.0.2 (registry+https://github.com/rust-lang/crates.io-index)", 543 | "winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", 544 | ] 545 | 546 | [[package]] 547 | name = "textwrap" 548 | version = "0.11.0" 549 | source = "registry+https://github.com/rust-lang/crates.io-index" 550 | dependencies = [ 551 | "unicode-width 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", 552 | ] 553 | 554 | [[package]] 555 | name = "thread_local" 556 | version = "1.0.1" 557 | source = "registry+https://github.com/rust-lang/crates.io-index" 558 | dependencies = [ 559 | "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", 560 | ] 561 | 562 | [[package]] 563 | name = "time" 564 | version = "0.1.43" 565 | source = "registry+https://github.com/rust-lang/crates.io-index" 566 | dependencies = [ 567 | "libc 0.2.74 (registry+https://github.com/rust-lang/crates.io-index)", 568 | "winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", 569 | ] 570 | 571 | [[package]] 572 | name = "toml" 573 | version = "0.4.10" 574 | source = "registry+https://github.com/rust-lang/crates.io-index" 575 | dependencies = [ 576 | "serde 1.0.115 (registry+https://github.com/rust-lang/crates.io-index)", 577 | ] 578 | 579 | [[package]] 580 | name = "unicode-segmentation" 581 | version = "1.6.0" 582 | source = "registry+https://github.com/rust-lang/crates.io-index" 583 | 584 | [[package]] 585 | name = "unicode-width" 586 | version = "0.1.8" 587 | source = "registry+https://github.com/rust-lang/crates.io-index" 588 | 589 | [[package]] 590 | name = "unicode-xid" 591 | version = "0.1.0" 592 | source = "registry+https://github.com/rust-lang/crates.io-index" 593 | 594 | [[package]] 595 | name = "vec_map" 596 | version = "0.8.2" 597 | source = "registry+https://github.com/rust-lang/crates.io-index" 598 | 599 | [[package]] 600 | name = "version_check" 601 | version = "0.1.5" 602 | source = "registry+https://github.com/rust-lang/crates.io-index" 603 | 604 | [[package]] 605 | name = "void" 606 | version = "1.0.2" 607 | source = "registry+https://github.com/rust-lang/crates.io-index" 608 | 609 | [[package]] 610 | name = "walkdir" 611 | version = "2.3.1" 612 | source = "registry+https://github.com/rust-lang/crates.io-index" 613 | dependencies = [ 614 | "same-file 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", 615 | "winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", 616 | "winapi-util 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", 617 | ] 618 | 619 | [[package]] 620 | name = "wasi" 621 | version = "0.9.0+wasi-snapshot-preview1" 622 | source = "registry+https://github.com/rust-lang/crates.io-index" 623 | 624 | [[package]] 625 | name = "winapi" 626 | version = "0.3.9" 627 | source = "registry+https://github.com/rust-lang/crates.io-index" 628 | dependencies = [ 629 | "winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", 630 | "winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", 631 | ] 632 | 633 | [[package]] 634 | name = "winapi-i686-pc-windows-gnu" 635 | version = "0.4.0" 636 | source = "registry+https://github.com/rust-lang/crates.io-index" 637 | 638 | [[package]] 639 | name = "winapi-util" 640 | version = "0.1.5" 641 | source = "registry+https://github.com/rust-lang/crates.io-index" 642 | dependencies = [ 643 | "winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", 644 | ] 645 | 646 | [[package]] 647 | name = "winapi-x86_64-pc-windows-gnu" 648 | version = "0.4.0" 649 | source = "registry+https://github.com/rust-lang/crates.io-index" 650 | 651 | [metadata] 652 | "checksum aho-corasick 0.7.13 (registry+https://github.com/rust-lang/crates.io-index)" = "043164d8ba5c4c3035fec9bbee8647c0261d788f3474306f93bb65901cae0e86" 653 | "checksum ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b" 654 | "checksum arrayref 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "a4c527152e37cf757a3f78aae5a06fbeefdb07ccc535c980a3208ee3060dd544" 655 | "checksum arrayvec 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cff77d8686867eceff3105329d4698d96c2391c176d5d03adc90c7389162b5b8" 656 | "checksum atty 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)" = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" 657 | "checksum autocfg 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f8aac770f1885fd7e387acedd76065302551364496e46b3dd00860b2f8359b9d" 658 | "checksum base64 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b41b7ea54a0c9d92199de89e20e58d49f02f8e699814ef3fdf266f6f748d15c7" 659 | "checksum bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4efd02e230a02e18f92fc2735f44597385ed02ad8f831e7c1c1156ee5e1ab3a5" 660 | "checksum bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" 661 | "checksum blake2b_simd 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)" = "d8fb2d74254a3a0b5cac33ac9f8ed0e44aa50378d9dbb2e5d83bd21ed1dc2c8a" 662 | "checksum byteorder 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "08c48aae112d48ed9f069b33538ea9e3e90aa263cfa3d1c24309612b1f7472de" 663 | "checksum bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)" = "206fdffcfa2df7cbe15601ef46c813fce0965eb3286db6b56c583b814b51c81c" 664 | "checksum cc 1.0.59 (registry+https://github.com/rust-lang/crates.io-index)" = "66120af515773fb005778dc07c261bd201ec8ce50bd6e7144c927753fe013381" 665 | "checksum cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" 666 | "checksum chrono 0.4.15 (registry+https://github.com/rust-lang/crates.io-index)" = "942f72db697d8767c22d46a598e01f2d3b475501ea43d0db4f16d90259182d0b" 667 | "checksum clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)" = "37e58ac78573c40708d45522f0d80fa2f01cc4f9b4e2bf749807255454312002" 668 | "checksum colored 1.9.3 (registry+https://github.com/rust-lang/crates.io-index)" = "f4ffc801dacf156c5854b9df4f425a626539c3a6ef7893cc0c5084a23f0b6c59" 669 | "checksum constant_time_eq 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc" 670 | "checksum crossbeam 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)" = "69323bff1fb41c635347b8ead484a5ca6c3f11914d784170b158d8449ab07f8e" 671 | "checksum crossbeam-channel 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "09ee0cc8804d5393478d743b035099520087a5186f3b93fa58cec08fa62407b6" 672 | "checksum crossbeam-deque 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)" = "9f02af974daeee82218205558e51ec8768b48cf524bd01d550abe5573a608285" 673 | "checksum crossbeam-epoch 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "058ed274caafc1f60c4997b5fc07bf7dc7cca454af7c6e81edffe5f33f70dace" 674 | "checksum crossbeam-queue 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "774ba60a54c213d409d5353bda12d49cd68d14e45036a285234c8d6f91f92570" 675 | "checksum crossbeam-utils 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c3c7c73a2d1e9fc0886a08b93e98eb643461230d5f1925e4036204d5f2e261a8" 676 | "checksum dirs 2.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "13aea89a5c93364a98e9b37b2fa237effbb694d5cfe01c5b70941f7eb087d5e3" 677 | "checksum dirs-sys 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "8e93d7f5705de3e49895a2b5e0b8855a1c27f080192ae9c32a6432d50741a57a" 678 | "checksum either 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "cd56b59865bce947ac5958779cfa508f6c3b9497cc762b7e24a12d11ccde2c4f" 679 | "checksum fnv 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)" = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" 680 | "checksum getrandom 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)" = "7abc8dd8451921606d809ba32e95b6111925cd2906060d2dcc29c070220503eb" 681 | "checksum heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "20564e78d53d2bb135c343b3f47714a56af2061f1c928fdb541dc7b9fdd94205" 682 | "checksum hermit-abi 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)" = "3deed196b6e7f9e44a2ae8d94225d80302d81208b1bb673fd21fe634645c85a9" 683 | "checksum iovec 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "b2b3ea6ff95e175473f8ffe6a7eb7c00d054240321b84c57051175fe3c1e075e" 684 | "checksum itertools 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f56a2d0bc861f9165be4eb3442afd3c236d8a98afd426f65d92324ae1091a484" 685 | "checksum lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" 686 | "checksum libc 0.2.74 (registry+https://github.com/rust-lang/crates.io-index)" = "a2f02823cf78b754822df5f7f268fb59822e7296276d3e069d8e8cb26a14bd10" 687 | "checksum libloading 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f2b111a074963af1d37a139918ac6d49ad1d0d5e47f72fd55388619691a7d753" 688 | "checksum maybe-uninit 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "60302e4db3a61da70c0cb7991976248362f30319e88850c487b9b95bbf059e00" 689 | "checksum memchr 2.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3728d817d99e5ac407411fa471ff9800a778d88a24685968b36824eaf4bee400" 690 | "checksum memoffset 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)" = "c198b026e1bbf08a937e94c6c60f9ec4a2267f5b0d2eec9c1b21b061ce2be55f" 691 | "checksum nix 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a2c5afeb0198ec7be8569d666644b574345aad2e95a53baf3a532da3e0f3fb32" 692 | "checksum nom 4.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2ad2a91a8e869eeb30b9cb3119ae87773a8f4ae617f41b1eb9c154b2905f7bd6" 693 | "checksum num-integer 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)" = "8d59457e662d541ba17869cf51cf177c0b5f0cbf476c66bdc90bf1edac4f875b" 694 | "checksum num-traits 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)" = "ac267bcc07f48ee5f8935ab0d24f316fb722d7a1292e2913f0cc196b29ffd611" 695 | "checksum portus 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)" = "3fe718cbf82f03a49acd63b28a9c4605efff179e3e8ef046301e19781c39c814" 696 | "checksum portus_export 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d976af813bd952cfdbe88be1daa2ef99ee8311587f4fd49dde8a0f382010ddc" 697 | "checksum proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)" = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759" 698 | "checksum quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)" = "6ce23b6b870e8f94f81fb0a363d65d86675884b34a09043c81e5562f11c1f8e1" 699 | "checksum redox_syscall 0.1.57 (registry+https://github.com/rust-lang/crates.io-index)" = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce" 700 | "checksum redox_users 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "09b23093265f8d200fa7b4c2c76297f47e681c655f6f1285a8780d6a022f7431" 701 | "checksum regex 1.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "9c3780fcf44b193bc4d09f36d2a3c87b251da4a046c87795a0d35f4f927ad8e6" 702 | "checksum regex-syntax 0.6.18 (registry+https://github.com/rust-lang/crates.io-index)" = "26412eb97c6b088a6997e05f69403a802a92d520de2f8e63c2b65f9e0f47c4e8" 703 | "checksum rust-argon2 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2bc8af4bda8e1ff4932523b94d3dd20ee30a87232323eda55903ffd71d2fb017" 704 | "checksum same-file 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" 705 | "checksum scopeguard 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" 706 | "checksum serde 1.0.115 (registry+https://github.com/rust-lang/crates.io-index)" = "e54c9a88f2da7238af84b5101443f0c0d0a3bbdc455e34a5c9497b1903ed55d5" 707 | "checksum slog 2.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1cc9c640a4adbfbcc11ffb95efe5aa7af7309e002adab54b185507dbf2377b99" 708 | "checksum slog-async 2.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "51b3336ce47ce2f96673499fc07eb85e3472727b9a7a2959964b002c2ce8fbbb" 709 | "checksum slog-term 2.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bab1d807cf71129b05ce36914e1dbb6fbfbdecaf686301cb457f4fa967f9f5b6" 710 | "checksum strsim 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" 711 | "checksum structopt 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)" = "16c2cdbf9cc375f15d1b4141bc48aeef444806655cd0e904207edc8d68d86ed7" 712 | "checksum structopt-derive 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)" = "53010261a84b37689f9ed7d395165029f9cc7abb9f56bbfe86bee2597ed25107" 713 | "checksum syn 0.15.44 (registry+https://github.com/rust-lang/crates.io-index)" = "9ca4b3b69a77cbe1ffc9e198781b7acb0c7365a883670e8f1c1bc66fba79a5c5" 714 | "checksum take_mut 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f764005d11ee5f36500a149ace24e00e3da98b0158b3e2d53a7495660d3f4d60" 715 | "checksum term 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c0863a3345e70f61d613eab32ee046ccd1bcc5f9105fe402c61fcd0c13eeb8b5" 716 | "checksum textwrap 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" 717 | "checksum thread_local 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d40c6d1b69745a6ec6fb1ca717914848da4b44ae29d9b3080cbee91d72a69b14" 718 | "checksum time 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)" = "ca8a50ef2360fbd1eeb0ecd46795a87a19024eb4b53c5dc916ca1fd95fe62438" 719 | "checksum toml 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)" = "758664fc71a3a69038656bee8b6be6477d2a6c315a6b81f7081f591bffa4111f" 720 | "checksum unicode-segmentation 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e83e153d1053cbb5a118eeff7fd5be06ed99153f00dbcd8ae310c5fb2b22edc0" 721 | "checksum unicode-width 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "9337591893a19b88d8d87f2cec1e73fad5cdfd10e5a6f349f498ad6ea2ffb1e3" 722 | "checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc" 723 | "checksum vec_map 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" 724 | "checksum version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "914b1a6776c4c929a602fafd8bc742e06365d4bcbe48c30f9cca5824f70dc9dd" 725 | "checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" 726 | "checksum walkdir 2.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "777182bc735b6424e1a57516d35ed72cb8019d85c8c9bf536dccb3445c1a2f7d" 727 | "checksum wasi 0.9.0+wasi-snapshot-preview1 (registry+https://github.com/rust-lang/crates.io-index)" = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" 728 | "checksum winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" 729 | "checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" 730 | "checksum winapi-util 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" 731 | "checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" 732 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "ccp_copa" 3 | version = "0.1.1" 4 | authors = ["Venkat Arun "] 5 | 6 | [dependencies] 7 | clap = "2.29" 8 | portus = "^0.5" 9 | slog = "2" 10 | slog-async = "2" 11 | slog-term = "2" 12 | time = "0.1" 13 | -------------------------------------------------------------------------------- /src/agg_measurement.rs: -------------------------------------------------------------------------------- 1 | use std; 2 | 3 | use portus::Report; 4 | use portus::lang::Scope; 5 | 6 | #[derive(Clone, PartialEq, Eq)] 7 | pub enum ReportStatus {Report, NoReport, UrgentReport} 8 | 9 | // CCP may return before the specified time. This struct will aggregate relevant 10 | // values till the time is right 11 | pub struct AggMeasurement { 12 | // In fraction of a (smoothed) RTT 13 | reporting_interval: f32, 14 | // For determining when to report 15 | srtt: f32, 16 | // EWMA variable 17 | srtt_alpha: f32, 18 | // Last time we reported 19 | last_report_time: u64, 20 | // Aggregate variables that are reset every measurement interval 21 | acked: u32, 22 | sacked: u32, 23 | rtt: u32, 24 | min_rtt: u32, 25 | } 26 | 27 | impl AggMeasurement { 28 | pub fn new(reporting_interval: f32) -> Self { 29 | Self { 30 | reporting_interval: reporting_interval, 31 | srtt: 0., 32 | srtt_alpha: 1. / 16., 33 | last_report_time: 0, 34 | acked: 0, 35 | sacked: 0, 36 | rtt: 0, 37 | min_rtt: std::u32::MAX, 38 | } 39 | } 40 | 41 | pub fn report(&mut self, m: Report, sc: &Scope) -> (ReportStatus, bool, u32, u32, u32, u32, u32, u32, u64) { 42 | let acked = m.get_field("Report.acked", sc).expect( 43 | "expected acked field in returned measurement", 44 | ) as u32; 45 | 46 | let sacked = m.get_field("Report.sacked", sc).expect( 47 | "expected sacked field in returned measurement", 48 | ) as u32; 49 | 50 | let was_timeout = m.get_field("Report.timeout", sc).expect( 51 | "expected timeout field in returned measurement", 52 | ) as u32; 53 | 54 | let inflight = m.get_field("Report.inflight", sc).expect( 55 | "expected inflight field in returned measurement", 56 | ) as u32; 57 | 58 | let loss = m.get_field("Report.loss", sc).expect( 59 | "expected loss field in returned measurement", 60 | ) as u32; 61 | 62 | let rtt = m.get_field("Report.rtt", sc).expect( 63 | "expected rtt field in returned measurement", 64 | ) as u32; 65 | 66 | let now = m.get_field("Report.now", sc).expect( 67 | "expected now field in returned measurement", 68 | ) as u64; 69 | 70 | let min_rtt = m.get_field("Report.minrtt", sc).expect( 71 | "expected minrtt field in returned measurement", 72 | ) as u32; 73 | 74 | self.acked += acked; 75 | self.sacked = sacked; 76 | self.min_rtt = std::cmp::min(self.min_rtt, min_rtt); 77 | 78 | if was_timeout == 1 || loss > 0 { 79 | return (ReportStatus::UrgentReport, (was_timeout == 1), 0, 0, loss, 80 | 0, 0, 0, now); 81 | } 82 | 83 | if rtt != 0 { 84 | self.rtt = rtt; 85 | self.srtt = self.srtt_alpha * rtt as f32+ 86 | (1. - self.srtt_alpha) * self.srtt; 87 | } 88 | 89 | if now > 0 && self.last_report_time < 90 | now - (self.srtt * self.reporting_interval) as u64 { 91 | let res = (ReportStatus::Report, false, self.acked, self.sacked, 92 | loss, inflight, self.rtt, self.min_rtt, now); 93 | self.last_report_time = now; 94 | self.acked = 0; 95 | self.sacked = 0; 96 | self.rtt = 0; 97 | self.min_rtt = std::u32::MAX; 98 | return res; 99 | } 100 | else { 101 | return (ReportStatus::NoReport, false, 0, 0, 0, 0, 0, 0, now); 102 | } 103 | } 104 | } 105 | -------------------------------------------------------------------------------- /src/bin/copa.rs: -------------------------------------------------------------------------------- 1 | extern crate clap; 2 | use clap::Arg; 3 | 4 | #[macro_use] 5 | extern crate slog; 6 | extern crate slog_async; 7 | extern crate slog_term; 8 | use slog::Drain; 9 | 10 | extern crate ccp_copa; 11 | use ccp_copa::CopaConfig; 12 | 13 | extern crate portus; 14 | 15 | fn make_logger() -> slog::Logger { 16 | let decorator = slog_term::TermDecorator::new().build(); 17 | let drain = slog_term::FullFormat::new(decorator).build().fuse(); 18 | let drain = slog_async::Async::new(drain).build().fuse(); 19 | slog::Logger::root(drain, o!()) 20 | } 21 | 22 | fn make_args(log: slog::Logger) -> Result<(CopaConfig, String), std::num::ParseIntError> { 23 | let matches = clap::App::new("CCP Copa") 24 | .version("0.1.0") 25 | .author("Venkat Arun ") 26 | .about("Implementation of Copa Congestion Control") 27 | .arg(Arg::with_name("ipc") 28 | .long("ipc") 29 | .help("Sets the type of ipc to use: (netlink|unix)") 30 | .default_value("unix") 31 | .validator(portus::algs::ipc_valid)) 32 | .arg(Arg::with_name("init_cwnd") 33 | .long("init_cwnd") 34 | .help("Sets the initial congestion window, in bytes. Setting 0 will use datapath default.") 35 | .default_value("0")) 36 | .arg(Arg::with_name("default_delta") 37 | .long("default_delta") 38 | .help("Delta to use when in default mode.") 39 | .default_value("0.5")) 40 | .get_matches(); 41 | 42 | Ok(( 43 | ccp_copa::CopaConfig { 44 | logger: Some(log), 45 | init_cwnd: u32::from_str_radix(matches.value_of("init_cwnd").unwrap(), 10)?, 46 | default_delta: (matches.value_of("default_delta").unwrap()) 47 | .parse() 48 | .unwrap(), 49 | delta_mode: ccp_copa::DeltaModeConf::Auto, 50 | }, 51 | String::from(matches.value_of("ipc").unwrap()), 52 | )) 53 | } 54 | 55 | fn main() { 56 | let log = make_logger(); 57 | let (cfg, ipc) = make_args(log.clone()) 58 | .map_err(|e| warn!(log, "bad argument"; "err" => ?e)) 59 | .unwrap(); 60 | 61 | info!(log, "configured Copa"; 62 | "ipc" => ipc.clone(), 63 | "init_cwnd" => cfg.init_cwnd, 64 | "default_delta" => cfg.default_delta, 65 | "delta_mode" => ?cfg.delta_mode, 66 | ); 67 | 68 | portus::start!(ipc.as_str(), Some(log), cfg).unwrap() 69 | } 70 | -------------------------------------------------------------------------------- /src/delta_manager.rs: -------------------------------------------------------------------------------- 1 | use rtt_window::RTTWindow; 2 | 3 | #[derive(Clone, Debug, Eq, PartialEq)] 4 | pub enum DeltaModeConf { 5 | NoTCP, 6 | Auto, 7 | } 8 | 9 | #[derive(Clone, Debug, Eq, PartialEq)] 10 | pub enum DeltaMode { 11 | Default, 12 | TCPCoop, 13 | Loss, 14 | } 15 | 16 | pub struct DeltaManager { 17 | // Configuration on how to choose delta 18 | switch_mode: DeltaModeConf, 19 | default_delta: f32, 20 | // End of the last window of tracking losses 21 | prev_loss_cycle: u64, 22 | // Loss rate in the previous cycle 23 | prev_loss_rate: f32, 24 | // Number of acks and losses in current cycle 25 | cur_num_acked: u32, 26 | cur_num_losses: u32, 27 | // Last time we reduced 1/delta due to loss, so we don't decrease twice 28 | // within the same RTT 29 | prev_loss_red_time: u64, 30 | // Current state of delta 31 | cur_mode: DeltaMode, 32 | delta: f32, 33 | } 34 | 35 | impl DeltaManager { 36 | pub fn new(default_delta: f32, mode: DeltaModeConf) -> Self { 37 | let cur_mode = match mode { 38 | DeltaModeConf::NoTCP => DeltaMode::Default, 39 | DeltaModeConf::Auto => DeltaMode::TCPCoop, 40 | }; 41 | if default_delta > 1.0 { 42 | panic!("Default delta should be less than or equal to 1."); 43 | } 44 | Self { 45 | switch_mode: mode, 46 | default_delta: default_delta, 47 | prev_loss_cycle: 0, 48 | prev_loss_rate: 0., 49 | cur_num_acked: 0, 50 | cur_num_losses: 0, 51 | prev_loss_red_time: 0, 52 | cur_mode: cur_mode, 53 | delta: 0.5, 54 | } 55 | } 56 | 57 | pub fn report_measurement(&mut self, rtt_win: &mut RTTWindow, acked: u32, lost: u32, now: u64) { 58 | // Update loss rate estimate 59 | self.cur_num_acked += acked; 60 | self.cur_num_losses += lost; 61 | if now > self.prev_loss_cycle + 2 * rtt_win.get_base_rtt() as u64 { 62 | self.prev_loss_cycle = now; 63 | if self.cur_num_losses + self.cur_num_acked > 0 { 64 | self.prev_loss_rate = 65 | self.cur_num_losses as f32 / (self.cur_num_losses + self.cur_num_acked) as f32; 66 | } 67 | self.cur_num_acked = 0; 68 | self.cur_num_losses = 0; 69 | } 70 | 71 | // Set delta mode 72 | // If we are losing more than 10% of packets, move to loss mode. Period. 73 | if self.prev_loss_rate >= 0.1 { 74 | self.cur_mode = DeltaMode::Loss; 75 | } else { 76 | // See if we need to be in TCP mode 77 | if self.switch_mode == DeltaModeConf::Auto 78 | && (rtt_win.num_tcp_detect_samples() < 10 || rtt_win.tcp_detected()) 79 | { 80 | self.cur_mode = DeltaMode::TCPCoop; 81 | } else { 82 | self.cur_mode = DeltaMode::Default; 83 | self.delta = self.default_delta; 84 | } 85 | } 86 | 87 | // Set delta 88 | match self.cur_mode { 89 | DeltaMode::Default => { 90 | // Coming from TCPCoop mode 91 | self.delta = self.default_delta; 92 | } 93 | DeltaMode::TCPCoop => { 94 | if lost > 0 { 95 | if now - rtt_win.get_base_rtt() as u64 > self.prev_loss_red_time { 96 | self.delta *= 2.; 97 | self.prev_loss_red_time = now; 98 | } 99 | } else { 100 | self.delta = 1. / (1. + 1. / self.delta); 101 | } 102 | if self.delta > self.default_delta { 103 | self.delta = self.default_delta; 104 | } 105 | } 106 | DeltaMode::Loss => { 107 | if lost > 0 { 108 | self.delta *= 2.; 109 | } 110 | if self.delta >= self.default_delta { 111 | self.delta = self.default_delta; 112 | } 113 | } 114 | }; 115 | } 116 | 117 | pub fn get_delta(&self) -> f32 { 118 | self.delta 119 | } 120 | 121 | pub fn get_mode(&self) -> DeltaMode { 122 | self.cur_mode.clone() 123 | } 124 | } 125 | -------------------------------------------------------------------------------- /src/lib.rs: -------------------------------------------------------------------------------- 1 | extern crate clap; 2 | use std::collections::HashMap; 3 | 4 | #[macro_use] 5 | extern crate slog; 6 | extern crate portus; 7 | 8 | use portus::ipc::Ipc; 9 | use portus::lang::Scope; 10 | use portus::{CongAlg, Datapath, DatapathInfo, DatapathTrait, Report}; 11 | 12 | mod delta_manager; 13 | mod rtt_window; 14 | pub use delta_manager::DeltaModeConf; 15 | use delta_manager::{DeltaManager, DeltaMode}; 16 | use rtt_window::RTTWindow; 17 | mod agg_measurement; 18 | use agg_measurement::{AggMeasurement, ReportStatus}; 19 | 20 | pub struct Copa { 21 | control_channel: Datapath, 22 | logger: Option, 23 | sc: Scope, 24 | delta_manager: DeltaManager, 25 | prev_report_time: u64, 26 | cwnd: u32, 27 | init_cwnd: u32, 28 | slow_start: bool, 29 | rtt_win: RTTWindow, 30 | velocity: u32, 31 | cur_direction: i64, 32 | prev_direction: i64, 33 | time_since_direction: u64, 34 | prev_update_rtt: u64, 35 | agg_measurement: AggMeasurement, 36 | } 37 | 38 | #[derive(Clone)] 39 | pub struct CopaConfig { 40 | pub logger: Option, 41 | pub init_cwnd: u32, 42 | pub default_delta: f32, 43 | pub delta_mode: DeltaModeConf, 44 | } 45 | 46 | impl Copa { 47 | fn compute_rate(&self) -> u32 { 48 | (2 * self.cwnd as u64 * 1_000_000 / self.rtt_win.get_base_rtt() as u64) as u32 49 | } 50 | 51 | fn update(&self) { 52 | let rate = std::cmp::max(self.compute_rate(), 2_000); 53 | self.logger.as_ref().map(|log| { 54 | debug!(log, "update"; 55 | "curr_cwnd (pkts)" => self.cwnd / 1460, 56 | "rate" => rate, 57 | ); 58 | }); 59 | 60 | self.control_channel 61 | .update_field(&self.sc, &[("Cwnd", self.cwnd), ("Rate", rate)]) 62 | .unwrap() 63 | } 64 | 65 | fn delay_control(&mut self, rtt: u32, actual_acked: u32, now: u64) { 66 | let increase = rtt as u64 * 1460u64 67 | > (((rtt - self.rtt_win.get_base_rtt()) as f64) 68 | * self.delta_manager.get_delta() as f64 69 | * self.cwnd as f64) as u64; 70 | 71 | let mut acked = actual_acked; 72 | // Just in case. Sometimes CCP returns after significantly longer than 73 | // what was asked for. In that case, actual_acked can be huge 74 | if actual_acked > self.cwnd { 75 | acked = self.cwnd; 76 | } 77 | // Update velocity 78 | if increase { 79 | self.cur_direction += 1; 80 | } else { 81 | self.cur_direction -= 1; 82 | } 83 | 84 | if self.velocity > 1 85 | && ((increase && self.prev_direction < 0) || (!increase && self.prev_direction > 0)) 86 | { 87 | self.velocity = 1; 88 | self.time_since_direction = now; 89 | } 90 | 91 | if now - self.prev_update_rtt >= 2 * rtt as u64 && !self.slow_start { 92 | // TODO(venkatar): Time (now) may be a u32 internally, which means it 93 | // will wrap around. Handle this. 94 | if (self.prev_direction > 0 && self.cur_direction > 0) 95 | || (self.prev_direction < 0 && self.cur_direction < 0) 96 | { 97 | if (now - self.time_since_direction) as u32 > 3 * rtt { 98 | self.velocity *= 2; 99 | } else { 100 | assert!(self.velocity == 1); 101 | } 102 | } else { 103 | self.velocity = 1; 104 | self.time_since_direction = now; 105 | } 106 | if self.velocity > 0xffff { 107 | self.velocity = 0xffff; 108 | } 109 | self.prev_direction = self.cur_direction; 110 | self.cur_direction = 0; 111 | self.prev_update_rtt = now; 112 | } 113 | 114 | // Change window 115 | if self.slow_start { 116 | if increase { 117 | self.cwnd += acked; 118 | } else { 119 | self.slow_start = false; 120 | } 121 | } else { 122 | let mut velocity = 1u64; 123 | if (increase && self.prev_direction > 0) || (!increase && self.prev_direction < 0) { 124 | velocity = self.velocity as u64; 125 | } 126 | 127 | // If we are in TCP mode, delta changes with time. Account for that. 128 | let delta = match !increase && self.delta_manager.get_mode() == DeltaMode::TCPCoop { 129 | false => self.delta_manager.get_delta(), 130 | true => 1. / (1. + 1. / self.delta_manager.get_delta()), 131 | }; 132 | 133 | // Do computations in u64 to avoid overflow. Multiply first so 134 | // integer division doesn't cause as many problems 135 | let change = 136 | (velocity * 1448 * (acked as u64) / (self.cwnd as f32 * delta) as u64) as u32; 137 | 138 | if increase { 139 | self.cwnd += change; 140 | } else { 141 | if change + self.init_cwnd > self.cwnd { 142 | self.cwnd = self.init_cwnd; 143 | self.velocity = 1; 144 | self.time_since_direction = now; 145 | } else { 146 | self.cwnd -= change; 147 | } 148 | } 149 | } 150 | assert!(self.cwnd >= self.init_cwnd); 151 | } 152 | 153 | fn handle_timeout(&mut self) { 154 | self.cwnd = self.init_cwnd; 155 | self.slow_start = true; 156 | 157 | self.logger.as_ref().map(|log| { 158 | warn!(log, "timeout"; 159 | "curr_cwnd (pkts)" => self.cwnd / 1448, 160 | ); 161 | }); 162 | } 163 | } 164 | 165 | impl CongAlg for CopaConfig { 166 | type Flow = Copa; 167 | 168 | fn name() -> &'static str { 169 | "copa" 170 | } 171 | 172 | fn datapath_programs(&self) -> HashMap<&'static str, String> { 173 | vec![( 174 | "copa", 175 | "(def 176 | (Report 177 | (volatile acked 0) 178 | (volatile sacked 0) 179 | (volatile loss 0) 180 | (volatile inflight 0) 181 | (volatile timeout 0) 182 | (volatile rtt 0) 183 | (volatile now 0) 184 | (volatile minrtt +infinity) 185 | ) 186 | (basertt +infinity) 187 | ) 188 | (when true 189 | (:= Report.acked (+ Report.acked Ack.bytes_acked)) 190 | (:= Report.inflight Flow.packets_in_flight) 191 | (:= Report.rtt Flow.rtt_sample_us) 192 | (:= Report.minrtt (min Report.minrtt Flow.rtt_sample_us)) 193 | (:= basertt (min basertt Flow.rtt_sample_us)) 194 | (:= Report.sacked (+ Report.sacked Ack.packets_misordered)) 195 | (:= Report.loss Ack.lost_pkts_sample) 196 | (:= Report.timeout Flow.was_timeout) 197 | (:= Report.now Ack.now) 198 | (fallthrough) 199 | ) 200 | (when (|| Flow.was_timeout (> Report.loss 0)) 201 | (:= Micros 0) 202 | (report) 203 | ) 204 | (when (> Micros (/ basertt 2)) 205 | (:= Micros 0) 206 | (report) 207 | )" 208 | .to_string(), 209 | )] 210 | .into_iter() 211 | .collect() 212 | } 213 | 214 | fn new_flow(&self, control: Datapath, info: DatapathInfo) -> Self::Flow { 215 | let mut s = Copa { 216 | control_channel: control, 217 | logger: self.logger.clone(), 218 | cwnd: info.init_cwnd, 219 | init_cwnd: info.init_cwnd, 220 | sc: Default::default(), 221 | delta_manager: DeltaManager::new(self.default_delta, self.delta_mode.clone()), 222 | slow_start: true, 223 | rtt_win: RTTWindow::new(), 224 | velocity: 1, 225 | cur_direction: 0, 226 | prev_direction: 0, 227 | time_since_direction: 0, 228 | prev_update_rtt: 0, 229 | agg_measurement: AggMeasurement::new(0.5), 230 | prev_report_time: 0, 231 | }; 232 | 233 | if self.init_cwnd != 0 { 234 | s.cwnd = self.init_cwnd; 235 | s.init_cwnd = self.init_cwnd; 236 | } 237 | 238 | self.logger.as_ref().map(|log| { 239 | info!(log, "starting copa flow"; "sock_id" => info.sock_id); 240 | }); 241 | 242 | s.sc = s.control_channel.set_program("copa", None).unwrap(); 243 | s.update(); 244 | s 245 | } 246 | } 247 | 248 | impl portus::Flow for Copa { 249 | fn on_report(&mut self, _sock_id: u32, m: Report) { 250 | let (report_status, was_timeout, acked, sacked, loss, _inflight, _rtt, min_rtt, now) = 251 | self.agg_measurement.report(m, &self.sc); 252 | if report_status == ReportStatus::UrgentReport { 253 | if was_timeout { 254 | self.handle_timeout(); 255 | } 256 | 257 | self.delta_manager 258 | .report_measurement(&mut self.rtt_win, 0, loss, now); 259 | } else if report_status == ReportStatus::NoReport || acked + loss + sacked == 0 { 260 | // Do nothing 261 | } else { 262 | // Record RTT 263 | self.rtt_win.new_rtt_sample(min_rtt, now); 264 | if self.rtt_win.did_base_rtt_change() { 265 | self.control_channel 266 | .update_field(&self.sc, &[("base_rtt", self.rtt_win.get_base_rtt())]) 267 | .unwrap(); 268 | } 269 | // Update delta mode and delta 270 | self.delta_manager 271 | .report_measurement(&mut self.rtt_win, acked, loss, now); 272 | 273 | // Increase/decrease the cwnd corresponding to new measurements 274 | self.delay_control(min_rtt, acked, now); 275 | } 276 | 277 | // Send decisions to CCP 278 | self.update(); 279 | 280 | self.logger.as_ref().map(|log| { 281 | info!(log, "got ack"; 282 | "acked(pkts)" => acked / 1448u32, 283 | "curr_cwnd (pkts)" => self.cwnd / 1460, 284 | "loss" => loss, 285 | "sacked" => sacked, 286 | "delta" => self.delta_manager.get_delta(), 287 | "min_rtt" => min_rtt, 288 | "base_rtt" => self.rtt_win.get_base_rtt(), 289 | "velocity" => self.velocity, 290 | "mode" => match self.delta_manager.get_mode() { 291 | DeltaMode::Default => "const", 292 | DeltaMode::TCPCoop => "tcp", 293 | DeltaMode::Loss => "loss", 294 | }, 295 | "report_interval" => now - self.prev_report_time, 296 | ); 297 | }); 298 | self.prev_report_time = now; 299 | } 300 | } 301 | -------------------------------------------------------------------------------- /src/rtt_window.rs: -------------------------------------------------------------------------------- 1 | use std; 2 | use std::collections::{VecDeque}; 3 | 4 | pub struct RTTWindow { 5 | // Maximum time till which to maintain history. It is minimum of 10s and 20 6 | // RTTs. 7 | max_time: u64, 8 | // Base RTT 9 | base_rtt: u32, 10 | // Did the base RTT change since the last rtt sample that was reported? 11 | base_rtt_changed: bool, 12 | srtt: u32, 13 | 14 | // RTT measurements 15 | rtts: VecDeque, 16 | // Times at which the measurements were reported 17 | times: VecDeque, 18 | 19 | // Whether or not RTT has increased in the last 2 X min. RTT period along 20 | // with the ending time of that period 21 | increase: VecDeque<(u64, bool)>, 22 | // Minimum RTT between now and now-2*min_rtt 23 | cur_min_rtt: u32, 24 | // Minimum RTT between now-2*min_rtt and now-4*min_rtt 25 | prev_min_rtt: u32, 26 | // Number of increases and decreases in the current `increase` window 27 | num_increase: u32, 28 | num_decrease: u32, 29 | } 30 | 31 | impl RTTWindow { 32 | pub fn new() -> Self { 33 | Self { 34 | max_time: 10_000_000, 35 | base_rtt: std::u32::MAX, 36 | base_rtt_changed: false, 37 | srtt: 0, 38 | 39 | rtts: VecDeque::new(), 40 | times: VecDeque::new(), 41 | 42 | increase: VecDeque::new(), 43 | cur_min_rtt: std::u32::MAX, 44 | prev_min_rtt: 0, // We want to bias toward TCP mode 45 | num_increase: 0, 46 | num_decrease: 0, 47 | } 48 | } 49 | 50 | fn clear_old_hist(&mut self, now: u64) { 51 | assert!(self.rtts.len() == self.times.len()); 52 | // Whether or not min. RTT needs to be recomputed 53 | let mut recompute_base_rtt = false; 54 | 55 | // Delete all samples older than max_time. However, if there is only one 56 | // sample left, don't delete it 57 | while self.times.len() > 1 && 58 | self.times.front().unwrap() < &(now - self.max_time) { 59 | if self.rtts.front().unwrap() <= &self.base_rtt { 60 | recompute_base_rtt = true; 61 | } 62 | self.times.pop_front(); 63 | self.rtts.pop_front(); 64 | } 65 | 66 | // If necessary, recompute min rtt 67 | if recompute_base_rtt { 68 | self.base_rtt = std::u32::MAX; 69 | self.base_rtt_changed = true; 70 | for x in self.rtts.iter() { 71 | if *x < self.base_rtt { 72 | self.base_rtt = *x; 73 | } 74 | } 75 | assert!(self.base_rtt != std::u32::MAX); 76 | } 77 | 78 | // Delete all old increase/decrease samples 79 | while self.increase.len() > 40 { 80 | let increase: bool = self.increase.front().unwrap().1; 81 | if increase {self.num_increase -= 1;} 82 | else {self.num_decrease -= 1;} 83 | self.increase.pop_front(); 84 | } 85 | } 86 | 87 | pub fn get_base_rtt(&self) -> u32 { 88 | self.base_rtt 89 | } 90 | 91 | pub fn did_base_rtt_change(&self) -> bool { 92 | self.base_rtt_changed 93 | } 94 | 95 | pub fn new_rtt_sample(&mut self, rtt: u32, now: u64) { 96 | assert!(self.rtts.len() == self.times.len()); 97 | self.max_time = std::cmp::max(10_000_000, 30 * self.srtt as u64); 98 | if now < self.max_time { 99 | self.max_time = 0; 100 | } 101 | else { 102 | self.max_time = now - self.max_time; 103 | } 104 | 105 | // Push back data 106 | self.rtts.push_back(rtt); 107 | self.times.push_back(now); 108 | 109 | // Update min. RTT 110 | if rtt < self.base_rtt { 111 | self.base_rtt = rtt; 112 | } 113 | 114 | // Update srtt 115 | if self.srtt == 0 { 116 | self.srtt = rtt; 117 | } else { 118 | let alpha = 1. / 16.0f64; 119 | self.srtt = ((1. - alpha) * self.srtt as f64 + alpha * rtt as f64) as u32; 120 | } 121 | 122 | // Update increase 123 | if self.increase.len() == 0 || 124 | self.increase.back().unwrap().0 < now - 2 * self.base_rtt as u64 { 125 | let increase = self.cur_min_rtt > self.prev_min_rtt; 126 | self.increase.push_back((now, increase)); 127 | self.prev_min_rtt = self.cur_min_rtt; 128 | self.cur_min_rtt = std::u32::MAX; 129 | if increase {self.num_increase += 1;} 130 | else {self.num_decrease += 1;} 131 | } 132 | self.cur_min_rtt = std::cmp::min(self.cur_min_rtt, rtt); 133 | 134 | // Delete old data 135 | self.clear_old_hist(now); 136 | } 137 | 138 | pub fn tcp_detected(&mut self) -> bool { 139 | if self.rtts.len() == 0 { 140 | return false; 141 | } 142 | 143 | let mut min1 = std::u32::MAX; 144 | let mut max = 0; 145 | 146 | for i in 0..(self.rtts.len()) { 147 | if self.times[i] > 148 | self.times.back().unwrap() - self.srtt as u64*10 { 149 | min1 = std::cmp::min(min1, self.rtts[i]); 150 | max = std::cmp::max(max, self.rtts[i]); 151 | } 152 | // else if self.times[i] > 153 | // self.times.back().unwrap() - self.min_rtt as u64*8 { 154 | // min2 = std::cmp::min(min2, self.rtts[i]); 155 | // max = std::cmp::max(max, self.rtts[i]); 156 | // } 157 | } 158 | 159 | let thresh = self.base_rtt + (max - self.base_rtt) / 10 + 100; 160 | let res = min1 > thresh; 161 | println!("min1: {}, max: {}, thresh: {}", min1, max, thresh); 162 | res 163 | } 164 | 165 | pub fn num_tcp_detect_samples(&self) -> u32 { 166 | self.num_increase + self.num_decrease 167 | } 168 | } 169 | --------------------------------------------------------------------------------