aboutsummaryrefslogtreecommitdiffstats
path: root/docs/design/012-link-protocol.md
diff options
context:
space:
mode:
authoreunhhu <[email protected]>2026-09-29 18:15:11 +0100
committereunhhu <[email protected]>2026-09-29 18:15:11 +0100
commitb09bda62059e11ee43ae6d1fd62bf31e2e4fbde6 (patch)
tree3efc11d95871bbc4445c083fe225587bd41ceeba /docs/design/012-link-protocol.md
parented118d278e4f088a0416f11db96951231cb6851e (diff)
downloadpure-b09bda62059e11ee43ae6d1fd62bf31e2e4fbde6.tar.gz
pure-b09bda62059e11ee43ae6d1fd62bf31e2e4fbde6.zip
Say what adopting the link took, and how it fares against ngtcp2 (102)
102: the spec (012) and a receiver written from it alone; the four holes writing it found (REFUSED, the record's size, a peer's run places, the memo's places beside) and the credit M6 showed fixed at 1,024 records; M6 with ngtcp2 as a third, two rounds. Under reordering Pure carries the most (45 Mbit/s; ngtcp2 29-47, quinn 1-2), under random loss the three are the same, on a clean bottleneck Pure carries 3-5 % less (its framing, some 112 B a packet to QUIC's 41), and where loss and reordering meet ngtcp2 carries 1.3-3.6 times as much: undoing a loss it took for reordering, it restores the window a real loss had cut too (its log: 22 of 34 undos past the window before the last cut; none without reordering). Shares beside TCP stay within 25 %. 011 and the status table say so; 012 also says that a receiver answers within 25 ms (a sender's PTO counts on it), that a shape and a record's bytes are the app's, and why a packet of the past does no harm.
Diffstat (limited to 'docs/design/012-link-protocol.md')
-rw-r--r--docs/design/012-link-protocol.md24
1 files changed, 16 insertions, 8 deletions
diff --git a/docs/design/012-link-protocol.md b/docs/design/012-link-protocol.md
index 1ad3739..558ff7f 100644
--- a/docs/design/012-link-protocol.md
+++ b/docs/design/012-link-protocol.md
@@ -18,8 +18,10 @@
- **보내는 쪽**: 한 노드의 출력 하나가 저장한 보내기를 다른 노드의 입력 하나로 보낸다. 시작할 때마다 **run**을 새로 뽑는다.
run은 0이 아닌 무작위 u64다.
- **받는 쪽**: 받아들일 보내는 쪽을 (source 이름, 공개 키) 목록으로 가진다.
-- **스트림**: source 이름과 input 이름의 쌍이다. 각 이름은 1–64 B다. 메시지의 shape(u32)가 함께 간다.
-- **기록**: 스트림 안에서 1부터 연속된 번호(u64)를 가진 바이트열이다. 0–16 MiB다.
+- **스트림**: source 이름과 input 이름의 쌍이다. 각 이름은 1–64 B다. 메시지의 shape(u32)가 함께 간다. 받는 쪽 입력의
+ shape와 같아야 한다. 링크에게 shape는 비교만 하는 값이고, 뜻은 모듈 형식([008](008-module-format.md))이 정한다.
+- **기록**: 스트림 안에서 1부터 연속된 번호(u64)를 가진 바이트열이다. 0–16 MiB다. 바이트는 보내는 앱이 저장한 그대로이고,
+ 링크는 읽지 않는다.
- **들은 번호**: 받는 쪽 앱이 적용하고 저장한 마지막 기록 번호다.
- **답**: 받는 쪽이 보내는 쪽의 run에 보내는 패킷이다.
@@ -197,8 +199,12 @@ STORED의 들은 번호 이하인 기록은 덜어 낸다. 보내는 앱은 그�
쌓인다(지역 선택). 그래서 꾸며 낸 패킷 폭주에 드는 HKDF에 상한이 있고, 열리는 보내는 쪽 천 개가 한꺼번에 깨어나도 토큰을
쓰지 않는다.
- run의 자리는 패킷이 열린 뒤에만 만든다. 위조한 패킷은 아무 자리도 밀어내지 못한다.
-- 이미 받은 패킷 번호(구간 32개까지 기억)의 패킷은 ACK만 다시 하고 프레임은 처리하지 않는다. 그보다 오래된 번호는 기록의
- 들은 번호와 STORED의 "가장 큰 값" 규칙이 막는다.
+- 이미 받은 패킷 번호(구간 32개까지 기억)의 패킷은 ACK만 다시 하고 프레임은 처리하지 않는다. 그보다 오래된 번호의 패킷은
+ 다시 처리해도 해가 없다.
+ - 기록은 들은 번호가 걸러 한 번만 적용된다.
+ - 지난 OFFER는 지금 에폭 다음이 아니라 받아들여지지 않는다.
+ - 지난 RESPONSE는 지금의 CHALLENGE와 맞지 않는다.
+ - 주소는 가장 큰 번호의 패킷만 옮긴다.
**주소.**
@@ -209,7 +215,7 @@ STORED의 들은 번호 이하인 기록은 덜어 낸다. 보내는 앱은 그�
**답.**
-- 확인을 부르는 패킷을 받은 뒤의 다음 차례에 답 패킷 하나에 다음을 넣는다.
+- 확인을 부르는 패킷을 받으면 25 ms 안에 답 패킷 하나에 다음을 넣어 보낸다. 보내는 쪽의 PTO가 이 상한을 기대한다.
- CHALLENGE(확인 전)
- ACCEPT(다음 에폭이 쓰이기 전)
- ACK: 가장 큰 번호를 받은 뒤 지난 시간과 구간들
@@ -284,7 +290,8 @@ LOST는 그 패킷의 번호를 담아 에폭 0의 키로 봉인한다. 답 run�
| 거절 뒤 기다림 | 1초부터 두 배, 64초까지 | 지역 선택 |
| 에폭을 잃었다고 볼 때 | 2초와 PTO 4번 | 지역 선택 |
| 받은 뒤 저장을 기다리는 시간 | 1초 | 지역 선택 |
-| RTT 첫값, ACK 지연 상한, PTO 상한 | 100 ms, 25 ms, 1초 | 지역 선택 |
+| ACK 지연 상한(받는 쪽이 지킨다) | 25 ms | 명세 |
+| RTT 첫값, PTO 상한 | 100 ms, 1초 | 지역 선택 |
| 혼잡 제어 | CUBIC(RFC 9438, C 0.4, β 0.7), 첫 창 10 데이터그램, 페이싱, 잘못 본 손실은 되돌림 | 지역 선택(표준 알고리즘만) |
| 재정렬 인내 | 패킷 3–256개, 시간 RTT/8부터 최소 RTT의 1/4씩 RTT까지 | 지역 선택 |
| 키 만들기 / 에폭 수락 / LOST | 초당 256 / 256(한꺼번에 8) / 4,096 | 지역 선택 |
@@ -326,8 +333,9 @@ LOST는 그 패킷의 번호를 담아 에폭 0의 키로 봉인한다. 답 run�
## 이 명세와 구현
- 구현은 `link/link-protocol.c`(상태, 소켓 없음)와 `link/link.c`(UDP, GSO/GRO, 스레드)다.
-- 전송 코드는 C 3,097줄이다(프로토콜 2,510, UDP 587). 011의 한도는 5,000줄이다.
-- 이 명세를 쓰면서 구현의 구멍 셋을 찾아 고쳤다. 셋 다 `link/test-link.c`에 검사가 있다.
+- 전송 코드는 C 3,146줄이다(프로토콜 2,559, UDP 587). 011의 한도는 5,000줄이다.
+- 이 명세를 쓰면서 구현의 구멍 셋을 찾아 고쳤다. 셋 다 `link/test-link.c`에 검사가 있다. 메모의 곁 자리와 허가의 크기까지
+ [102](../research/102-adoption-and-spec.md)에 있다.
- 받는 쪽이 스트림을 받지 않을 때 보내는 쪽이 아무 말도 듣지 못해 매초 기록을 다시 보냈다. REFUSED를 더했다.
- 보내는 쪽은 64 MiB까지의 기록을 받아 두었지만 받는 쪽은 16 MiB까지만 쥘 수 있었다. 그 사이 크기의 기록은 영원히 다시
갔다. 기록의 상한을 16 MiB로 맞췄다.