# quic **Repository Path**: dnsoa/quic ## Basic Information - **Project Name**: quic - **Description**: No description available - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-04-05 - **Last Updated**: 2026-04-05 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # quic Pure Go QUIC (RFC 9000) + HTTP/3 implementation, CDN-ready. ## 状态 | 能力 | 状态 | |------|------| | TLS 1.3 握手 | ✅ X25519, RSA/ECDSA, 证书链验证 | | 双向 Stream | ✅ 读写、FIN、deadline | | 包加密/解密 | ✅ AES-128-GCM + Header Protection | | PN 空间隔离 | ✅ Initial / Handshake / 1-RTT | | HTTP/3 帧 | ✅ DATA / HEADERS / SETTINGS / GOAWAY | | QPACK | ✅ 静态表 99 条目 + 动态表 + RIC 编码 | | 请求/响应 | ✅ pseudo-header, body via DATA frames | | 丢包重传 | ✅ RFC 9002 loss detection (SRTT/RTTVAR/PTO) | | 流控 | ✅ MAX_DATA / MAX_STREAM_DATA 收发 + 自动窗口更新 | | 拥塞控制 | ✅ NewReno (慢启动/拥塞避免/乘法减少) | | QPACK 动态表 | ✅ 容量管理 + 自动淘汰 | | Retry Token | ✅ HMAC-SHA256 源地址验证 | | 0-RTT | ✅ Session ticket + AES-GCM 加解密 | **测试:69 个通过 + 6 个 benchmark** ## 快速开始 ### 服务端 ```go package main import ( "context" "crypto/tls" "fmt" "io" "quic" ) func main() { cert, _ := quic.GenerateSelfSignedCert() listener, _ := quic.ListenAddr("0.0.0.0:4433", quic.Config{ MaxIncomingStreams: 1000, MaxIdleTimeout: 30 * time.Second, TLSConfig: &tls.Config{ Certificates: []tls.Certificate{cert}, NextProtos: []string{"h3"}, }, }) defer listener.Close() for { conn, _ := listener.Accept(context.Background()) go handleConn(conn) } } func handleConn(conn quic.Connection) { defer conn.Close() for { stream, err := conn.AcceptStream(context.Background()) if err != nil { return } go func(s quic.Stream) { defer s.Close() buf := make([]byte, 4096) n, _ := s.Read(buf) s.Write([]byte("echo: " + string(buf[:n]))) }(stream) } } ``` ### 客户端 ```go conn, _ := quic.DialAddr(context.Background(), "127.0.0.1:4433", quic.Config{ MaxIdleTimeout: 30 * time.Second, TLSConfig: &tls.Config{ InsecureSkipVerify: true, ServerName: "localhost", }, Alpn: "h3", }) defer conn.Close() stream, _ := conn.OpenStream() stream.Write([]byte("hello")) buf := make([]byte, 4096) n, _ := stream.Read(buf) fmt.Println(string(buf[:n])) ``` ### HTTP/3 ```go import "quic/http3" // 服务端 server := &http3.Server{ Addr: ":4433", TLSConfig: tlsConfig, Handler: http.DefaultServeMux, } server.ListenAndServe() // 客户端 client := &http3.Client{TLSConfig: tlsConfig} resp, _ := client.Do(req) ``` ## CDN 集成指南 ### 架构概览 ``` ┌─────────┐ ┌──────────────────┐ ┌──────────────┐ │ Client │────▶│ QUIC Terminator │────▶│ Origin Pool │ │ (HTTP/3)│ │ (Edge / CDN) │ │ (HTTP/1.1+) │ └─────────┘ └──────────────────┘ └──────────────┘ ``` CDN 节点作为 QUIC terminator,接收客户端 HTTP/3 请求,转发到后端源站。 ### 1. 边缘节点配置 ```go // 边缘节点 QUIC 监听 listener, _ := quic.ListenAddr("0.0.0.0:443", quic.Config{ MaxIncomingStreams: 10000, // CDN 大并发 MaxIdleTimeout: 30 * time.Second, TLSConfig: &tls.Config{ Certificates: []tls.Certificate{loadCDNCert()}, NextProtos: []string{"h3"}, }, }) ``` ### 2. 流控调优 ```go quic.Config{ // 连接级流控: 大文件需要更大的窗口 // 默认 4MB,CDN 大文件场景建议调大 // 实际通过 transport params 协商 } ``` 流控自动管理: - 收到数据时,50% 窗口消耗自动发送 `MAX_DATA` / `MAX_STREAM_DATA` 更新 - 发送侧检查 `CanSend()`,超限返回 `ErrFlowControl` ### 3. 拥塞控制 内置 NewReno,自动适配网络条件: - **慢启动**:cwnd 指数增长,快速探测带宽 - **拥塞避免**:cwnd 线性增长,稳定利用带宽 - **乘法减少**:检测到丢包,cwnd 减半 ```go // 可通过 CongestionController 自定义 cc := quic.NewCongestionController() cwnd := cc.Cwnd() // 当前窗口 bif := cc.BytesInFlight() // 在飞字节 state := cc.State() // SlowStart / CongestionAvoidance / Recovery ``` ### 4. 丢包重传 自动处理,无需手动干预: - RTT 估算 → 计算 PTO (Probe Timeout) - 超时检测 → 自动重传丢失包 - 指数退避 → 避免网络风暴 ```go // LossDetector 状态可监控 ld := quic.NewLossDetector() rtt := ld.RTT() // 平滑 RTT inFlight := ld.InFlightCount() // 在飞包数 ``` ### 5. Retry Token (防放大攻击) CDN 必须开启,防止 DDoS 反射放大: ```go tg, _ := quic.NewTokenGenerator() // 收到 Initial 包时,先验证 token // 无 token → 发 Retry 包 // 有 token → 验证通过才处理 retryPacket := quic.EncodeRetryPacket( newCID, // 新的 server CID origDestCID, // 客户端原始 dest CID token, // HMAC 签名的 token ) ``` ### 6. 0-RTT (减少重连延迟) CDN 场景大量客户端复连,0-RTT 显著降低延迟: ```go // 服务端: 生成 session ticket ticket, _ := quic.GenerateSessionTicket() // 客户端: 保存 session store := quic.NewSessionStore() store.Save("cdn.example.com:443", ticket) // 客户端: 使用 0-RTT 发送早期数据 ciphertext, _ := quic.Encrypt0RTT( payload, ticket.Client0RTTKey, ticket.Client0RTTIV, packetNumber, ) ``` ### 7. QPACK 动态表 CDN 大量重复 header(Host, User-Agent, Accept 等),动态表显著压缩带宽: ```go enc := http3.NewQPACKEncoder(4096) // 4KB 动态表 dec := http3.NewQPACKDecoder(4096) // 第一次请求: 编码并插入动态表 encoded := enc.EncodeFieldSection(headers) // 后续相同 header: 引用动态表索引 (更短) encoded2 := enc.EncodeFieldSection(repeatedHeaders) // len(encoded2) << len(encoded) ← 带宽节省 ``` ### 8. 监控指标 建议采集的关键指标: ```go // 连接级 conn.LocalAddr() conn.RemoteAddr() // 传输级 lossDetector.RTT() // P50/P99 RTT lossDetector.InFlightCount() // 在飞包数 congestion.Cwnd() // 拥塞窗口 congestion.BytesInFlight() // 在飞字节 congestion.State() // 拥塞状态 flowControl.SendWindowRemaining() // 发送窗口余量 // 应用级 stream.StreamID() stream.SetReadDeadline() stream.SetWriteDeadline() ``` ## 测试 ```bash # 运行全部测试 go test ./... -v # 运行 benchmark go test -bench=. -benchmem # 只跑某个包 go test ./http3/ -v ``` ### Benchmark (Intel Xeon 6982P-C) ``` BenchmarkProtectPacket 1381 ns/op 377 MB/s 21 allocs BenchmarkUnprotectPacket 1191 ns/op 451 MB/s 19 allocs BenchmarkEncodeFrames 3002 ns/op 12904 B/op 40 allocs BenchmarkDecodeFrames 489 ns/op 1065 MB/s 6 allocs BenchmarkVarintAppend 10.9 ns/op 0 allocs BenchmarkLossDetectorOnAck 25.0 μs/op (100 packets) ``` ## 项目结构 ``` quic/ ├── api.go # 公共 API (Listener, Connection, Stream 接口) ├── cid.go # Connection ID ├── client.go # 客户端 Dial + 握手 ├── conn.go # 连接管理、收发包、帧分发、ACK 生成 ├── congestion.go # 拥塞控制 (NewReno) ├── flow_control.go # 流控 (MAX_DATA / MAX_STREAM_DATA) ├── frame.go # 帧编解码 ├── keys.go # 密钥派生 (HKDF) ├── listener.go # 服务端监听 + 握手 ├── loss.go # 丢包检测 (RFC 9002) ├── packet.go # 包头编解码 ├── protect.go # 包加密/解密 + Header Protection ├── retry.go # Retry Token + Retry 包 ├── stream.go # Stream 实现 ├── tls13.go # TLS 1.3 握手状态机 ├── varint.go # QUIC varint 编码 ├── zerortt.go # 0-RTT 早期数据 ├── http3/ │ ├── conn.go # HTTP/3 连接封装 │ ├── dynamic_table.go # QPACK 动态表 │ ├── frame.go # HTTP/3 帧 + Settings │ ├── qpack.go # QPACK 编码器/解码器 │ ├── qpack_table.go # QPACK 静态表 (99 条目) │ ├── server.go # HTTP/3 Server + Client │ ├── stream.go # RequestStream + body 读写 │ ├── types.go # HTTP/3 帧类型、错误码 │ └── varint.go # HTTP/3 varint ├── p0_test.go # 丢包重传 + 流控 + 拥塞控制测试 (27) ├── p1_test.go # Retry + 0-RTT 测试 (19) ├── bench_test.go # Benchmark (6) ├── quic_test.go # 集成测试 (1) └── http3/ ├── http3_test.go # HTTP/3 测试 (6) └── dynamic_table_test.go # 动态表测试 (15) ``` ## 依赖 - Go 1.22+ - 仅标准库 (`crypto`, `net`, `sync`) - 零外部依赖 ## 协议合规 - [RFC 9000](https://www.rfc-editor.org/rfc/rfc9000) — QUIC: A UDP-Based Multiplexed and Secure Transport - [RFC 9001](https://www.rfc-editor.org/rfc/rfc9001) — Using TLS to Secure QUIC - [RFC 9002](https://www.rfc-editor.org/rfc/rfc9002) — QUIC Loss Detection and Congestion Control - [RFC 9114](https://www.rfc-editor.org/rfc/rfc9114) — HTTP/3 - [RFC 9204](https://www.rfc-editor.org/rfc/rfc9204) — QPACK: Field Compression for HTTP/3