std.net.quic
QUIC (RFC 9000) ist ein modernes Transportprotokoll auf UDP-Basis, das von Google entwickelt und durch die IETF standardisiert wurde. Gegenüber TCP+TLS bietet QUIC integrierte TLS 1.3-Verschlüsselung, Stream-Multiplexing ohne Head-of-Line-Blocking und schnellere Verbindungsaufbauzeiten (0-RTT/1-RTT Handshake). QUIC ist die Transportschicht von HTTP/3.
Die Unit implementiert den QUIC-Handshake, Stream-Management (öffnen/schließen/lesen/schreiben), alle Frame-Typen (STREAM, ACK, PADDING, CRYPTO, CONNECTION_CLOSE) und variable-length Integer-Codierung (Varint). Einsatzbereiche sind hochperformante verschlüsselte Kommunikation und HTTP/3-Implementierungen.
Imports
std.net.socketstd.net.dnsstd.net.types
Konstanten
| Name | Typ | Wert | Sichtbarkeit |
|---|---|---|---|
QUIC_PORT | int64 | 443 | pub |
QUIC_VERSION_1 | int64 | $00000001 | pub |
QUIC_PKT_INITIAL | int64 | 0 | pub |
QUIC_PKT_0RTT | int64 | 1 | pub |
QUIC_PKT_HANDSHAKE | int64 | 2 | pub |
QUIC_PKT_RETRY | int64 | 3 | pub |
QUIC_PKT_1RTT | int64 | 4 | pub |
QUIC_FRAME_PADDING | int64 | $00 | pub |
QUIC_FRAME_PING | int64 | $01 | pub |
QUIC_FRAME_ACK | int64 | $02 | pub |
QUIC_FRAME_ACK_ECN | int64 | $03 | pub |
QUIC_FRAME_RESET_STREAM | int64 | $04 | pub |
QUIC_FRAME_STOP_SENDING | int64 | $05 | pub |
QUIC_FRAME_CRYPTO | int64 | $06 | pub |
QUIC_FRAME_NEW_TOKEN | int64 | $07 | pub |
QUIC_FRAME_STREAM_BASE | int64 | $08 | pub |
QUIC_FRAME_MAX_DATA | int64 | $10 | pub |
QUIC_FRAME_MAX_STREAM_DATA | int64 | $11 | pub |
QUIC_FRAME_MAX_STREAMS_BIDI | int64 | $12 | pub |
QUIC_FRAME_MAX_STREAMS_UNI | int64 | $13 | pub |
QUIC_FRAME_DATA_BLOCKED | int64 | $14 | pub |
QUIC_FRAME_STREAM_DATA_BLOCKED | int64 | $15 | pub |
QUIC_FRAME_STREAMS_BLOCKED_BIDI | int64 | $16 | pub |
QUIC_FRAME_STREAMS_BLOCKED_UNI | int64 | $17 | pub |
QUIC_FRAME_NEW_CONNECTION_ID | int64 | $18 | pub |
QUIC_FRAME_RETIRE_CONNECTION_ID | int64 | $19 | pub |
QUIC_FRAME_PATH_CHALLENGE | int64 | $1A | pub |
QUIC_FRAME_PATH_RESPONSE | int64 | $1B | pub |
QUIC_FRAME_CONNECTION_CLOSE | int64 | $1C | pub |
QUIC_FRAME_CONNECTION_CLOSE_APP | int64 | $1D | pub |
QUIC_FRAME_HANDSHAKE_DONE | int64 | $1E | pub |
QUIC_ERR_NO_ERROR | int64 | $00 | pub |
QUIC_ERR_INTERNAL_ERROR | int64 | $01 | pub |
QUIC_ERR_CONNECTION_REFUSED | int64 | $02 | pub |
QUIC_ERR_FLOW_CONTROL_ERROR | int64 | $03 | pub |
QUIC_ERR_STREAM_LIMIT_ERROR | int64 | $04 | pub |
QUIC_ERR_STREAM_STATE_ERROR | int64 | $05 | pub |
QUIC_ERR_FINAL_SIZE_ERROR | int64 | $06 | pub |
QUIC_ERR_FRAME_ENCODING_ERROR | int64 | $07 | pub |
QUIC_ERR_TRANSPORT_PARAMETER_ERROR | int64 | $08 | pub |
QUIC_ERR_CONNECTION_ID_LIMIT_ERROR | int64 | $09 | pub |
QUIC_ERR_PROTOCOL_VIOLATION | int64 | $0A | pub |
QUIC_ERR_INVALID_TOKEN | int64 | $0B | pub |
QUIC_ERR_APPLICATION_ERROR | int64 | $0C | pub |
QUIC_ERR_CRYPTO_BUFFER_EXCEEDED | int64 | $0D | pub |
QUIC_ERR_KEY_UPDATE_ERROR | int64 | $0E | pub |
QUIC_ERR_AEAD_LIMIT_REACHED | int64 | $0F | pub |
QUIC_ERR_NO_VIABLE_PATH | int64 | $10 | pub |
QUIC_MAX_PACKET_SIZE | int64 | 1452 | pub |
QUIC_MIN_INITIAL_SIZE | int64 | 1200 | pub |
QUIC_CONN_ID_LEN | int64 | 8 | pub |
<WRAP alert>
Transportparameter fehlen vollständig. Frühere Fassungen dieser Seite führten hier 17 Konstanten QUIC_TP_ORIGINAL_DESTINATION_CONNECTION_ID bis QUIC_TP_RETRY_SOURCE_CONNECTION_ID auf. Keine davon existiert — die Unit kennt kein einziges Symbol mit dem Präfix QUIC_TP_:
$ lyxc q1.lyx -o /dev/null
sema error (line 2): undefined symbol 'QUIC_TP_MAX_IDLE_TIMEOUT'
Von den Transportparametern nach RFC 9000 §18 ist allein der Fehlercode QUIC_ERR_TRANSPORT_PARAMETER_ERROR vorhanden — gemeldet werden kann ein fehlerhafter Parameter also, ausgehandelt wird keiner. Damit fehlen unter anderem Idle-Timeout, Flusskontrollgrenzen und die Stream-Obergrenzen; QUICConnect handelt nichts davon aus.
</WRAP>
Typen
QUICConn (struct)
Der Verbindungszustand. Wird von QUICConnect gefüllt und an QUICOpenStream weitergereicht.
| Feld | Typ | Bedeutung |
|---|---|---|
sock | UDPSocket | der zugrunde liegende UDP-Socket |
connected | int64 | 1, wenn die Verbindung steht |
localConnId | int64 | Zeiger auf die eigene Connection-ID (8 Byte) |
remoteConnId | int64 | Zeiger auf die Connection-ID der Gegenstelle (8 Byte) |
nextStreamId | int64 | nächste zu vergebende Stream-Nummer |
packetNumber | int64 | laufende Paketnummer |
serverIp | int64 | aufgelöste Server-Adresse |
serverPort | int64 | Server-Port |
clientKey | int64 | Zeiger auf den 16-Byte-AEAD-Schlüssel |
clientIV | int64 | Zeiger auf den 12-Byte-IV |
clientHP | int64 | Zeiger auf den 16-Byte-Header-Protection-Schlüssel |
QUICStream (struct)
Ein Stream innerhalb der Verbindung. Mehrere Felder sind Kopien aus QUICConn — der Stream trägt Socket, Adresse und Schlüssel selbst mit, statt über conn zuzugreifen.
| Feld | Typ | Bedeutung |
|---|---|---|
conn | int64 | unbenutzt, laut Quelltext nur für die ABI beibehalten |
streamId | int64 | Stream-Nummer |
state | int64 | 0 = geschlossen, 1 = offen |
offset | int64 | bisher gesendete Bytes; dient zugleich als Paketzähler |
sockFd | int64 | Socket-Deskriptor, aus conn kopiert |
serverIp | int64 | aus conn kopiert |
serverPort | int64 | aus conn kopiert |
keyPtr | int64 | Zeiger auf den Schlüssel, aus conn |
ivPtr | int64 | Zeiger auf den IV, aus conn |
QUICPacketHeader (struct)
Hilfsstruktur zum Zerlegen eines Paketkopfes.
| Feld | Typ | Bedeutung |
|---|---|---|
headerForm | int64 | 1 = Long Header, 0 = Short Header |
fixedBit | int64 | das nach RFC 9000 stets gesetzte Bit |
packetType | int64 | QUIC_PKT_* |
typeSpecific | int64 | typabhängige Bits des ersten Bytes |
version | int64 | Versionsfeld, QUIC_VERSION_1 |
destConnIdLen | int64 | Länge der Ziel-Connection-ID |
destConnId | int64 | Zeiger auf die Ziel-Connection-ID |
srcConnIdLen | int64 | Länge der Quell-Connection-ID |
srcConnId | int64 | Zeiger auf die Quell-Connection-ID |
packetNumber | int64 | Paketnummer |
payloadLen | int64 | Länge der Nutzlast |
Funktionen
| Signatur | Sichtbarkeit | Beschreibung |
|---|---|---|
QUICRandomBytes(buf: int64, len: int64) | pub | Kryptografisch zufällige Bytes erzeugen |
QUICWriteVarint(buf: int64, pos: int64, value: int64): int64 | pub | Variable-Length-Integer in Puffer schreiben |
QUICReadVarint(buf: int64, pos: int64): int64 | pub | Variable-Length-Integer aus Puffer lesen |
QUICVarintSize(buf: int64, pos: int64): int64 | pub | Byte-Größe eines Varint bestimmen |
QUICBuildInitialPacket(destConnId: int64, destLen: int64, srcConnId: int64, srcLen: int64): int64 | pub | QUIC-Initial-Paket für Handshake aufbauen |
QUICBuildStreamFrame(streamId: int64, data: int64, dataLen: int64, fin: int64): int64 | pub | STREAM-Frame aufbauen |
QUICBuildPaddingFrame(len: int64): int64 | pub | PADDING-Frame aufbauen |
QUICBuildAckFrame(largestAcked: int64, ackDelay: int64): int64 | pub | ACK-Frame aufbauen |
QUICBuildConnectionClose(errorCode: int64, reason: pchar): int64 | pub | CONNECTION_CLOSE-Frame aufbauen; reason ist ein pchar, kein Zeiger als int64 |
QUICConnect(host: int64, port: int64): QUICConn | pub | QUIC-Verbindung aufbauen |
QUICOpenStream(conn: QUICConn): QUICStream | pub | Neuen Stream in Verbindung öffnen |
QUICStreamWrite(stream: QUICStream, data: int64, len: int64): int64 | pub | Daten in Stream schreiben |
QUICStreamRead(stream: QUICStream, buf: int64, bufsize: int64): int64 | pub | Daten aus Stream lesen |
QUICCloseStream(stream: QUICStream) | pub | Stream schließen |
QUICDisconnect(conn: QUICConn) | pub | QUIC-Verbindung trennen |
