QUIC transport for MoonBit.
// A protected packet, from the connection ID up (RFC 9001 §5.2–§5.4).
let (_, server) = @crypto.initial(dcid[:])
let number = @packet.number(1L, None)
let header = long.header(number[:], payload=payload.length() + 16)
let wire = server.seal(header[:], payload[:], number=1L)
// And back, with the packet number recovered against what this space has seen.
let (plain, n) = server.open(wire[:], largest=0L).unwrap()
let frames = @packet.read_payload(plain)moon run src/examples/02-frames moon run src/examples/05-ack moon run src/examples/08-streams
moon run src/examples/03-params moon run src/examples/06-flow moon run src/examples/09-sender
moon run src/examples/04-crypto moon run src/examples/07-recovery| Specification | State | |
|---|---|---|
| frame | §19 every frame type, and §19.3.1 the ACK range encoding both ways | 0.1.0 |
| packet | §17 long and short headers, Retry, Version Negotiation, §17.1 packet numbers, §12.3 the three spaces | 0.1.0 |
| crypto | §5 packet protection, header protection and the Retry tag, §6 key update | 0.1.0 |
| recovery | RFC 9002 the round-trip estimate, both loss thresholds, the probe timeout, and NewReno, CUBIC (RFC 9438) and BBR behind one controller trait, with persistent congestion | 0.1.0 |
| stream | §2 stream IDs and reassembly, §3 both state machines, §4 data flow control and the stream quota, and a round-robin scheduler | 0.1.0 |
| conn | §18 transport parameters, §12.3 the three spaces and their CRYPTO streams, the client and server handshakes, the connection table and event loop with its timers and amplification limit (§8.1, §10, §14.1), §9 migration and path validation, §10.3 stateless reset, RFC 9221 datagrams, and 0-RTT packets | 0.1.0 |
let server : @conn.Endpoint[Addr] = @conn.Endpoint::server(
@conn.Config::default(),
@tls.Server::new(chain, key, alpn=["h3"]),
rand=entropy,
)
server.recv(datagram, from, now)
for conn in server.take_busy() {
for event in conn.take_events() {
match event {
Readable(id) => {
let bytes = conn.read(id)
conn.write(id, reply(bytes), fin=conn.finished(id))
}
_ => ()
}
}
}
while server.poll_out(now) is Some((datagram, to)) {
send(datagram, to)
}let client = @conn.Client::new(
@tls.Client::new(roots, alpn=["h3"]),
"a.example",
@conn.encode(params),
rand=entropy,
dcid=Bytes::make(8, 1),
scid=Bytes::make(8, 2),
now,
)
for datagram in client.poll_out(now) { send(datagram, to) }
for datagram in receive() {
client.recv(datagram, now)
for answer in client.poll_out(now) { send(answer, to) }
}let queued = client.send_zero_rtt([
@frame.Stream(id=0UL, offset=0UL, fin=false, data=request),
])let cfg = { ..@conn.Config::default(), max_datagram_frame_size: 1200UL }
let taken = conn.send_datagram(payload)
for datagram in conn.take_datagrams() { handle(datagram) }@crypto.initial(dcid[:]) // AEAD_AES_128_GCM, RFC 9001 §5.2
@crypto.Keys::of(secret[:], suite=@crypto.aes256) // AEAD_AES_256_GCM
@crypto.Keys::of(secret[:], suite=@crypto.chacha20) // AEAD_CHACHA20_POLY1305@recovery.State::new() // NewReno
@recovery.State::new(control=@recovery.Cubic::new()) // CUBIC, RFC 9438
@recovery.State::new(control=@recovery.Bbr::new()) // BBRInstall
Download zipQUIC transport for MoonBit.