{"id":50128762,"url":"https://github.com/lxin/quic","last_synced_at":"2026-06-26T13:01:18.936Z","repository":{"id":172595333,"uuid":"649485122","full_name":"lxin/quic","owner":"lxin","description":"In-kernel QUIC implementation with Userspace handshake","archived":false,"fork":false,"pushed_at":"2026-06-18T22:10:52.000Z","size":3380,"stargazers_count":276,"open_issues_count":8,"forks_count":26,"subscribers_count":13,"default_branch":"main","last_synced_at":"2026-06-19T00:12:12.572Z","etag":null,"topics":["handshake","in-kernel","kquic","linux","posix","quic","socket"],"latest_commit_sha":null,"homepage":"","language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/lxin.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"COPYING","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2023-06-05T01:16:12.000Z","updated_at":"2026-06-18T22:10:57.000Z","dependencies_parsed_at":"2024-04-20T20:27:25.757Z","dependency_job_id":"06e891ee-9597-4ce7-83cb-10d0341fed86","html_url":"https://github.com/lxin/quic","commit_stats":null,"previous_names":["lxin/quic"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/lxin/quic","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lxin%2Fquic","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lxin%2Fquic/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lxin%2Fquic/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lxin%2Fquic/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/lxin","download_url":"https://codeload.github.com/lxin/quic/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lxin%2Fquic/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34817641,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-26T02:00:06.560Z","response_time":106,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["handshake","in-kernel","kquic","linux","posix","quic","socket"],"created_at":"2026-05-23T21:00:29.530Z","updated_at":"2026-06-26T13:01:18.930Z","avatar_url":"https://github.com/lxin.png","language":"C","funding_links":[],"categories":["C"],"sub_categories":[],"readme":"# QUIC in Linux Kernel\n\n## Introduction\n\nThe QUIC protocol, defined in RFC 9000, is a secure, multiplexed transport built on top of UDP. It\nenables low-latency connection establishment, stream-based communication with flow control, and\nsupports connection migration across network paths, while ensuring confidentiality, integrity, and\navailability.\n\nThis implementation introduces QUIC support in Linux Kernel, offering several key advantages:\n\n- **In-Kernel QUIC Support for Subsystems**: Enables kernel subsystems such as SMB and NFS to\noperate over QUIC with minimal changes. Once the handshake is complete via the net/handshake APIs,\ndata exchange proceeds over standard in-kernel transport interfaces.\n\n- **Standard Socket API Semantics**: Implements core socket operations (listen(), accept(),\nconnect(), sendmsg(), recvmsg(), close(), getsockopt(), setsockopt(), getsockname(), and\ngetpeername()), allowing user space to interact with QUIC sockets in a familiar, POSIX-compliant\nway.\n\n- **ALPN-Based Connection Dispatching**: Supports in-kernel ALPN (Application-Layer Protocol\nNegotiation) routing, allowing demultiplexing of QUIC connections across different user-space\nprocesses based on the ALPN identifiers.\n\n- **Performance Enhancements**: Handles all control messages in-kernel to reduce syscall overhead,\nincorporates zero-copy mechanisms such as sendfile() minimize data movement, and is also\nstructured to support future crypto hardware offloads.\n\n## Implementation\n\n### General Idea\n\nThe central design is to implement QUIC within the kernel while delegating the handshake to\nuserspace.\n\n- **What's in Userspace**: Only the processing and creation of raw TLS Handshake Messages are\nhandled in userspace, facilitated by a TLS library like GnuTLS. These messages are exchanged\nbetween kernel and userspace via sendmsg() and recvmsg(), with cryptographic details conveyed\nthrough control messages (cmsg). See: [libquic/](https://github.com/lxin/quic/tree/main/libquic).\n\n- **What's in Kernel**: The entire QUIC protocol, aside from the TLS Handshake Messages processing\nand creation, is managed within the kernel. Rather than using a Upper Layer Protocol (ULP) layer,\nthis implementation establishes a socket of type IPPROTO_QUIC (similar to IPPROTO_MPTCP), operating\nover UDP tunnels. See: [modules/net/quic/](https://github.com/lxin/quic/tree/main/modules/net/quic).\n\n- **How Kernel Consumers Use It**: Kernel consumers can initiate a handshake request from the kernel\nto userspace using the existing\n[net/handshake netlink](https://docs.kernel.org/networking/tls-handshake.html). The userspace\ncomponent, such as tlshd service in [ktls-utils](https://github.com/oracle/ktls-utils), then manages\nthe processing of the QUIC handshake request.\n\n### Infrastructures\n\n- Handshake Architecture:\n\n      +------+  +------+\n      | APP1 |  | APP2 | ...\n      +------+  +------+\n      +------------------------------------------+\n      |     {quic_client/server_handshake()}     |\n      +------------------------------------------+       +-------------+\n       {send/recvmsg()}      {set/getsockopt()}          |    tlshd    |\n       [CMSG handshake_info] [SOCKOPT_CRYPTO_SECRET]     +-------------+\n                             [SOCKOPT_TRANSPORT_PARAM_EXT]    |   ^\n                    | ^                  | ^                  |   |\n      Userspace     | |                  | |                  |   |\n      --------------|-|------------------|-|------------------|---|-------\n      Kernel        | |                  | |                  |   |\n                    v |                  v |                  v   |\n      +------------------+-----------------------+       +-------------+\n      | protocol, timer, | socket (IPPROTO_QUIC) |\u003c--+   | handshake   |\n      |                  +-----------------------+   |   |netlink APIs |\n      | common, family,  | outqueue  |  inqueue  |   |   +-------------+\n      |                  +-----------------------+   |      |       |\n      | stream, connid,  |         frame         |   |   +-----+ +-----+\n      |                  +-----------------------+   |   |     | |     |\n      | path, pnspace,   |         packet        |   |---| SMB | | NFS |...\n      |                  +-----------------------+   |   |     | |     |\n      | cong, crypto     |       UDP tunnels     |   |   +--+--+ +--+--+\n      +------------------+-----------------------+   +------+-------|\n\n- Application Data Architecture:\n\n      +------+  +------+\n      | APP1 |  | APP2 | ...\n      +------+  +------+\n       {send/recvmsg()}   {set/getsockopt()}              {recvmsg()}\n       [CMSG stream_info] [SOCKOPT_KEY_UPDATE]            [EVENT conn update]\n                          [SOCKOPT_CONNECTION_MIGRATION]  [EVENT stream update]\n                          [SOCKOPT_STREAM_OPEN/RESET/STOP]\n                    | ^               | ^                     ^\n      Userspace     | |               | |                     |\n      --------------|-|---------------|-|---------------------|-----------\n      Kernel        | |               | |                     |\n                    v |               v |  |------------------+\n      +------------------+-----------------------+\n      | protocol, timer, | socket (IPPROTO_QUIC) |\u003c--+{kernel_send/recvmsg()}\n      |                  +-----------------------+   |{kernel_set/getsockopt()}\n      | common, family,  | outqueue  |  inqueue  |   |{kernel_recvmsg()}\n      |                  +-----------------------+   |\n      | stream, connid,  |         frame         |   |   +-----+ +-----+\n      |                  +-----------------------+   |   |     | |     |\n      | path, pnspace,   |         packet        |   |---| SMB | | NFS |...\n      |                  +-----------------------+   |   |     | |     |\n      | cong, crypto     |       UDP tunnels     |   |   +--+--+ +--+--+\n      +------------------+-----------------------+   +------+-------|\n\n### Features\nThis implementation offers fundamental support for the following RFCs:\n\n- RFC9000 - QUIC: A UDP-Based Multiplexed and Secure Transport\n- RFC9001 - Using TLS to Secure QUIC\n- RFC9002 - QUIC Loss Detection and Congestion Control\n- RFC9221 - An Unreliable Datagram Extension to QUIC\n- RFC9287 - Greasing the QUIC Bit\n- RFC9368 - Compatible Version Negotiation for QUIC\n- RFC9369 - QUIC Version 2\n\nThe socket APIs for QUIC follow the RFC draft:\n\n- The Sockets API Extensions for In-kernel QUIC Implementations\n\n### Next Step\n- Submit QUIC module to upstream kernel.\n- Submit quic_handshake() in libquic to gnutls library.\n- Implement HW crypto offloading infrastructure.\n\n## INSTALL\n\nBoth QUIC Kernel Module and Libquic will be built and installed simply by the commands below:\n\n    Packages Required: (kernel_version \u003e= 6.1)\n    - make autoconf automake libtool pkg-config\n    - gnutls-devel kernel-devel (yum)\n      gnutls-dev linux-headers-$(uname -r) (apt-get)\n\n    # cd /home/lxin (my home directory)\n    # git clone https://github.com/lxin/quic.git\n    # cd quic/\n    # ./autogen.sh\n    # ./configure --prefix=/usr\n    # make\n    # sudo make install\n    # sudo make check (optional, run selftests)\n\nNOTE: For these who want to integrate QUIC modules into kernel source code (e.g.\n/home/lxin/net-next/), follow the instruction below to build and install kernel first, then the\ncommands above will skip QUIC modules building and use the one provided by kernel.\n\n    # cp -r modules/include modules/net /home/lxin/net-next\n    # cd /home/lxin/net-next/\n    # sed -i 's@.*sctp.*@\u0026\\nobj-$(CONFIG_IP_QUIC)\\t\\t+= quic/@' net/Makefile\n    # sed -i 's@.*sctp.*@\u0026\\nsource \"net/quic/Kconfig\"@' net/Kconfig\n\n    Then build kernel with:\n\n    CONFIG_IP_QUIC=m\n    CONFIG_IP_QUIC_TEST=m\n\nAlso libquic is not necessary if you're able to use raw socket APIs and gnutls APIs to complete\nthe QUIC handshake, see\n[Raw Socket APIs with more Control](https://github.com/lxin/quic#raw-socket-apis-with-more-control).\n\n## USE CASES\n\n### Kernel Consumers with ktls-utils:\n    Packages Required:\n    - keyutils\n    - glib2-devel libnl3-devel keyutils-libs-devel (yum)\n      libglib2.0-dev libnl-genl-3-dev libkeyutils-dev (apt-get)\n\n    # cd /home/lxin\n    # git clone https://github.com/oracle/ktls-utils\n    # cd ktls-utils/\n    # ./autogen.sh\n    # ./configure --with-systemd --sysconfdir=/etc\n    # make\n    # sudo make install\n\n    # sudo vim /etc/tlshd/config\n      [debug]\n      loglevel=0\n      tls=0\n      nl=0\n\n      [authenticate]\n      keyrings=quic\n\n      [authenticate.client]\n      x509.truststore= /home/lxin/quic/tests/keys/ca-cert.pem\n      x509.certificate=/home/lxin/quic/tests/keys/client-cert.pem\n      x509.private_key=/home/lxin/quic/tests/keys/client-key.pem\n\n      [authenticate.server]\n      x509.truststore= /home/lxin/quic/tests/keys/ca-cert.pem\n      x509.certificate=/home/lxin/quic/tests/keys/server-cert.pem\n      x509.private_key=/home/lxin/quic/tests/keys/server-key.pem\n\n    # sudo systemctl enable --now tlshd\n\n    # cd /home/lxin/quic\n    # sudo make check tests=tlshd (optional, run some tests for tlshd)\n\nAfter tlshd service is started, Kernel Consumers can use these user APIs from kernel space,\nsee [Use in Kernel Space](https://github.com/lxin/quic/#use-in-kernel-space).\n\n### HTTP/3 Client with Curl:\n    # cd /home/lxin\n    # git clone --recurse-submodules https://github.com/ngtcp2/nghttp3.git\n    # cd nghttp3\n    # autoreconf -i\n    # ./configure --prefix=/usr/\n    # make\n    # sudo make install\n\n    # cd /home/lxin/quic\n    # sudo make check tests=http3 (optional, run some tests for http3)\n\nMoritz Buhl has made curl http3 work over linuxquic:\n\n    # git clone https://github.com/moritzbuhl/curl.git -b linux_curl\n    # cd curl\n    # autoreconf -i\n    # ./configure --prefix=/usr/ --with-gnutls --with-linux-quic --with-nghttp3\n    # make -j$(nproc)\n    # sudo make install\n\nThe test can be done with curl:\n\n    # curl --http3-only --ipv4 https://cloudflare-quic.com/\n    # curl --http3-only --ipv4 https://facebook.com/\n    # curl --http3-only --ipv4 https://litespeedtech.com/\n    # curl --http3-only --ipv4 https://nghttp2.org:4433/\n    # curl --http3-only --ipv4 https://outlook.office.com/\n    # curl --http3-only --ipv4 https://www.google.com/\n\n### QUIC Interop Test with quic-interop-runner:\n    Packages Required:\n    - cmake flex bison byacc ninja-build\n    - python3-pip docker docker-compose\n    - libgcrypt-devel c-ares-devel glib2-devel libpcap-devel (yum)\n      libgcrypt20-dev libc-ares-dev libglib2.0-dev libpcap-dev (apt-get)\n\n    Build latest wireshark:\n    # cd /home/lxin\n    # git clone https://github.com/wireshark/wireshark.git\n    # cd wireshark/\n    # cmake -GNinja -DBUILD_wireshark=0 -DBUILD_qtshark=0 -DBUILD_editcap=1 \\\n      -DBUILD_capinfos=0 -DBUILD_text2pcap=0 -DBUILD_rawshark=0 -DBUILD_sdjournal=0 \\\n      -DBUILD_sshdump=0 -DBUILD_ciscodump=0 -DBUILD_sharkd=0 -DENABLE_STATIC=1 \\\n      -DENABLE_PLUGINS=0 -DENABLE_LIBXML2=0 -DENABLE_BROTLI=0 -DENABLE_GNUTLS=1 .\n    # ninja\n    # sudo ninja install\n\n    Build test image (Optional):\n    # cd /home/lxin\n    # git clone https://github.com/quic-interop/quic-network-simulator.git\n    # cd quic-network-simulator/\n    # cp -r /home/lxin/quic/tests/interop linuxquic-interop\n    # CLIENT=\"linuxquic-interop\" SERVER=\"linuxquic-interop\" docker compose build\n    # docker image ls linuxquic-interop\n      REPOSITORY           TAG       IMAGE ID       CREATED          SIZE\n      linuxquic-interop    latest    3329ae030c62   52 seconds ago   568MB\n\n    Run tests:\n    # cd /home/lxin\n    # git clone https://github.com/quic-interop/quic-interop-runner.git\n    # cd quic-interop-runner/\n    # pip3 install -r requirements.txt\n\nYou can change implementations_quic.json file to run test cases between different implementations.\nHere displays the testing result between linuxquic ngtcp2 quiche and msquic:\n\n    # cat implementations_quic.json\n      {\n        \"linuxquic\": {\n          \"image\": \"quay.io/lxin/linuxquic-interop:latest\",\n          \"url\": \"https://github.com/lxin/quic\",\n          \"role\": \"both\"\n        },\n        \"ngtcp2\": {\n          \"image\": \"ghcr.io/ngtcp2/ngtcp2-interop:latest\",\n          \"url\": \"https://github.com/ngtcp2/ngtcp2\",\n          \"role\": \"both\"\n        },\n        \"quiche\": {\n          \"image\": \"cloudflare/quiche-qns:latest\",\n          \"url\": \"https://github.com/cloudflare/quiche\",\n          \"role\": \"both\"\n        },\n        \"msquic\": {\n          \"image\": \"ghcr.io/microsoft/msquic/qns:main\",\n          \"url\": \"https://github.com/microsoft/msquic\",\n          \"role\": \"both\"\n        }\n      }\n\n    # python3 run.py\n      ...\n      Run took 7:03:10.119649\n\n      Tests:\n      +-----------+---------------------------------------------+----------------------------------------------+\n      |           |                     linuxquic               |                       ngtcp2                 |\n      +-----------+---------------------------------------------+----------------------------------------------+\n      | linuxquic | ✓(H,DC,LR,C20,M,S,R,Z,3,B,U,E,A,L1,L2,C1,C2,| ✓(H,DC,LR,C20,M,S,R,Z,3,B,U,E,A,L1,L2,C1,C2, |\n      |           |   6,V2)                                     |   6,V2)                                      |\n      |           |                      ?()                    |                      ?()                     |\n      |           |                      ✕()                    |                      ✕()                     |\n      +-----------+---------------------------------------------+----------------------------------------------+\n      |   ngtcp2  | ✓(H,DC,LR,C20,M,S,R,Z,3,B,U,E,A,L1,L2,C1,C2,| ✓(H,DC,LR,C20,M,S,R,Z,3,B,U,E,A,L1,L2,C1,C2, |\n      |           |   6,V2)                                     |   6,V2)                                      |\n      |           |                      ?()                    |                      ?()                     |\n      |           |                      ✕()                    |                      ✕()                     |\n      +-----------+---------------------------------------------+----------------------------------------------+\n      |   quiche  |    ✓(H,DC,LR,M,S,R,Z,3,B,A,L1,L2,C1,C2,6)   |   ✓(H,DC,LR,M,S,R,Z,3,B,A,L1,L2,C1,C2,6)     |\n      |           |                 ?(C20,U,E,V2)               |                 ?(C20,U,E,V2)                |\n      |           |                      ✕()                    |                      ✕()                     |\n      +-----------+---------------------------------------------+----------------------------------------------+\n      |   msquic  |    ✓(H,DC,LR,C20,M,S,R,B,U,A,L1,L2,C1,C2,6, |   ✓(H,DC,LR,C20,M,S,R,B,U,A,L1,L2,C1,C2,6)   |\n      |           |                    ?(Z,3,E)                 |                    ?(Z,3,E)                  |\n      |           |                      ✕()                    |                     ✕(V2)                    |\n      +-----------+---------------------------------------------+----------------------------------------------+\n      +-----------+---------------------------------------------+----------------------------------------------+\n      |           |                    quiche                   |                     msquic                   |\n      +-----------+---------------------------------------------+----------------------------------------------+\n      | linuxquic | ✓(H,DC,LR,C20,M,S,R,Z,3,B,U,A,L1,L2,C1,C2,6)| ✓(H,DC,LR,C20,M,S,R,Z,B,U,A,L1,L2,C1,C2,6,V2)|\n      |           |                   ?(E,V2)                   |                     ?(3,E)                   |\n      |           |                     ✕()                     |                      ✕()                     |\n      +-----------+---------------------------------------------+----------------------------------------------+\n      |   ngtcp2  | ✓(H,DC,LR,C20,M,S,R,Z,3,B,U,A,L1,L2,C1,C2,6)|  ✓(H,DC,LR,C20,M,S,R,Z,B,U,L1,L2,C1,C2,6,V2) |\n      |           |                   ?(E,V2)                   |                    ?(3,E,A)                  |\n      |           |                     ✕()                     |                      ✕()                     |\n      +-----------+---------------------------------------------+----------------------------------------------+\n      |   quiche  |     ✓(H,DC,LR,M,S,R,Z,3,B,A,L1,L2,C2,6)     |          ✓(H,DC,LR,M,S,R,Z,B,L2,C2,6)        |\n      |           |                ?(C20,U,E,V2)                |                ?(C20,3,U,E,V2)               |\n      |           |                    ✕(C1)                    |                   ✕(A,L1,C1)                 |\n      +-----------+---------------------------------------------+----------------------------------------------+\n      |   msquic  |    ✓(H,DC,LR,C20,M,S,R,B,A,L1,L2,C1,C2,6)   |   ✓(H,DC,LR,C20,M,S,R,B,U,L1,L2,C1,C2,6,V2)  |\n      |           |                 ?(Z,3,E,V2)                 |                   ?(Z,3,E,A)                 |\n      |           |                     ✕(U)                    |                      ✕()                     |\n      +-----------+---------------------------------------------+----------------------------------------------+\n\n      Measurments:\n      +-----------+----------------------+-----------------------+----------------------+----------------------+\n      |           |      linuxquic       |         ngtcp2        |        quiche        |        msquic        |\n      +-----------+----------------------+-----------------------+----------------------+----------------------+\n      | linuxquic | G: 8671 (± 273) kbps |  G: 5824 (± 552) kbps | G: 9097 (± 34) kbps  | G: 7393 (± 406) kbps |\n      |           | C: 3731 (± 168) kbps |  C: 2951 (± 261) kbps | C: 6841 (± 191) kbps | C: 9016 (± 95) kbps  |\n      +-----------+----------------------+-----------------------+----------------------+----------------------+\n      |   ngtcp2  | G: 9104 (± 141) kbps |  G: 9028 (± 273) kbps | G: 9305 (± 12) kbps  | G: 8971 (± 15) kbps  |\n      |           | C: 3704 (± 194) kbps | C: 6852 (± 1811) kbps | C: 7512 (± 306) kbps | C: 7976 (± 412) kbps |\n      +-----------+----------------------+-----------------------+----------------------+----------------------+\n      |   quiche  | G: 9137 (± 149) kbps |  G: 9146 (± 12) kbps  | G: 9155 (± 28) kbps  | G: 7601 (± 416) kbps |\n      |           | C: 4877 (± 165) kbps | C: 7813 (± 2508) kbps | C: 7649 (± 89) kbps  | C: 7422 (± 107) kbps |\n      +-----------+----------------------+-----------------------+----------------------+----------------------+\n      |   msquic  | G: 8929 (± 212) kbps |  G: 7182 (± 873) kbps | G: 9401 (± 11) kbps  |  G: 9091 (± 4) kbps  |\n      |           |          C           |           C           | C: 6989 (± 292) kbps | C: 7089 (± 506) kbps |\n      +-----------+----------------------+-----------------------+----------------------+----------------------+\n\n### Performance Test with iperf:\n    # git clone https://github.com/lxin/iperf.git\n    # cd iperf/\n    # ./bootstrap.sh\n    # ./configure --prefix=/usr\n    # make\n    # sudo make install\n\nQUIC vs kTLS iperf testing over 100G physical NIC with different packet size and MTU:\n\n    On server:\n    # iperf3 -s --pkey /home/lxin/quic/tests/keys/server-key.pem  \\\n                --cert /home/lxin/quic/tests/keys/server-cert.pem\n\n    On client:\n    # iperf3 -c $SERVER_IP --quic -l $PACKET_LEN\n\n    UNIT        size:1024      size:4096      size:16384     size:65536\n    Gbits/sec   QUIC | kTLS    QUIC | kTLS    QUIC | kTLS    QUIC | kTLS\n    --------------------------------------------------------------------\n    mtu:1500    1.67 | 2.16    3.04 | 5.04    3.49 | 7.84    3.83 | 7.95\n    no GSO           | 1.73         | 3.12         | 4.05         | 4.28\n    --------------------------------------------------------------------\n    mtu:9000    2.17 | 2.41    5.47 | 6.19    6.45 | 8.66    7.48 | 8.90\n    no GSO           | 2.30         | 5.69         | 8.66         | 8.82\n\nQUIC (disable_1rtt_encryption) vs TCP iperf testing over 100G physical NIC with different packet\nsize and MTU:\n\n    On server:\n    # iperf3 -s --pkey /home/lxin/quic/tests/keys/server-key.pem  \\\n                --cert /home/lxin/quic/tests/keys/server-cert.pem --no-cryption\n\n    On client:\n    # iperf3 -c $SERVER_IP --quic -l $PACKET_LEN --no-cryption\n\n    UNIT        size:1024      size:4096      size:16384     size:65536\n    Gbits/sec   QUIC | TCP     QUIC | TCP     QUIC | TCP     QUIC | TCP\n    --------------------------------------------------------------------\n    mtu:1500    2.17 | 2.49    3.59 | 8.36    6.09 | 15.1    6.92 | 16.2\n    no GSO           | 2.50         | 4.12         | 4.86         | 5.04\n    --------------------------------------------------------------------\n    mtu:9000    2.47 | 2.54    7.66 | 7.97    14.7 | 20.3    19.1 | 31.3\n    no GSO           | 2.51         | 8.34         | 18.3         | 22.3\n\nNote kTLS testing is using iperf from https://github.com/Mellanox/iperf_ssl, and the only way to\ndisable TCP GSO is to remove sk_is_tcp() check in sk_setup_caps() and bring sk_can_gso() back in\nkernel code.\n\nAs the test data shows, the TCP GSO contributes to performance a lot for TCP and kTLS with mtu 1500\nand large msgs. With TCP GSO disabled, the small performance gap between QUIC and kTLS, QUIC with\ndisable_1rtt_encryption and TCP is caused by:\n\n- QUIC has an extra copy on TX path.\n- QUIC has an extra encryption for header protection.\n- QUIC has a longer header for the stream DATA.\n\n### QUIC Test with NetPerfMeter\n\n[Network Performance Meter\u0026nbsp;(NetPerfMeter)](https://www.nntb.no/~dreibh/netperfmeter/) is a\nnetwork performance metering tool for the TCP, MPTCP, SCTP, UDP, DCCP, and QUIC transport protocols.\nParticularly, it can be utilized to compare concurrent flows of different protocols to e.g.\u0026nbsp;\nevaluate congestion control behavior using saturated and non-saturated flows, with various\nconfiguration options.\n\nNetPerfMeter can be built with support for Linux Kernel QUIC (details in\n[NetPerfMeter QUIC Communication](https://www.nntb.no/~dreibh/netperfmeter/#quic-communication)),\nto run performance evaluations:\n\n* Server side using base port 9000:\n\n  ```bash\n  netperfmeter 9000 \\\n     --control-over-tcp \\\n     --tls-key  server.domain.example.key \\\n     --tls-cert server.domain.example.crt \\\n     --tls-ca   ca.crt \\\n  ```\n\n* Client side establishing a bidirectional, saturated QUIC flow using messages of 1000\u0026nbsp;bytes:\n\n  ```bash\n   netperfmeter $SERVER_IP:9000 \\\n      --control-over-tcp \\\n      --tls-hostname server.domain.example \\\n      --tls-ca $DIRECTORY/TestCA/TestLevel1/certs/TestLevel1.crt \\\n      --quic const0:const1000:const0:const1000\n  ```\n\n  `SERVER_IP` contains the server's IP address.\n\nWireshark in its latest version supports the dissection of NetPerfMeter payload traffic over QUIC\nfor analysis; see [NetPerfMeter Wireshark](https://www.nntb.no/~dreibh/netperfmeter/#wireshark)\nfor the configuration details.\n\n## USER APIS\n\nSimilar to TCP and SCTP, a typical server and client use the following system call sequence to\ncommunicate:\n\n      Client                             Server\n    ----------------------------------------------------------------------\n    sockfd = socket(IPPROTO_QUIC)      listenfd = socket(IPPROTO_QUIC)\n    bind(sockfd)                       bind(listenfd)\n                                       listen(listenfd)\n    connect(sockfd)\n    quic_client_handshake(sockfd)\n                                       sockfd = accept(listenfd)\n                                       quic_server_handshake(sockfd, cert)\n\n    sendmsg(sockfd)                    recvmsg(sockfd)\n    close(sockfd)                      close(sockfd)\n                                       close(listenfd)\n\nThis section shows you the basic usage of QUIC, you can get more details via man page:\n\n    # man quic\n\n### Basic APIs Use in User Space\n\n- these APIs are provided (see [tests/sample_test.c](https://github.com/lxin/quic/blob/main/tests/sample_test.c) for how APIs are used):\n\n      int quic_client_handshake(int sockfd, const char *pkey_file,\n                                const char *hostname, const char *alpns);\n      int quic_server_handshake(int sockfd, const char *pkey_file,\n                                const char *cert_file, const char *alpns);\n\n      ssize_t quic_sendmsg(int sockfd, const void *msg, size_t len,\n                           int64_t sid, uint32_t flags);\n      ssize_t quic_recvmsg(int sockfd, void *msg, size_t len,\n                           int64_t *sid, uint32_t *flags);\n\n- include the header file in c file like sample_test.c:\n\n      #include \u003cnetinet/quic.h\u003e\n\n- then build it by:\n\n      # gcc sample_test.c -o sample_test -lquic\n\n### Advanced APIs with more TLS Handshake Parameters\n\n- these APIs are provided (see [tests/ticket_test.c](https://github.com/lxin/quic/blob/main/tests/ticket_test.c) for how APIs are used):\n\n      int quic_handshake_init(gnutls_session_t session, struct quic_handshake_step **pstep);\n      int quic_handshake_step(gnutls_session_t session, struct quic_handshake_step **pstep);\n      void quic_handshake_deinit(gnutls_session_t session);\n\n      int quic_handshake(gnutls_session_t session);\n\n      int quic_session_get_data(gnutls_session_t session,\n                                void *data, size_t *size);\n      int quic_session_set_data(gnutls_session_t session,\n                                const void *data, size_t size);\n\n      int quic_session_get_alpn(gnutls_session_t session,\n                                void *data, size_t *size);\n      int quic_session_set_alpn(gnutls_session_t session,\n                                const void *data, size_t size);\n\n- include the header file in c file like ticket_test.c:\n\n      #include \u003cnetinet/quic.h\u003e\n\n- then build it by:\n\n      # gcc ticket_test.c -o ticket_test -lquic -lgnutls\n\n### Raw Socket APIs with more Control\n\nquic_client/server_handshake() and quic_handshake() in libquic are implemented with gnutls APIs and\nsocket APIs such as send/recvmsg() and set/getsocket().\n\nFor these who want more control or flexibility in the handshake, instead of using the APIs from\nlibquic, they should use the raw socket APIs and gnutls APIs to implement their own QUIC handshake\nfunctions, and they may copy and reuse some code from libquic.\n\n### Use in Kernel Space\n\nNOTE: tlshd service must be installed and started, see\n[Kernel Consumers with ktls-utils](https://github.com/lxin/quic#kernel-consumers-with-ktls-utils),\nas it receives and handles the kernel handshake request for kernel sockets.\n\nIn kernel space, the use is pretty much like TCP sockets, except a extra handshake up-call.\n(See [modules/net/quic/test/sample_test.c](https://github.com/lxin/quic/blob/main/modules/net/quic/test/sample_test.c) for examples)\n\n      Client                             Server\n    -------------------------------------------------------------------------\n    __sock_create(IPPROTO_QUIC, \u0026sock)  __sock_create(IPPROTO_QUIC, \u0026sock)\n    kernel_bind(sock)                   kernel_bind(sock)\n                                        kernel_listen(sock)\n    kernel_connect(sock)\n    tls_client_hello_x509(args:{sock})\n                                        kernel_accept(sock, \u0026newsock)\n                                        tls_server_hello_x509(args:{newsock})\n\n    kernel_sendmsg(sock)                kernel_recvmsg(newsock)\n    sock_release(sock)                  sock_release(newsock)\n                                        sock_release(sock)\n\nYou can run the kernel test code as it shows in tlshd_tests() of\n[tests/runtest.sh](https://github.com/lxin/quic/blob/main/tests/runtest.sh)\n\n## Contributing\n\nWe welcome contributions from the community.\n\n- **Mailing List**: The Linux QUIC developer mailing list is available at\n[lists.linux.dev](https://subspace.kernel.org/lists.linux.dev.html).\nYou can subscribe to \u003cquic@lists.linux.dev\u003e or browse archived threads.\n\n- **Reporting Features or Issues**: Bugs, feature requests, or socket API RFC discussions can be\nsubmitted via the mailing list or GitHub issues.\n\n- **Submitting Patches**: Patches can be sent through the mailing list or via GitHub pull requests.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flxin%2Fquic","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flxin%2Fquic","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flxin%2Fquic/lists"}