From 8140a59205911170e151c95ed5596db7aa0d5ba5 Mon Sep 17 00:00:00 2001 From: eunhhu Date: Tue, 29 Sep 2026 11:49:32 +0100 Subject: Measure a link on paths of loss, reordering and a bottleneck, against quinn (097) M6 of design 011: with a 50 Mbit/s bottleneck, a link carries 21-41 times quinn's goodput when packets reorder, the same under random loss, and 1.3-3.5 times with both; its p99 at 50 records a second is the same or shorter; beside TCP CUBIC it takes 0.48-0.55 of the path, inside the guardrail. Only on a clean path is it 3-5% below quinn. --- docs/design/011-pure-transport.md | 7 +- docs/research/096-per-delivery-cpu.md | 2 + docs/research/097-lossy-paths.md | 210 +++++++++++++++++++++ .../2026-09-29-paths-linux-aarch64.jsonl | 126 +++++++++++++ 4 files changed, 344 insertions(+), 1 deletion(-) create mode 100644 docs/research/097-lossy-paths.md create mode 100644 research/experiments/020-lossy-paths/2026-09-29-paths-linux-aarch64.jsonl diff --git a/docs/design/011-pure-transport.md b/docs/design/011-pure-transport.md index d50b593..be25a86 100644 --- a/docs/design/011-pure-transport.md +++ b/docs/design/011-pure-transport.md @@ -1,6 +1,6 @@ # 011 — 연결 없는 전송: 전송의 상태를 앱의 데이터로 -작성일: 2026-09-28(같은 날 첫 판을 버리고 다시 씀). 상태: 설계. 1단계를 구현했고 M1, M2, M4, M5를 쟀다. +작성일: 2026-09-28(같은 날 첫 판을 버리고 다시 씀). 상태: 설계. 1단계를 구현했고 M1, M2, M4, M5, M6를 쟀다. [외부 피드백 002](../outside-feedback/feedback-002.md)의 "QUIC을 능가할 자체 raw socket 프로토콜"에서 시작한다. 1단계(링크 시제품과 kill -9 검사)는 [093](../research/093-connectionless-link.md)에 있다. 어느 쪽을 죽여도 핸드셰이크 없이 @@ -22,6 +22,11 @@ M5는 [096](../research/096-per-delivery-cpu.md)에 있다. 처음에는 작은 25 % 적고, 61 B에서 1.06–1.12배다. 설계가 적은 송수신 경로(GSO, GRO, 묶어 받기)를 이때 넣었고, 작은 기록을 담는 RECORDS 프레임을 더했다. +M6는 [097](../research/097-lossy-paths.md)에 있다. 처음에는 패킷 순서만 바뀌어도 링크가 1.5 Mbit/s로 주저앉았다. 늦게 온 패킷을 +알아보고 혼잡 사건을 되돌리게 하고, CUBIC, 패킷 경계에서 자르는 부분, 경로 MTU, 페이싱을 넣었다. 50 Mbit/s 병목에서 재정렬 +아래 quinn의 21–41배, 무작위 손실 아래 같은 처리량, 같거나 짧은 꼬리 지연이다. TCP CUBIC 옆에서 대역의 0.48–0.55를 쓴다. +가드레일(±25 %) 안이다. + 2026-09-29에 링크를 `link/`로 뗐다([009](009-layout.md)). 프로토콜은 이제 소켓, 스레드, 시계가 없는 상태이고 (`link/link-protocol.h`), UDP와 스레드는 그 위의 층이다. 그래서 한 스레드가 링크 여럿을 들 수 있다. M2를 이 보내는 쪽으로 다시 돌렸더니 결과가 같았다. 다만 재시작 뒤 가장 늦은 저장이 1초였다. 받았다고 했지만 저장 소식이 없는 기록을 1초 기다리기 diff --git a/docs/research/096-per-delivery-cpu.md b/docs/research/096-per-delivery-cpu.md index df2718c..fe45954 100644 --- a/docs/research/096-per-delivery-cpu.md +++ b/docs/research/096-per-delivery-cpu.md @@ -122,6 +122,8 @@ pure-serve 두 대를 잇고, 보내는 앱에 주문 2만 건을 쌓은 뒤 받 설계해야 한다. - H4("활성 링크의 전달당 CPU는 QUIC 기준선보다 나쁘지 않다")는 1 KiB 이상에서 선다. 작은 기록에서는 거의 선다. quinn의 값에는 기록마다의 확인과 정확히 한 번이 없다는 점을 함께 본다. +- 뒤에 M6([097](097-lossy-paths.md))을 하며 세 가지를 바꿨다: 패킷 경계에서 자르는 부분, 경로 MTU(1,452 B), 페이싱이다. 그 + 뒤 이 조건에서 기록 하나의 CPU가 1 KiB와 16 KiB에서 12 % 더 줄었다. 61 B는 같다(나누기 전 판과 번갈아 세 라운드). ## 한계와 다음 diff --git a/docs/research/097-lossy-paths.md b/docs/research/097-lossy-paths.md new file mode 100644 index 0000000..c30d9d8 --- /dev/null +++ b/docs/research/097-lossy-paths.md @@ -0,0 +1,210 @@ +# 097 — 손실과 재정렬, 병목: 재정렬에 무너지지 않고, 손실에서 QUIC만큼 + +2026-09-29. [설계 011](../design/011-pure-transport.md)의 M6다. [096](096-per-delivery-cpu.md)이 깨끗한 루프백에서 기록 하나의 +CPU를 쟀다면, 여기서는 지연, 손실, 재정렬, 병목이 있는 경로에서 링크 하나가 얼마나 나르는지, 기록 하나가 얼마나 늦는지, 옆의 +TCP와 대역을 어떻게 나누는지를 quinn과 댄다. + +착수 기준: + +- **바꿀 결정.** 011의 가드레일이다. TCP CUBIC과 나눈 몫이 ±25 %를 벗어나면(0.375–0.625 밖), 고친 뒤에야 채택한다. 처리량과 + 꼬리 지연은 quinn과 댄다. +- **최소 확인.** RTT 20·100 ms, 손실 0·1·5 %, 재정렬, 50 Mbit/s 병목에서 세 가지를 본다. 쌓인 1 KiB 기록을 푸는 처리량, 초당 + 50건의 꼬리 지연, TCP CUBIC 흐름 옆의 몫이다. +- **중단 기준.** 위의 ±25 %다. + +## 쉬운 말로 + +- 알아낸 것: + - 처음에는 패킷 순서만 바뀌어도 링크가 주저앉았다. 잃은 패킷이 없는데 50 Mbit/s 경로에서 1.5 Mbit/s였다. RFC 9002의 고정 + 문턱 때문이고, quinn도 같은 규칙을 쓴다. + - 늦게 온 패킷을 알아보고 창을 되돌리게 하니, 순서가 흔들려도 흔들리지 않을 때와 같은 45 Mbit/s를 낸다. 같은 경로에서 + quinn은 1–2 Mbit/s다(21–41배). + - 무작위 손실 아래 처리량은 quinn과 같다(0.97–1.07배). 손실과 재정렬이 함께 있으면 quinn의 1.3–3.5배다. + - 초당 50건의 꼬리 지연(p99)은 quinn과 같거나 짧다. RTT 100 ms에 손실 5 %에서 418 대 547 ms다. + - TCP CUBIC 흐름 옆에서 대역의 0.48–0.55를 쓴다. 가드레일(0.375–0.625) 안이다. 같은 경로에서 quinn은 지연이 1 ms만 흔들려도 + 0.02–0.07로 밀려난다. + - 깨끗한 경로의 처리량만 quinn보다 3–5 % 낮다. 패킷마다 붙는 머리 때문이다. +- 아직 모르는 것: 실제 무선·셀룰러 경로, 흐름이 많거나 RTT가 서로 다를 때, ngtcp2와의 비교, 저장소 옮기기(M3), 보안 검사. +- 사용 경험의 차이: 와이파이나 셀룰러처럼 패킷 순서가 흔들리는 망에서도 링크가 느려지지 않는다. 이 에뮬레이션에서 quinn은 + 1–3 ms의 흔들림만으로 한 자릿수 Mbit/s로 떨어졌다. + +## 한 것 + +### 프로토콜을 시간 밖으로 꺼냈다 + +측정 전에 링크를 `link/`로 떼고 둘로 나눴다([009](../design/009-layout.md)). `link/link-protocol.h`는 소켓, 스레드, 시계가 없는 +상태다. 패킷과 시각이 들어가고 패킷이 나온다. 그래서 두 쪽을 가상 시간의 네트워크에 놓을 수 있다. + +- 시뮬레이터([sim.c](../../research/experiments/020-lossy-paths/sim.c))는 병목(속도, 큐, 드롭테일), 지연, 흔들림(재정렬), 무작위 + 손실을 흉내 낸다. 같은 씨앗이면 같은 결과가 나온다. 1 KiB 기록 3만 건이 1초 안팎에 끝난다. +- 처음 돌린 결과가 문제를 곧바로 보여 줬다(RTT 20 ms, 50 Mbit/s, 1 KiB). + +| 경로 | 처리량 | 실제로 잃은 패킷 | 손실로 판정 | 가장 작은 창 | +|---|---:|---:|---:|---:| +| 깨끗함 | 41 Mbit/s | 0(큐 225) | 225 | 12,000 B | +| 재정렬만(흔들림 5 ms) | 1.5 Mbit/s | 0 | 308 | 2,400 B | +| 손실 1 % | 5.5 Mbit/s | 130 | 49 | 4,244 B | + +재정렬만 있고 잃은 것이 없는데, 순서가 바뀐 패킷을 손실로 판정해 창이 최소로 주저앉았다. RFC 9002의 고정 문턱(나중 패킷 3개, +RTT의 9/8) 때문이다. quinn도 같은 규칙을 쓴다. + +### 늦게 온 패킷 + +손실로 판정한 비행을 링에 잠시(RTT 두 번) 남겨 둔다. 그 사이에 확인이 오면 늦게 온 것이다. + +- 그 패킷이 나른 부분은 받은 것으로 친다. 아직 다시 보내지 않았으면 다시 보내지 않는다. +- 문턱을 넓힌다. RACK처럼 두 가지다. 나중 패킷 문턱은 실제로 본 재정렬 깊이로, 시간 문턱은 최소 RTT의 4분의 1씩 늘린다. 재정렬 + 없는 혼잡 사건이 16번 이어지면 반으로 줄인다. +- 혼잡 사건을 되돌린다. 앞 사건의 손실이 정해지기 전에 이어진 사건들을 한 에피소드로 묶는다. 에피소드의 손실이 모두 늦게 온 + 것이면, 첫 사건 전의 창, 문턱, CUBIC 상태로 돌아간다. 하나라도 진짜 손실이면(링에서 늦은 확인 없이 떠나면) 되돌리지 않는다. + +시뮬레이터에서 재정렬만 있을 때의 처리량이 RTT 20 ms에서 1.5 → 43.6 Mbit/s, RTT 100 ms에서 10 → 40.1 Mbit/s가 됐다. 재정렬이 +없을 때와 같다. + +### CUBIC, 쓰지 않은 창 + +- 혼잡 회피를 NewReno에서 CUBIC(RFC 9438)으로 바꿨다. quinn의 기본값이고, TCP CUBIC과 나란히 설 때 같은 규칙이어야 한다. + Reno 친화 추정은 RTT마다 0.53 데이터그램이다. 배포된 CUBIC(Linux, quinn)이 그렇게 한다. RFC 9438처럼 이전 최대를 넘은 뒤 + 1로 올리지는 않는다. +- 창을 다 쓰지 않을 때는(보낼 것이 없거나 받는 쪽 크레딧에 막히면) 창을 키우지 않는다(RFC 9002 §7.8). 전에는 크레딧에 막힌 + 채로 창이 1만 패킷 넘게 자랐다. +- Reno 추정은 확인이 올 때만큼, 또는 시간이 가는 만큼(RFC 8312) 가운데 앞선 쪽으로 키운다. 앱이 초당 몇 건만 보내는 링크는 + 확인이 드물어, 손실 뒤 필요한 창으로 돌아가는 데 오래 걸렸다. + +### 기록을 패킷 경계에서 자른다 + +전에는 기록을 1,000 B 조각으로 나눴다. 1 KiB 기록은 패킷에 하나씩만 들어가 패킷의 13 %가 비었다. + +- 이제 패킷의 남은 자리에 64 B 이상 들어가면 기록을 그만큼 자른다. 자른 자리는 바뀌지 않는다. 그래서 한 패킷이 나른 것은 늘 + 온전한 부분들이다. +- 받는 쪽은 조각 표 대신 받은 바이트 범위를 합쳐 둔다. 순서대로 오는 부분은 할당 없이 줄 끝에서 바로 이어 붙인다. +- 루프백에서 패킷이 1 KiB 기록에 8 %, 16 KiB 기록에 10 % 줄었다. 기록 하나의 CPU는 61 B와 1 KiB에서 같고, 16 KiB에서 5 % + 줄었다. + +### 경로가 나르는 만큼 큰 패킷 + +1,200 B로 시작한다. RTT를 알면 1,452 B로 채운 PING을 혼자, 조각내지 말라는 표시(DF)를 달고 보낸다(DPLPMTUD, RFC 8899). 확인이 +오면 그 크기를 쓴다. 탐침을 잃는 것은 혼잡이 아니다. 1초 뒤 다시, 세 번까지, 그 뒤로는 10분마다 해 본다. + +- CUBIC은 데이터그램 단위로 창을 키운다. 그래서 같은 손실률에서 패킷이 큰 쪽이 바이트로 더 빨리 자란다. quinn과의 손실 아래 + 차이는 대부분 이것이었다. +- GSO를 소켓 옵션이 아니라 묶음마다 제어 메시지로 청한다. 소켓 옵션이 걸려 있으면, 혼자 보낸 1,452 B 탐침을 시스템이 + 1,200 B와 252 B로 잘라 보냈다. `make check`의 UDP 검사가 이것을 잡았다. +- 루프백에서 패킷이 19–27 % 줄고, 기록 하나의 CPU가 1 KiB에서 12 %, 16 KiB에서 12 % 줄었다([096](096-per-delivery-cpu.md)의 + 조건, 나누기 전과 번갈아 세 라운드). + +### 페이싱 + +창을 RTT에 걸쳐 1.25배(느린 시작에서 2배)의 빠르기로 보낸다. 한 번에는 2 ms어치(10–256 데이터그램)까지만 보낸다(RFC 9002 §7.7). +보내는 쪽 상태가 다음에 보낼 수 있는 때를 알려 준다. + +### 측정 경로 + +비특권 이름공간의 루프백 하나를 경로로 쓴다([run.py](../../research/experiments/020-lossy-paths/run.py)). + +- 방향마다 netem이 지연(RTT의 절반), 흔들림, 손실을 준다. 받는 쪽 포트(40000–40007)로 가는 쪽만 그 뒤에 tbf 병목(50 Mbit/s, 큐는 + RTT 한 번어치)을 지난다. 되돌아오는 답과 TCP의 확인은 병목 뒤에 줄 서지 않는다. +- Pure와 quinn은 GSO 없이 보내고, TCP의 세그먼트는 1,500 B를 넘지 않게 한다. 큐 규칙은 GSO 묶음과 TSO 조각을 패킷 하나로 + 다루기 때문이다. +- 몫을 잴 때는 흐름마다 따로 된 프로세스를 동시에 띄우고, 60초 동안 20초부터 센다. 이때 경로의 지연을 1 ms 흔든다. 흔들림이 + 없으면 드롭테일 큐가 흐름들의 위상만으로 한쪽 패킷을 여덟 배 더 버린다(Floyd와 Jacobson, 1992). + - 흔들림 없이 쟀을 때 Pure는 TCP에게서 0.63–0.77, quinn에게서 0.69를 가져갔다. + - 같은 조건에서 Pure끼리는 0.47, 큐를 fq_codel로 바꾸면 0.49였다. + - 1 ms 흔들림에서는 RTT 20 ms에서 0.53이다. +- 이 경로를 맞추는 데 측정 여섯 벌을 버렸다. 이유는 이렇다. + - tbf 밑에 netem을 두면 tbf의 큐 한도가 사라진다. + - 답이 데이터 뒤에 줄 선다. + - GSO 묶음이 패킷 하나로 다뤄진다. + - 먼저 띄운 흐름이 몫을 더 가져간다. + - 흔들림이 없으면 위상 효과가 생긴다. + - 하네스가 재정렬을 틀림으로 셌다. + +## 결과 + +라즈베리 파이 5, 비특권 이름공간의 루프백이다. 병목은 50 Mbit/s이고 큐는 RTT 한 번어치다. 번갈아 세 라운드의 중앙값이다. +Pure는 링크와 리스너만 잰다([transport.c](../../research/experiments/019-idle-links/transport.c), 앱과 저장 없음). quinn은 한 +연결의 한 스트림이다. 기록은 1,013 B(1 KiB 항목의 주문)다. 원시 결과는 `research/experiments/020-lossy-paths/`의 +`2026-09-29-paths-linux-aarch64.jsonl`에 있다. 앞 단계의 결과도 같은 곳에 있다(`-parts-`는 세 라운드, `-mtu-`는 한 라운드). + +**쌓인 기록 풀기(Mbit/s, 기록의 바이트).** 흔들림 3 ms면 패킷 순서가 바뀐다. + +| RTT | 손실 | 흔들림 | Pure | quinn | Pure/quinn | +|---:|---:|---:|---:|---:|---:| +| 20 ms | 0 | 0 | 45.4 | 46.8 | 0.97 | +| 20 ms | 0 | 3 ms | 45.4 | 2.18 | 20.8 | +| 20 ms | 1 % | 0 | 6.84 | 6.54 | 1.05 | +| 20 ms | 1 % | 3 ms | 7.30 | 2.07 | 3.53 | +| 20 ms | 5 % | 0 | 3.08 | 2.89 | 1.07 | +| 20 ms | 5 % | 3 ms | 3.27 | 1.62 | 2.02 | +| 100 ms | 0 | 0 | 44.9 | 47.3 | 0.95 | +| 100 ms | 0 | 3 ms | 45.2 | 1.11 | 40.8 | +| 100 ms | 1 % | 0 | 1.58 | 1.56 | 1.01 | +| 100 ms | 1 % | 3 ms | 1.43 | 0.82 | 1.74 | +| 100 ms | 5 % | 0 | 0.60 | 0.62 | 0.97 | +| 100 ms | 5 % | 3 ms | 0.65 | 0.49 | 1.33 | + +**단계마다, RTT 20 ms에서.** 무엇이 얼마나 바꿨는지다. + +| Pure | 깨끗함 | 재정렬 | 손실 1 % | 손실 5 % | +|---|---:|---:|---:|---:| +| 늦은 패킷, CUBIC, 부분까지(세 라운드) | 44.3 | 44.3 | 5.83 | 2.26 | +| + 경로 MTU(한 라운드) | 45.4 | 45.4 | 8.24 | 2.80 | +| + 페이싱, Reno 0.53(세 라운드, 최종) | 45.4 | 45.4 | 6.84 | 3.08 | +| quinn(최종과 같은 때) | 46.8 | 2.18 | 6.54 | 2.89 | + +경로 MTU를 쓴 판의 손실 1 % 값(8.24)은 RFC 9438처럼 Reno 추정을 이전 최대 뒤에 RTT마다 1 데이터그램으로 키운 판이다. 배포된 +CUBIC과 같게 0.53으로 두니 6.84가 됐다. + +**초당 50건의 꼬리 지연(ms, 넣은 때부터 넘겨받은 때까지).** Pure / quinn이다. + +| RTT | 손실 | p50 | p99 | 최대 | +|---:|---:|---|---|---| +| 20 ms | 0 | 10 / 10 | 10 / 10 | 10 / 10 | +| 20 ms | 1 % | 10 / 10 | 50 / 50 | 50 / 83 | +| 20 ms | 5 % | 10 / 10 | 70 / 96 | 90 / 137 | +| 100 ms | 0 | 50 / 50 | 50 / 50 | 50 / 50 | +| 100 ms | 1 % | 50 / 50 | 170 / 196 | 190 / 282 | +| 100 ms | 5 % | 70 / 110 | 418 / 547 | 517 / 686 | + +잃은 패킷은 다음 패킷의 확인이 오는 순간에 손실로 판정해 곧바로 다시 보낸다(RTT 100 ms, 20 ms 간격이면 보낸 뒤 약 120 ms). +p99가 170 ms인 까닭이다. 시뮬레이터도 같은 값을 준다. + +**TCP CUBIC 옆의 몫(60초 가운데 20초부터, 경로 지연 1 ms 흔들림).** + +| RTT | Pure | 라운드별 | TCP끼리 | quinn | +|---:|---:|---|---:|---:| +| 20 ms | 0.484 | 0.517, 0.484, 0.483 | 0.518 | 0.065 | +| 100 ms | 0.549 | 0.560, 0.545, 0.549 | 0.482 | 0.018 | + +- TCP끼리의 몫도 라운드마다 0.44–0.58 사이에서 움직인다. Pure는 그 범위 안이다. +- quinn은 1 ms 흔들림을 손실로 읽어 창을 줄인다. 같은 흔들림에서 quinn 혼자 몰아 보낼 때도 1–2 Mbit/s였다. +- 큐를 fq_codel로 바꾸면(흐름마다 공정하게 줄 세움, 한 라운드) Pure 0.49·0.48, quinn 0.50·0.50이다. + +## 판정 + +- **가드레일은 통과다.** TCP CUBIC 옆에서 Pure의 몫은 0.48(RTT 20 ms)과 0.55(RTT 100 ms)다. 라운드별로 0.48–0.56으로, + 0.375–0.625 안이고 TCP끼리의 흔들림과 같은 범위다. +- **M6의 나머지.** + - 재정렬에서 quinn의 21–41배다. + - 무작위 손실에서는 같다(0.97–1.07배). + - 손실과 재정렬이 함께 있으면 1.3–3.5배다. + - 꼬리 지연은 같거나 짧다. + - 깨끗한 경로에서만 3–5 % 낮다. +- **M5는 더 좋아졌다.** 부분, 경로 MTU, 페이싱을 넣은 뒤 기록 하나의 CPU가 1 KiB와 16 KiB에서 12 % 줄었다. 61 B는 같다 + (096의 조건). +- 011의 5단계("M5·M6 가드레일을 잰다")가 끝났다. 남은 것은 4단계다: 에폭 바꿈, 경로 바뀜, 저장소 옮기기(H3, M3), 보안 검사. + +## 한계와 다음 + +- **경로는 에뮬레이션이다.** + - 루프백 하나에 netem과 tbf를 얹었다. 실제 무선·셀룰러, ECMP의 재정렬, 여러 AQM이 아니다. + - 몫은 두 흐름, 같은 RTT만 봤다. +- **무작위 손실 아래는 손실을 혼잡으로 읽는 모든 제어와 같다.** 손실 5 %, RTT 100 ms에서 0.6 Mbit/s다. 넘으려면 모델 기반 제어 + (BBR 계열)나 여분 전송이 필요하다. 그것은 가드레일(TCP와의 몫)과 함께 따져야 한다. +- **꼬리 지연은 확인으로 알 수 있는 가장 이른 때에 다시 보낸다.** 더 줄이려면, 앱이 한가해 창이 빌 때 기록을 한 번 더 보내는 + 여분이 필요하다. +- **깨끗한 경로의 3–5 %.** 패킷마다 스트림 이름(약 25 B)을 싣는다. 096의 짧은 이름표 과제와 같다. +- **경로 MTU는 늘리기만 한다.** 경로가 도중에 좁아지면(블랙홀) 알아채지 못한다. RFC 8899의 블랙홀 탐지는 다음이다. +- **페이싱은 보내는 스레드의 poll(ms 단위)에 묶인다.** +- **QUIC 비교는 quinn 0.11 하나다.** GSO 없이 쟀다. ngtcp2는 아직이다. quinn이 흔들림에 무너진 것은 RFC 9002의 고정 문턱 때문으로 + 보지만, quinn의 코드로 확인하지는 않았다. diff --git a/research/experiments/020-lossy-paths/2026-09-29-paths-linux-aarch64.jsonl b/research/experiments/020-lossy-paths/2026-09-29-paths-linux-aarch64.jsonl new file mode 100644 index 0000000..fd25e28 --- /dev/null +++ b/research/experiments/020-lossy-paths/2026-09-29-paths-linux-aarch64.jsonl @@ -0,0 +1,126 @@ +{"kind": "bulk", "who": "pure", "rtt_ms": 20, "loss": 0, "jitter_ms": 0, "seconds": 20, "round": 0, "mbit": 45.39, "resent": 502, "lost": 251, "late": 0, "undone": 0, "packets": 84106} +{"kind": "bulk", "who": "quinn", "rtt_ms": 20, "loss": 0, "jitter_ms": 0, "seconds": 20, "round": 0, "mbit": 46.77, "waited_ms_p50": 0.0, "waited_ms_p99": 0.0, "waited_ms_max": 0.0} +{"kind": "bulk", "who": "pure", "rtt_ms": 20, "loss": 0, "jitter_ms": 3, "seconds": 20, "round": 0, "mbit": 45.39, "resent": 523, "lost": 262, "late": 22, "undone": 8, "packets": 84090} +{"kind": "bulk", "who": "quinn", "rtt_ms": 20, "loss": 0, "jitter_ms": 3, "seconds": 20, "round": 0, "mbit": 2.15, "waited_ms_p50": 0.0, "waited_ms_p99": 0.0, "waited_ms_max": 0.0} +{"kind": "bulk", "who": "pure", "rtt_ms": 20, "loss": 1, "jitter_ms": 0, "seconds": 20, "round": 0, "mbit": 6.97, "resent": 254, "lost": 127, "late": 0, "undone": 0, "packets": 13289} +{"kind": "bulk", "who": "quinn", "rtt_ms": 20, "loss": 1, "jitter_ms": 0, "seconds": 20, "round": 0, "mbit": 6.34, "waited_ms_p50": 0.0, "waited_ms_p99": 0.0, "waited_ms_max": 0.0} +{"kind": "bulk", "who": "pure", "rtt_ms": 20, "loss": 1, "jitter_ms": 3, "seconds": 20, "round": 0, "mbit": 7.3, "resent": 369, "lost": 192, "late": 39, "undone": 19, "packets": 14528} +{"kind": "bulk", "who": "quinn", "rtt_ms": 20, "loss": 1, "jitter_ms": 3, "seconds": 20, "round": 0, "mbit": 2.07, "waited_ms_p50": 0.0, "waited_ms_p99": 0.0, "waited_ms_max": 0.0} +{"kind": "bulk", "who": "pure", "rtt_ms": 20, "loss": 5, "jitter_ms": 0, "seconds": 20, "round": 0, "mbit": 3.08, "resent": 616, "lost": 290, "late": 0, "undone": 0, "packets": 5987} +{"kind": "bulk", "who": "quinn", "rtt_ms": 20, "loss": 5, "jitter_ms": 0, "seconds": 20, "round": 0, "mbit": 2.89, "waited_ms_p50": 0.0, "waited_ms_p99": 0.0, "waited_ms_max": 0.0} +{"kind": "bulk", "who": "pure", "rtt_ms": 20, "loss": 5, "jitter_ms": 3, "seconds": 20, "round": 0, "mbit": 3.27, "resent": 687, "lost": 357, "late": 40, "undone": 24, "packets": 6517} +{"kind": "bulk", "who": "quinn", "rtt_ms": 20, "loss": 5, "jitter_ms": 3, "seconds": 20, "round": 0, "mbit": 1.66, "waited_ms_p50": 0.0, "waited_ms_p99": 0.0, "waited_ms_max": 0.0} +{"kind": "paced", "who": "pure", "rtt_ms": 20, "loss": 0, "jitter_ms": 0, "seconds": 20, "round": 0, "mbit": 0.41, "waited_ms_p50": 10.042, "waited_ms_p99": 10.118, "waited_ms_max": 10.319, "resent": 0, "lost": 0, "late": 0, "undone": 0, "packets": 1001} +{"kind": "paced", "who": "quinn", "rtt_ms": 20, "loss": 0, "jitter_ms": 0, "seconds": 20, "round": 0, "mbit": 0.41, "waited_ms_p50": 10.055, "waited_ms_p99": 10.182, "waited_ms_max": 10.272} +{"kind": "paced", "who": "pure", "rtt_ms": 20, "loss": 1, "jitter_ms": 0, "seconds": 20, "round": 0, "mbit": 0.41, "waited_ms_p50": 10.036, "waited_ms_p99": 50.032, "waited_ms_max": 51.068, "resent": 12, "lost": 12, "late": 0, "undone": 0, "packets": 1013} +{"kind": "paced", "who": "quinn", "rtt_ms": 20, "loss": 1, "jitter_ms": 0, "seconds": 20, "round": 0, "mbit": 0.41, "waited_ms_p50": 10.07, "waited_ms_p99": 56.362, "waited_ms_max": 96.848} +{"kind": "paced", "who": "pure", "rtt_ms": 20, "loss": 5, "jitter_ms": 0, "seconds": 20, "round": 0, "mbit": 0.41, "waited_ms_p50": 10.045, "waited_ms_p99": 50.152, "waited_ms_max": 90.101, "resent": 51, "lost": 51, "late": 0, "undone": 0, "packets": 1052} +{"kind": "paced", "who": "quinn", "rtt_ms": 20, "loss": 5, "jitter_ms": 0, "seconds": 20, "round": 0, "mbit": 0.41, "waited_ms_p50": 10.068, "waited_ms_p99": 96.603, "waited_ms_max": 190.435} +{"kind": "share", "who": "pure", "rtt_ms": 20, "loss": 0, "jitter_ms": 1, "seconds": 60, "round": 0, "mbit": 24.05, "tcp_mbit": 22.47, "share": 0.517} +{"kind": "share", "who": "quinn", "rtt_ms": 20, "loss": 0, "jitter_ms": 1, "seconds": 60, "round": 0, "mbit": 3.1, "tcp_mbit": 44.63, "share": 0.065} +{"kind": "share", "who": "tcp", "rtt_ms": 20, "loss": 0, "jitter_ms": 1, "seconds": 60, "round": 0, "mbit": 24.75, "tcp_mbit": 23.07, "share": 0.518} +{"kind": "bulk", "who": "pure", "rtt_ms": 100, "loss": 0, "jitter_ms": 0, "seconds": 20, "round": 0, "mbit": 44.86, "resent": 0, "lost": 0, "late": 0, "undone": 0, "packets": 107900} +{"kind": "bulk", "who": "quinn", "rtt_ms": 100, "loss": 0, "jitter_ms": 0, "seconds": 20, "round": 0, "mbit": 47.27, "waited_ms_p50": 0.0, "waited_ms_p99": 0.0, "waited_ms_max": 0.0} +{"kind": "bulk", "who": "pure", "rtt_ms": 100, "loss": 0, "jitter_ms": 3, "seconds": 20, "round": 0, "mbit": 45.23, "resent": 34, "lost": 19, "late": 19, "undone": 10, "packets": 86008} +{"kind": "bulk", "who": "quinn", "rtt_ms": 100, "loss": 0, "jitter_ms": 3, "seconds": 20, "round": 0, "mbit": 1.11, "waited_ms_p50": 0.0, "waited_ms_p99": 0.0, "waited_ms_max": 0.0} +{"kind": "bulk", "who": "pure", "rtt_ms": 100, "loss": 1, "jitter_ms": 0, "seconds": 20, "round": 0, "mbit": 1.58, "resent": 46, "lost": 23, "late": 0, "undone": 0, "packets": 2933} +{"kind": "bulk", "who": "quinn", "rtt_ms": 100, "loss": 1, "jitter_ms": 0, "seconds": 20, "round": 0, "mbit": 1.56, "waited_ms_p50": 0.0, "waited_ms_p99": 0.0, "waited_ms_max": 0.0} +{"kind": "bulk", "who": "pure", "rtt_ms": 100, "loss": 1, "jitter_ms": 3, "seconds": 20, "round": 0, "mbit": 1.43, "resent": 78, "lost": 40, "late": 8, "undone": 2, "packets": 2934} +{"kind": "bulk", "who": "quinn", "rtt_ms": 100, "loss": 1, "jitter_ms": 3, "seconds": 20, "round": 0, "mbit": 0.68, "waited_ms_p50": 0.0, "waited_ms_p99": 0.0, "waited_ms_max": 0.0} +{"kind": "bulk", "who": "pure", "rtt_ms": 100, "loss": 5, "jitter_ms": 0, "seconds": 20, "round": 0, "mbit": 0.67, "resent": 121, "lost": 59, "late": 0, "undone": 0, "packets": 1421} +{"kind": "bulk", "who": "quinn", "rtt_ms": 100, "loss": 5, "jitter_ms": 0, "seconds": 20, "round": 0, "mbit": 0.57, "waited_ms_p50": 0.0, "waited_ms_p99": 0.0, "waited_ms_max": 0.0} +{"kind": "bulk", "who": "pure", "rtt_ms": 100, "loss": 5, "jitter_ms": 3, "seconds": 20, "round": 0, "mbit": 0.69, "resent": 131, "lost": 67, "late": 10, "undone": 3, "packets": 1304} +{"kind": "bulk", "who": "quinn", "rtt_ms": 100, "loss": 5, "jitter_ms": 3, "seconds": 20, "round": 0, "mbit": 0.44, "waited_ms_p50": 0.0, "waited_ms_p99": 0.0, "waited_ms_max": 0.0} +{"kind": "paced", "who": "pure", "rtt_ms": 100, "loss": 0, "jitter_ms": 0, "seconds": 20, "round": 0, "mbit": 0.41, "waited_ms_p50": 50.045, "waited_ms_p99": 50.099, "waited_ms_max": 50.411, "resent": 0, "lost": 0, "late": 0, "undone": 0, "packets": 1001} +{"kind": "paced", "who": "quinn", "rtt_ms": 100, "loss": 0, "jitter_ms": 0, "seconds": 20, "round": 0, "mbit": 0.41, "waited_ms_p50": 50.051, "waited_ms_p99": 50.171, "waited_ms_max": 50.228} +{"kind": "paced", "who": "pure", "rtt_ms": 100, "loss": 1, "jitter_ms": 0, "seconds": 20, "round": 0, "mbit": 0.41, "waited_ms_p50": 50.038, "waited_ms_p99": 169.988, "waited_ms_max": 190.054, "resent": 9, "lost": 9, "late": 0, "undone": 0, "packets": 1007} +{"kind": "paced", "who": "quinn", "rtt_ms": 100, "loss": 1, "jitter_ms": 0, "seconds": 20, "round": 0, "mbit": 0.41, "waited_ms_p50": 50.066, "waited_ms_p99": 190.765, "waited_ms_max": 282.411} +{"kind": "paced", "who": "pure", "rtt_ms": 100, "loss": 5, "jitter_ms": 0, "seconds": 20, "round": 0, "mbit": 0.41, "waited_ms_p50": 70.15, "waited_ms_p99": 417.557, "waited_ms_max": 517.231, "resent": 61, "lost": 49, "late": 0, "undone": 0, "packets": 959} +{"kind": "paced", "who": "quinn", "rtt_ms": 100, "loss": 5, "jitter_ms": 0, "seconds": 20, "round": 0, "mbit": 0.41, "waited_ms_p50": 96.372, "waited_ms_p99": 546.84, "waited_ms_max": 685.711} +{"kind": "share", "who": "pure", "rtt_ms": 100, "loss": 0, "jitter_ms": 1, "seconds": 60, "round": 0, "mbit": 26.0, "tcp_mbit": 20.43, "share": 0.56} +{"kind": "share", "who": "quinn", "rtt_ms": 100, "loss": 0, "jitter_ms": 1, "seconds": 60, "round": 0, "mbit": 0.77, "tcp_mbit": 47.03, "share": 0.016} +{"kind": "share", "who": "tcp", "rtt_ms": 100, "loss": 0, "jitter_ms": 1, "seconds": 60, "round": 0, "mbit": 20.92, "tcp_mbit": 26.9, "share": 0.437} +{"kind": "bulk", "who": "pure", "rtt_ms": 20, "loss": 0, "jitter_ms": 0, "seconds": 20, "round": 1, "mbit": 45.39, "resent": 498, "lost": 249, "late": 0, "undone": 0, "packets": 84109} +{"kind": "bulk", "who": "quinn", "rtt_ms": 20, "loss": 0, "jitter_ms": 0, "seconds": 20, "round": 1, "mbit": 46.77, "waited_ms_p50": 0.0, "waited_ms_p99": 0.0, "waited_ms_max": 0.0} +{"kind": "bulk", "who": "pure", "rtt_ms": 20, "loss": 0, "jitter_ms": 3, "seconds": 20, "round": 1, "mbit": 45.38, "resent": 538, "lost": 271, "late": 25, "undone": 8, "packets": 84939} +{"kind": "bulk", "who": "quinn", "rtt_ms": 20, "loss": 0, "jitter_ms": 3, "seconds": 20, "round": 1, "mbit": 2.18, "waited_ms_p50": 0.0, "waited_ms_p99": 0.0, "waited_ms_max": 0.0} +{"kind": "bulk", "who": "pure", "rtt_ms": 20, "loss": 1, "jitter_ms": 0, "seconds": 20, "round": 1, "mbit": 6.38, "resent": 266, "lost": 133, "late": 0, "undone": 0, "packets": 12304} +{"kind": "bulk", "who": "quinn", "rtt_ms": 20, "loss": 1, "jitter_ms": 0, "seconds": 20, "round": 1, "mbit": 6.54, "waited_ms_p50": 0.0, "waited_ms_p99": 0.0, "waited_ms_max": 0.0} +{"kind": "bulk", "who": "pure", "rtt_ms": 20, "loss": 1, "jitter_ms": 3, "seconds": 20, "round": 1, "mbit": 7.06, "resent": 365, "lost": 190, "late": 36, "undone": 18, "packets": 14345} +{"kind": "bulk", "who": "quinn", "rtt_ms": 20, "loss": 1, "jitter_ms": 3, "seconds": 20, "round": 1, "mbit": 2.03, "waited_ms_p50": 0.0, "waited_ms_p99": 0.0, "waited_ms_max": 0.0} +{"kind": "bulk", "who": "pure", "rtt_ms": 20, "loss": 5, "jitter_ms": 0, "seconds": 20, "round": 1, "mbit": 3.11, "resent": 598, "lost": 274, "late": 0, "undone": 0, "packets": 6164} +{"kind": "bulk", "who": "quinn", "rtt_ms": 20, "loss": 5, "jitter_ms": 0, "seconds": 20, "round": 1, "mbit": 3.01, "waited_ms_p50": 0.0, "waited_ms_p99": 0.0, "waited_ms_max": 0.0} +{"kind": "bulk", "who": "pure", "rtt_ms": 20, "loss": 5, "jitter_ms": 3, "seconds": 20, "round": 1, "mbit": 3.27, "resent": 653, "lost": 337, "late": 40, "undone": 22, "packets": 6329} +{"kind": "bulk", "who": "quinn", "rtt_ms": 20, "loss": 5, "jitter_ms": 3, "seconds": 20, "round": 1, "mbit": 1.57, "waited_ms_p50": 0.0, "waited_ms_p99": 0.0, "waited_ms_max": 0.0} +{"kind": "paced", "who": "pure", "rtt_ms": 20, "loss": 0, "jitter_ms": 0, "seconds": 20, "round": 1, "mbit": 0.41, "waited_ms_p50": 10.036, "waited_ms_p99": 10.116, "waited_ms_max": 10.428, "resent": 0, "lost": 0, "late": 0, "undone": 0, "packets": 1001} +{"kind": "paced", "who": "quinn", "rtt_ms": 20, "loss": 0, "jitter_ms": 0, "seconds": 20, "round": 1, "mbit": 0.41, "waited_ms_p50": 10.057, "waited_ms_p99": 10.187, "waited_ms_max": 10.259} +{"kind": "paced", "who": "pure", "rtt_ms": 20, "loss": 1, "jitter_ms": 0, "seconds": 20, "round": 1, "mbit": 0.41, "waited_ms_p50": 10.043, "waited_ms_p99": 30.126, "waited_ms_max": 50.143, "resent": 9, "lost": 9, "late": 0, "undone": 0, "packets": 1010} +{"kind": "paced", "who": "quinn", "rtt_ms": 20, "loss": 1, "jitter_ms": 0, "seconds": 20, "round": 1, "mbit": 0.41, "waited_ms_p50": 10.066, "waited_ms_p99": 50.37, "waited_ms_max": 83.454} +{"kind": "paced", "who": "pure", "rtt_ms": 20, "loss": 5, "jitter_ms": 0, "seconds": 20, "round": 1, "mbit": 0.41, "waited_ms_p50": 10.046, "waited_ms_p99": 70.108, "waited_ms_max": 90.145, "resent": 64, "lost": 64, "late": 0, "undone": 0, "packets": 1066} +{"kind": "paced", "who": "quinn", "rtt_ms": 20, "loss": 5, "jitter_ms": 0, "seconds": 20, "round": 1, "mbit": 0.41, "waited_ms_p50": 10.067, "waited_ms_p99": 84.667, "waited_ms_max": 124.965} +{"kind": "share", "who": "pure", "rtt_ms": 20, "loss": 0, "jitter_ms": 1, "seconds": 60, "round": 1, "mbit": 22.58, "tcp_mbit": 24.03, "share": 0.484} +{"kind": "share", "who": "quinn", "rtt_ms": 20, "loss": 0, "jitter_ms": 1, "seconds": 60, "round": 1, "mbit": 3.23, "tcp_mbit": 44.5, "share": 0.068} +{"kind": "share", "who": "tcp", "rtt_ms": 20, "loss": 0, "jitter_ms": 1, "seconds": 60, "round": 1, "mbit": 25.86, "tcp_mbit": 21.96, "share": 0.541} +{"kind": "bulk", "who": "pure", "rtt_ms": 100, "loss": 0, "jitter_ms": 0, "seconds": 20, "round": 1, "mbit": 44.86, "resent": 0, "lost": 0, "late": 0, "undone": 0, "packets": 107727} +{"kind": "bulk", "who": "quinn", "rtt_ms": 100, "loss": 0, "jitter_ms": 0, "seconds": 20, "round": 1, "mbit": 47.27, "waited_ms_p50": 0.0, "waited_ms_p99": 0.0, "waited_ms_max": 0.0} +{"kind": "bulk", "who": "pure", "rtt_ms": 100, "loss": 0, "jitter_ms": 3, "seconds": 20, "round": 1, "mbit": 45.23, "resent": 50, "lost": 26, "late": 26, "undone": 13, "packets": 85881} +{"kind": "bulk", "who": "quinn", "rtt_ms": 100, "loss": 0, "jitter_ms": 3, "seconds": 20, "round": 1, "mbit": 1.11, "waited_ms_p50": 0.0, "waited_ms_p99": 0.0, "waited_ms_max": 0.0} +{"kind": "bulk", "who": "pure", "rtt_ms": 100, "loss": 1, "jitter_ms": 0, "seconds": 20, "round": 1, "mbit": 1.49, "resent": 66, "lost": 33, "late": 0, "undone": 0, "packets": 3884} +{"kind": "bulk", "who": "quinn", "rtt_ms": 100, "loss": 1, "jitter_ms": 0, "seconds": 20, "round": 1, "mbit": 1.3, "waited_ms_p50": 0.0, "waited_ms_p99": 0.0, "waited_ms_max": 0.0} +{"kind": "bulk", "who": "pure", "rtt_ms": 100, "loss": 1, "jitter_ms": 3, "seconds": 20, "round": 1, "mbit": 1.09, "resent": 80, "lost": 39, "late": 4, "undone": 2, "packets": 2579} +{"kind": "bulk", "who": "quinn", "rtt_ms": 100, "loss": 1, "jitter_ms": 3, "seconds": 20, "round": 1, "mbit": 0.98, "waited_ms_p50": 0.0, "waited_ms_p99": 0.0, "waited_ms_max": 0.0} +{"kind": "bulk", "who": "pure", "rtt_ms": 100, "loss": 5, "jitter_ms": 0, "seconds": 20, "round": 1, "mbit": 0.6, "resent": 150, "lost": 66, "late": 0, "undone": 0, "packets": 1290} +{"kind": "bulk", "who": "quinn", "rtt_ms": 100, "loss": 5, "jitter_ms": 0, "seconds": 20, "round": 1, "mbit": 0.63, "waited_ms_p50": 0.0, "waited_ms_p99": 0.0, "waited_ms_max": 0.0} +{"kind": "bulk", "who": "pure", "rtt_ms": 100, "loss": 5, "jitter_ms": 3, "seconds": 20, "round": 1, "mbit": 0.65, "resent": 134, "lost": 68, "late": 8, "undone": 4, "packets": 1282} +{"kind": "bulk", "who": "quinn", "rtt_ms": 100, "loss": 5, "jitter_ms": 3, "seconds": 20, "round": 1, "mbit": 0.49, "waited_ms_p50": 0.0, "waited_ms_p99": 0.0, "waited_ms_max": 0.0} +{"kind": "paced", "who": "pure", "rtt_ms": 100, "loss": 0, "jitter_ms": 0, "seconds": 20, "round": 1, "mbit": 0.41, "waited_ms_p50": 50.036, "waited_ms_p99": 50.129, "waited_ms_max": 50.336, "resent": 0, "lost": 0, "late": 0, "undone": 0, "packets": 1001} +{"kind": "paced", "who": "quinn", "rtt_ms": 100, "loss": 0, "jitter_ms": 0, "seconds": 20, "round": 1, "mbit": 0.41, "waited_ms_p50": 50.066, "waited_ms_p99": 50.178, "waited_ms_max": 50.818} +{"kind": "paced", "who": "pure", "rtt_ms": 100, "loss": 1, "jitter_ms": 0, "seconds": 20, "round": 1, "mbit": 0.41, "waited_ms_p50": 50.042, "waited_ms_p99": 170.136, "waited_ms_max": 250.16, "resent": 12, "lost": 11, "late": 0, "undone": 0, "packets": 1001} +{"kind": "paced", "who": "quinn", "rtt_ms": 100, "loss": 1, "jitter_ms": 0, "seconds": 20, "round": 1, "mbit": 0.41, "waited_ms_p50": 50.074, "waited_ms_p99": 196.403, "waited_ms_max": 236.965} +{"kind": "paced", "who": "pure", "rtt_ms": 100, "loss": 5, "jitter_ms": 0, "seconds": 20, "round": 1, "mbit": 0.41, "waited_ms_p50": 50.243, "waited_ms_p99": 330.278, "waited_ms_max": 437.53, "resent": 57, "lost": 43, "late": 0, "undone": 0, "packets": 968} +{"kind": "paced", "who": "quinn", "rtt_ms": 100, "loss": 5, "jitter_ms": 0, "seconds": 20, "round": 1, "mbit": 0.41, "waited_ms_p50": 130.682, "waited_ms_p99": 751.983, "waited_ms_max": 872.947} +{"kind": "share", "who": "pure", "rtt_ms": 100, "loss": 0, "jitter_ms": 1, "seconds": 60, "round": 1, "mbit": 25.2, "tcp_mbit": 21.08, "share": 0.545} +{"kind": "share", "who": "quinn", "rtt_ms": 100, "loss": 0, "jitter_ms": 1, "seconds": 60, "round": 1, "mbit": 1.07, "tcp_mbit": 46.74, "share": 0.022} +{"kind": "share", "who": "tcp", "rtt_ms": 100, "loss": 0, "jitter_ms": 1, "seconds": 60, "round": 1, "mbit": 27.54, "tcp_mbit": 20.27, "share": 0.576} +{"kind": "bulk", "who": "pure", "rtt_ms": 20, "loss": 0, "jitter_ms": 0, "seconds": 20, "round": 2, "mbit": 45.39, "resent": 498, "lost": 249, "late": 0, "undone": 0, "packets": 84110} +{"kind": "bulk", "who": "quinn", "rtt_ms": 20, "loss": 0, "jitter_ms": 0, "seconds": 20, "round": 2, "mbit": 46.77, "waited_ms_p50": 0.0, "waited_ms_p99": 0.0, "waited_ms_max": 0.0} +{"kind": "bulk", "who": "pure", "rtt_ms": 20, "loss": 0, "jitter_ms": 3, "seconds": 20, "round": 2, "mbit": 45.38, "resent": 499, "lost": 249, "late": 21, "undone": 5, "packets": 84042} +{"kind": "bulk", "who": "quinn", "rtt_ms": 20, "loss": 0, "jitter_ms": 3, "seconds": 20, "round": 2, "mbit": 2.22, "waited_ms_p50": 0.0, "waited_ms_p99": 0.0, "waited_ms_max": 0.0} +{"kind": "bulk", "who": "pure", "rtt_ms": 20, "loss": 1, "jitter_ms": 0, "seconds": 20, "round": 2, "mbit": 6.84, "resent": 272, "lost": 136, "late": 0, "undone": 0, "packets": 13293} +{"kind": "bulk", "who": "quinn", "rtt_ms": 20, "loss": 1, "jitter_ms": 0, "seconds": 20, "round": 2, "mbit": 6.64, "waited_ms_p50": 0.0, "waited_ms_p99": 0.0, "waited_ms_max": 0.0} +{"kind": "bulk", "who": "pure", "rtt_ms": 20, "loss": 1, "jitter_ms": 3, "seconds": 20, "round": 2, "mbit": 7.92, "resent": 318, "lost": 166, "late": 32, "undone": 20, "packets": 14994} +{"kind": "bulk", "who": "quinn", "rtt_ms": 20, "loss": 1, "jitter_ms": 3, "seconds": 20, "round": 2, "mbit": 2.13, "waited_ms_p50": 0.0, "waited_ms_p99": 0.0, "waited_ms_max": 0.0} +{"kind": "bulk", "who": "pure", "rtt_ms": 20, "loss": 5, "jitter_ms": 0, "seconds": 20, "round": 2, "mbit": 3.04, "resent": 641, "lost": 301, "late": 0, "undone": 0, "packets": 5951} +{"kind": "bulk", "who": "quinn", "rtt_ms": 20, "loss": 5, "jitter_ms": 0, "seconds": 20, "round": 2, "mbit": 2.87, "waited_ms_p50": 0.0, "waited_ms_p99": 0.0, "waited_ms_max": 0.0} +{"kind": "bulk", "who": "pure", "rtt_ms": 20, "loss": 5, "jitter_ms": 3, "seconds": 20, "round": 2, "mbit": 3.24, "resent": 657, "lost": 339, "late": 38, "undone": 17, "packets": 6303} +{"kind": "bulk", "who": "quinn", "rtt_ms": 20, "loss": 5, "jitter_ms": 3, "seconds": 20, "round": 2, "mbit": 1.62, "waited_ms_p50": 0.0, "waited_ms_p99": 0.0, "waited_ms_max": 0.0} +{"kind": "paced", "who": "pure", "rtt_ms": 20, "loss": 0, "jitter_ms": 0, "seconds": 20, "round": 2, "mbit": 0.41, "waited_ms_p50": 10.037, "waited_ms_p99": 10.119, "waited_ms_max": 10.424, "resent": 0, "lost": 0, "late": 0, "undone": 0, "packets": 1001} +{"kind": "paced", "who": "quinn", "rtt_ms": 20, "loss": 0, "jitter_ms": 0, "seconds": 20, "round": 2, "mbit": 0.41, "waited_ms_p50": 10.058, "waited_ms_p99": 10.178, "waited_ms_max": 10.268} +{"kind": "paced", "who": "pure", "rtt_ms": 20, "loss": 1, "jitter_ms": 0, "seconds": 20, "round": 2, "mbit": 0.41, "waited_ms_p50": 10.048, "waited_ms_p99": 50.028, "waited_ms_max": 50.188, "resent": 10, "lost": 10, "late": 0, "undone": 0, "packets": 1011} +{"kind": "paced", "who": "quinn", "rtt_ms": 20, "loss": 1, "jitter_ms": 0, "seconds": 20, "round": 2, "mbit": 0.41, "waited_ms_p50": 10.068, "waited_ms_p99": 50.282, "waited_ms_max": 82.48} +{"kind": "paced", "who": "pure", "rtt_ms": 20, "loss": 5, "jitter_ms": 0, "seconds": 20, "round": 2, "mbit": 0.41, "waited_ms_p50": 10.038, "waited_ms_p99": 70.127, "waited_ms_max": 93.141, "resent": 56, "lost": 54, "late": 0, "undone": 0, "packets": 1055} +{"kind": "paced", "who": "quinn", "rtt_ms": 20, "loss": 5, "jitter_ms": 0, "seconds": 20, "round": 2, "mbit": 0.41, "waited_ms_p50": 10.065, "waited_ms_p99": 95.533, "waited_ms_max": 136.894} +{"kind": "share", "who": "pure", "rtt_ms": 20, "loss": 0, "jitter_ms": 1, "seconds": 60, "round": 2, "mbit": 22.53, "tcp_mbit": 24.08, "share": 0.483} +{"kind": "share", "who": "quinn", "rtt_ms": 20, "loss": 0, "jitter_ms": 1, "seconds": 60, "round": 2, "mbit": 2.65, "tcp_mbit": 45.07, "share": 0.056} +{"kind": "share", "who": "tcp", "rtt_ms": 20, "loss": 0, "jitter_ms": 1, "seconds": 60, "round": 2, "mbit": 24.33, "tcp_mbit": 23.49, "share": 0.509} +{"kind": "bulk", "who": "pure", "rtt_ms": 100, "loss": 0, "jitter_ms": 0, "seconds": 20, "round": 2, "mbit": 44.86, "resent": 0, "lost": 0, "late": 0, "undone": 0, "packets": 108043} +{"kind": "bulk", "who": "quinn", "rtt_ms": 100, "loss": 0, "jitter_ms": 0, "seconds": 20, "round": 2, "mbit": 47.27, "waited_ms_p50": 0.0, "waited_ms_p99": 0.0, "waited_ms_max": 0.0} +{"kind": "bulk", "who": "pure", "rtt_ms": 100, "loss": 0, "jitter_ms": 3, "seconds": 20, "round": 2, "mbit": 45.24, "resent": 31, "lost": 17, "late": 17, "undone": 10, "packets": 86095} +{"kind": "bulk", "who": "quinn", "rtt_ms": 100, "loss": 0, "jitter_ms": 3, "seconds": 20, "round": 2, "mbit": 1.17, "waited_ms_p50": 0.0, "waited_ms_p99": 0.0, "waited_ms_max": 0.0} +{"kind": "bulk", "who": "pure", "rtt_ms": 100, "loss": 1, "jitter_ms": 0, "seconds": 20, "round": 2, "mbit": 1.6, "resent": 70, "lost": 35, "late": 0, "undone": 0, "packets": 3670} +{"kind": "bulk", "who": "quinn", "rtt_ms": 100, "loss": 1, "jitter_ms": 0, "seconds": 20, "round": 2, "mbit": 1.71, "waited_ms_p50": 0.0, "waited_ms_p99": 0.0, "waited_ms_max": 0.0} +{"kind": "bulk", "who": "pure", "rtt_ms": 100, "loss": 1, "jitter_ms": 3, "seconds": 20, "round": 2, "mbit": 1.45, "resent": 86, "lost": 43, "late": 6, "undone": 3, "packets": 3251} +{"kind": "bulk", "who": "quinn", "rtt_ms": 100, "loss": 1, "jitter_ms": 3, "seconds": 20, "round": 2, "mbit": 0.82, "waited_ms_p50": 0.0, "waited_ms_p99": 0.0, "waited_ms_max": 0.0} +{"kind": "bulk", "who": "pure", "rtt_ms": 100, "loss": 5, "jitter_ms": 0, "seconds": 20, "round": 2, "mbit": 0.56, "resent": 156, "lost": 69, "late": 0, "undone": 0, "packets": 1272} +{"kind": "bulk", "who": "quinn", "rtt_ms": 100, "loss": 5, "jitter_ms": 0, "seconds": 20, "round": 2, "mbit": 0.62, "waited_ms_p50": 0.0, "waited_ms_p99": 0.0, "waited_ms_max": 0.0} +{"kind": "bulk", "who": "pure", "rtt_ms": 100, "loss": 5, "jitter_ms": 3, "seconds": 20, "round": 2, "mbit": 0.63, "resent": 179, "lost": 89, "late": 9, "undone": 3, "packets": 1442} +{"kind": "bulk", "who": "quinn", "rtt_ms": 100, "loss": 5, "jitter_ms": 3, "seconds": 20, "round": 2, "mbit": 0.5, "waited_ms_p50": 0.0, "waited_ms_p99": 0.0, "waited_ms_max": 0.0} +{"kind": "paced", "who": "pure", "rtt_ms": 100, "loss": 0, "jitter_ms": 0, "seconds": 20, "round": 2, "mbit": 0.41, "waited_ms_p50": 50.039, "waited_ms_p99": 50.113, "waited_ms_max": 50.414, "resent": 0, "lost": 0, "late": 0, "undone": 0, "packets": 1001} +{"kind": "paced", "who": "quinn", "rtt_ms": 100, "loss": 0, "jitter_ms": 0, "seconds": 20, "round": 2, "mbit": 0.41, "waited_ms_p50": 50.054, "waited_ms_p99": 50.178, "waited_ms_max": 50.26} +{"kind": "paced", "who": "pure", "rtt_ms": 100, "loss": 1, "jitter_ms": 0, "seconds": 20, "round": 2, "mbit": 0.41, "waited_ms_p50": 50.035, "waited_ms_p99": 170.071, "waited_ms_max": 190.107, "resent": 9, "lost": 9, "late": 0, "undone": 0, "packets": 1009} +{"kind": "paced", "who": "quinn", "rtt_ms": 100, "loss": 1, "jitter_ms": 0, "seconds": 20, "round": 2, "mbit": 0.41, "waited_ms_p50": 50.088, "waited_ms_p99": 389.311, "waited_ms_max": 508.039} +{"kind": "paced", "who": "pure", "rtt_ms": 100, "loss": 5, "jitter_ms": 0, "seconds": 20, "round": 2, "mbit": 0.4, "waited_ms_p50": 90.061, "waited_ms_p99": 610.258, "waited_ms_max": 690.166, "resent": 77, "lost": 48, "late": 0, "undone": 0, "packets": 946} +{"kind": "paced", "who": "quinn", "rtt_ms": 100, "loss": 5, "jitter_ms": 0, "seconds": 20, "round": 2, "mbit": 0.41, "waited_ms_p50": 110.498, "waited_ms_p99": 506.435, "waited_ms_max": 586.416} +{"kind": "share", "who": "pure", "rtt_ms": 100, "loss": 0, "jitter_ms": 1, "seconds": 60, "round": 2, "mbit": 25.52, "tcp_mbit": 20.93, "share": 0.549} +{"kind": "share", "who": "quinn", "rtt_ms": 100, "loss": 0, "jitter_ms": 1, "seconds": 60, "round": 2, "mbit": 0.88, "tcp_mbit": 46.92, "share": 0.018} +{"kind": "share", "who": "tcp", "rtt_ms": 100, "loss": 0, "jitter_ms": 1, "seconds": 60, "round": 2, "mbit": 23.04, "tcp_mbit": 24.78, "share": 0.482} -- cgit v1.2.3