aboutsummaryrefslogtreecommitdiffstats
path: root/docs/design
diff options
context:
space:
mode:
Diffstat (limited to 'docs/design')
-rw-r--r--docs/design/011-pure-transport.md27
-rw-r--r--docs/design/012-link-protocol.md24
2 files changed, 33 insertions, 18 deletions
diff --git a/docs/design/011-pure-transport.md b/docs/design/011-pure-transport.md
index 5513476..392210c 100644
--- a/docs/design/011-pure-transport.md
+++ b/docs/design/011-pure-transport.md
@@ -56,18 +56,25 @@ M3(저장소 옮기기, H3)는 [100](../research/100-moved-receiver.md)에 있�
- 잃음·겹침 검사, 논스 검사, 보안 검사를 모두 통과한다.
- 전달당 CPU는 1 KiB 이상에서 두 QUIC보다 25 % 넘게 가볍다. 61 B에서는 ngtcp2의 1.04배로 10 % 안이다.
- TCP와의 몫은 ±25 % 안이다.
-- 전송 코드는 C 3,097줄이다.
+- 전송 코드는 C 3,146줄이다.
그래서 연결 없는 링크를 노드 사이 전달의 기본으로 삼는다(`--send OUTPUT=pure://host:port/INPUT`). HTTP 전달은 제3자와
-브라우저를 잇는 경계로 남고, 중계를 지나는 봉인한 전달([088](../research/088-sealed-sessions.md))도 그대로다. M6를 ngtcp2와
-재지는 않았다. 가드레일은 quinn과 TCP로 쟀다.
-
-명세 [012](012-link-protocol.md)를 쓰면서 구현의 구멍 셋을 찾아 고쳤다.
-- 받는 쪽이 받지 않는 스트림을 보내는 쪽은 아무 말도 듣지 못해 매초 다시 보냈다. 이제 REFUSED로 이유를 듣고 드물게 다시 시도한다.
-- 받는 쪽이 쥘 수 없는 16–64 MiB 기록이 영원히 다시 갔다.
-- 한 노드의 출력 셋 이상이 같은 노드로 가면 run들이 받는 쪽의 두 자리를 서로 밀어냈다.
-
-명세만 보고 파이썬으로 따로 쓴 받는 쪽이 `pure-serve` 노드와 에폭 바꿈까지 맞붙는다.
+브라우저를 잇는 경계로 남고, 중계를 지나는 봉인한 전달([088](../research/088-sealed-sessions.md))도 그대로다.
+
+채택과 함께 한 일은 [102](../research/102-adoption-and-spec.md)에 있다.
+- 명세 [012](012-link-protocol.md)를 쓰면서 구현의 구멍 넷을 찾아 고쳤다.
+ - 받는 쪽이 받지 않는 스트림을 보내는 쪽은 아무 말도 듣지 못해, 90초에 패킷 2만 2천여 개를 다시 보냈다. 이제 REFUSED로
+ 이유를 듣고 드물게 다시 시도한다(같은 90초에 9개).
+ - 받는 쪽이 쥘 수 없는 16–64 MiB 기록이 영원히 다시 갔다.
+ - 한 노드의 출력 셋 이상이 같은 노드로 가면 run들이 받는 쪽의 두 자리를 서로 밀어냈다.
+ - 메모가 피어마다 run 하나의 에폭만 들어, 다시 뜬 받는 쪽이 나머지 run에 LOST를 보냈다.
+- 명세만 보고 파이썬으로 따로 쓴 받는 쪽이 `pure-serve` 노드와 에폭 바꿈까지 맞붙는다.
+- 허가가 기록 1,024건으로 고정되어, 100 ms 경로에서 61 B 기록은 초당 1만 건이 끝이었다. 이제 받는 쪽 메모리에 맞추어 5만
+ 6천 건이다.
+- M6를 ngtcp2와도 쟀다.
+ - 재정렬만 있을 때 Pure가 가장 많이 나르고, 손실만 있을 때 셋이 같다.
+ - 깨끗한 병목에서는 틀의 바이트로 3–5 % 뒤진다.
+ - 손실과 재정렬이 겹칠 때 ngtcp2가 1.3–3.6배 나르는 것은, 잘못 본 손실을 되돌리며 진짜 손실의 감소까지 지우기 때문이다.
2026-09-29에 링크를 `link/`로 뗐다([009](009-layout.md)). 프로토콜은 이제 소켓, 스레드, 시계가 없는 상태이고
(`link/link-protocol.h`), UDP와 스레드는 그 위의 층이다. 그래서 한 스레드가 링크 여럿을 들 수 있다. M2를 이 보내는 쪽으로
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로 맞췄다.