neqo — an Implementation of QUIC written in Rust

Overview

Neqo, an Implementation of QUIC written in Rust

neqo logo

To run test HTTP/3 programs (neqo-client and neqo-server):

  • cargo build
  • ./target/debug/neqo-server [::]:12345 --db ./test-fixture/db
  • ./target/debug/neqo-client http://127.0.0.1:12345/

Faster Builds with Separate NSS/NSPR

You can clone NSS (https://hg.mozilla.org/projects/nss) and NSPR (https://hg.mozilla.org/projects/nspr) into the same directory and export an environment variable called NSS_DIR pointing to NSS. This causes the build to use the existing NSS checkout. However, in order to run anything that depends on NSS, you need to set $\[DY]LD\_LIBRARY\_PATH to point to $NSS_DIR/../dist/Debug/lib.

Note: If you did not compile NSS separately, you need to have mercurial (hg), installed. NSS builds require gyp, and ninja (or ninja-build) to be present also.

Debugging Neqo

Using SSLKEYLOGFILE to decrypt Wireshark logs

Info here

TODO: What is the minimum Wireshark version needed? TODO: Above link may be incorrect, protocol now called TLS instead of SSL?

Using RUST_LOG effectively

As documented in the env_logger documentation, the RUST_LOG environment variable can be used to selectively enable log messages from Rust code. This works for Neqo's cmdline tools, as well as for when Neqo is incorporated into Gecko, although Gecko needs to be built in debug mode.

Some examples:

  1. RUST_LOG=neqo_transport::dump ./mach run lists sent and received QUIC packets and their frames' contents only.
  2. RUST_LOG=neqo_transport=debug,neqo_http3=trace,info ./mach run sets a 'debug' log level for transport, 'trace' level for http3, and 'info' log level for all other Rust crates, both Neqo and others used by Gecko.
  3. RUST_LOG=neqo=trace,error ./mach run sets trace level for all modules starting with "neqo", and sets error as minimum log level for other unrelated Rust log messages.

Trying In-development Neqo code in Gecko

In a checked-out copy of Gecko source, set paths for the four Neqo crates to local versions in netwerk/socket/neqo_glue/Cargo.toml. For example, if Neqo was checked out to /home/alice/git/neqo, change:

neqo-http3 = { tag = "v0.1.7", git = "https://github.com/mozilla/neqo" }
neqo-transport = { tag = "v0.1.7", git = "https://github.com/mozilla/neqo" }
neqo-common = { tag = "v0.1.7", git = "https://github.com/mozilla/neqo" }

to

neqo-http3 = { path = "/home/alice/git/neqo/neqo-http3" }
neqo-transport = { path = "/home/alice/git/neqo/neqo-transport" }
neqo-common = { path = "/home/alice/git/neqo/neqo-common" }

and

[dependencies.neqo-crypto]
tag = "v0.1.7"
git = "https://github.com/mozilla/neqo"
default-features = false
features = ["gecko"]

to

[dependencies.neqo-crypto]
path = "/home/alice/git/neqo/neqo-crypto"
default-features = false
features = ["gecko"]

Note: Using newer Neqo code with Gecko may also require changes (likely to neqo_glue) if something has changed.

Compile Gecko as usual with ./mach build.

Comments
  • Crash: assert!(body.len() <= 2048); in neqo-transport/src/crypto.rs#l549

    Crash: assert!(body.len() <= 2048); in neqo-transport/src/crypto.rs#l549

    0 xul.dll RustMozCrash mozglue/static/rust/wrappers.cpp:16 1 xul.dll mozglue_static::panic_hook mozglue/static/rust/lib.rs:89 2 xul.dll core::ops::function::Fn::call<fn ../18bf6b4f01a6feaf7259ba7cdae58031af1b7b39/library/core/src/ops/function.rs:227 3 xul.dll std::panicking::rust_panic_with_hook ../18bf6b4f01a6feaf7259ba7cdae58031af1b7b39//library/std/src/panicking.rs:573 4 xul.dll std::panicking::begin_panic::{{closure}}<str*> ../18bf6b4f01a6feaf7259ba7cdae58031af1b7b39/library/std/src/panicking.rs:498 5 xul.dll std::sys_common::backtrace::__rust_end_short_backtrace<closure-0, !> ../18bf6b4f01a6feaf7259ba7cdae58031af1b7b39/library/std/src/sys_common/backtrace.rs:153 6 xul.dll std::panicking::begin_panic<str*> ../18bf6b4f01a6feaf7259ba7cdae58031af1b7b39/library/std/src/panicking.rs:497 7 xul.dll neqo_transport::crypto::CryptoDxState::encrypt third_party/rust/neqo-transport/src/crypto.rs:552 8 xul.dll static neqo_transport::packet::PacketBuilder::build third_party/rust/neqo-transport/src/packet/mod.rs:320 9 xul.dll neqo_transport::connection::Connection::output third_party/rust/neqo-transport/src/connection/mod.rs:1408

    opened by ddragana 16
  • Qlog

    Qlog

    Add optional qlog context when creating a Connection.

    Pass qlog context into Connection from neqo-client. Add cmdline option to save qlog to a file.

    Implement initial trace hooks for client connected start and packet received. Still a lot more to do.

    help wanted work-in-progress 
    opened by agrover 12
  • Fix #354: QPACK: Reset increment count after sending a header acknowledgment

    Fix #354: QPACK: Reset increment count after sending a header acknowledgment

    Per https://tools.ietf.org/html/draft-ietf-quic-qpack-11#section-2.1.4, it seems that a header acknowledgment obviates the requirement of sending increment instructions, in certain cases. This patch makes sure that the decoder does not send increment instructions for only the potentially-blocking references from the header block which are implictly acknowledged by the header acknowledgment.

    opened by hawkinsw 12
  • Enable clippy::pedantic

    Enable clippy::pedantic

    There are a bunch of problems that might be revealed by clippy::pedantic. While false positives are a risk, we can suppress individual warnings as they are analyzed.

    opened by martinthomson 12
  • Drop support for drafts -27 and -28

    Drop support for drafts -27 and -28

    The usage rates of these early drafts is low enough that we should remove them. They are also a tiny bit weaker as they don't do some validation checking (on connection IDs specifically).

    This will need to be coordinated with Firefox, probably by removing them from there first (which is just a few lines of code).

    good first issue task-small 
    opened by martinthomson 11
  • Decide on final name for this code

    Decide on final name for this code

    Yes it's a bikeshed, but it seems like some things are gated on resolving this. Here's some possibilities I'll throw out there:

    1. Neqo (current working name)
    2. Quico
    3. Minqo
    4. Sable (a Mink-like creature)
    5. Polecat (same as above)
    6. Quickness (QUIC + NSS)
    7. Morq (Mozilla-Originated Rust-based Quic)
    8. Marq (Mozilla-Authored Rust-based Quic)
    9. Jiffy
    opened by agrover 11
  • Handshake fails with custom client

    Handshake fails with custom client

    I'm using a custom client to connect to the neqo server. However, the handshake never completes and this is what I get on the server side :-

    Event: StateChange { conn: ActiveConnectionRef { c: RefCell { value: ServerConnectionState { c: Server Connection: Closing { error: Transport(CryptoAlert(120)), frame_type: 6, msg: "CryptoAlert(120)", timeout: Instant { tv_sec: 21793, tv_nsec: 997789700 } } None, last_timer: Instant { tv_sec: 21793, tv_nsec: 997789700 } } } }, state: Closing(Transport(376)) }

    Are there any obvious reasons this could be happening ? NOTE :- The client being used successfully completes handshakes with several other QUIC Implementations.

    server-side 
    opened by piano-man 10
  • Neqo sometimes fails to establish connection in case of high packet loss

    Neqo sometimes fails to establish connection in case of high packet loss

    neqo-client.log.gz

    handshakeloss test occasionally fails at https://github.com/mozilla/neqo/blob/141c232d1227001fb53254b84893b071719485d2/neqo-client/src/main.rs#L719, because connecting times out

    bug 
    opened by vonasek 9
  • Reduce timer granularity constant

    Reduce timer granularity constant

    from https://github.com/mozilla/neqo/pull/591#issuecomment-622251047

    We should also look to reducing our timer granularity constant. It's currently 20ms, which is far too high.

    enhancement 
    opened by agrover 9
  • Create events for when send streams become blocked

    Create events for when send streams become blocked

    In light of use cases like #261, it seems like a good idea to create/expose a DataBlocked event (a parallel of a DataWritable event) when a send stream becomes blocked because of a lack of credits.

    work-in-progress 
    opened by hawkinsw 9
  • Build NSS into docker image

    Build NSS into docker image

    This should make CI builds a LOT faster.

    Unfortunately, I have been unable to test that this works because dockerhub is acting strangely and I'm unwilling to give it the permissions that it thinks it needs.

    The resulting image is 1.7G, which is hugely overweight. For reference, NSS builds use an image that is half that size. I wanted to keep the ability to track NSS and NSPR versions, and about 300M of that extra is in the NSS checkout, a debug build of NSS and NSPR, and other intermediate files.

    I thought that NSS was the main contributor to the bloat here, but it seems like installing rust is the main contributor. Installing the minimal set of things we rely on bumps the image from 561M to 1.42G. That probably bears further investigation.

    Originally thinking that NSS was the reason for the bloat, I learned something interesting about mercurial. If you remove a directory, it will happily update even if there are changes to that directory. That allowed me to remove some of the larger directories from NSS. That's worth a couple of hundred meg.

    As a bonus, I've disabled building of tests for NSS, which - in addition to saving a lot of space - drives the compilation time down a lot. That applies always, so you should see that benefit elsewhere.

    opened by martinthomson 9
  • When receiving a datagram, the stream id needs to be multiplied by 4

    When receiving a datagram, the stream id needs to be multiplied by 4

    According to spec, the HTTP/3 datagram format is:

    HTTP/3 Datagram {
         Quarter Stream ID (i),
         HTTP Datagram Payload (..),
       }
    

    When sending a datagram, we did divide the stream id by 4, but we didn't multiply it by 4 when receiving a datagram.

    opened by KershawChang 0
  • gecko build issue with version v0.6.2

    gecko build issue with version v0.6.2

    I encountered this error when building gecko with v0.6.2.

     0:16.07    Compiling neqo_glue v0.1.0 (/Users/changkershaw/work/gecko/netwerk/socket/neqo_glue)
     0:16.17 error[E0603]: module `features` is private
     0:16.17    --> netwerk/socket/neqo_glue/src/lib.rs:11:5
     0:16.17     |
     0:16.17 11  |     features::extended_connect::SessionCloseReason, Error as Http3Error, Http3Client,
     0:16.17     |     ^^^^^^^^ private module
     0:16.17     |
     0:16.17 note: the module `features` is defined here
     0:16.17    --> /Users/changkershaw/work/neqo/neqo/neqo-http3/src/lib.rs:146:1
     0:16.17     |
     0:16.17 146 | mod features;
     0:16.17     | ^^^^^^^^^^^^^
     0:16.21 For more information about this error, try `rustc --explain E0603`.
     0:16.21 error: could not compile `neqo_glue` due to previous error
    
    opened by KershawChang 0
  • Update QUICv2 and VN codepoints

    Update QUICv2 and VN codepoints

    We currently support the draft version codepoints. Final values have been assigned for QUICv2 and I expect IANA to make a new assignment for the version negotiation draft soon. (The -13 draft is still on the codepoint we have in our code.)

    We should make the change to both sets of codepoints concurrently. There is a possible interop failure if we deploy one change without the other.

    opened by martinthomson 0
  • Turn on TLS greasing

    Turn on TLS greasing

    When https://phabricator.services.mozilla.com/D161806 lands, we should enable greasing.

    This means either tolerating a failure to set the option or bumping the NSS version requirement (and waiting for an NSS release). I might lean toward the former for the moment to avoid a pipeline stall.

    opened by martinthomson 2
  • Properly check validity of a session ID

    Properly check validity of a session ID

    Related Issue https://github.com/mozilla/neqo/issues/1367

    Changes

    • check if the session ID is a valid client-initiated stream id.
    • check if the session ID is a valid bidirectional stream id.
    • check if the session ID is a allowed value.
    opened by highpon 0
Releases(v0.6.3)
Owner
Mozilla
This technology could fall into the right hands.
Mozilla
QUIC proxy that allows to use QUIC to connect to an SSH server without needing to patch the client or the server.

quicssh-rs ?? quicssh-rs is a QUIC proxy that allows to use QUIC to connect to an SSH server without needing to patch the client or the server. quicss

Jun Ouyang 18 May 5, 2023
Futures-based QUIC implementation in Rust

Pure-rust QUIC protocol implementation Quinn is a pure-rust, future-based implementation of the QUIC transport protocol undergoing standardization by

null 2.6k Jan 8, 2023
🥧 Savoury implementation of the QUIC transport protocol and HTTP/3

quiche is an implementation of the QUIC transport protocol and HTTP/3 as specified by the IETF. It provides a low level API for processing QUIC packet

Cloudflare 7.1k Jan 8, 2023
Peer-to-peer communications library for Rust based on QUIC protocol

qp2p Crate Documentation MaidSafe website SAFE Dev Forum SAFE Network Forum Overview This library provides an API to simplify common tasks when creati

MaidSafe 337 Dec 14, 2022
An experimental HTTP server in Rust that supports HTTP/1.1, HTTP/2, and HTTP/3 over QUIC.

?? H123 An experimental HTTP server in Rust that supports HTTP/1.1, HTTP/2, and HTTP/3 over QUIC. Warning This is an experimental project and not inte

Naoki Ikeguchi 7 Dec 15, 2022
TCP is so widely used, however QUIC may have a better performance.

TCP is so widely used, however QUIC may have a better performance. For softwares which use protocols built on TCP, this program helps them take FULL advantage of QUIC.

zephyr 15 Jun 10, 2022
MQTT over QUIC

MQuicTT ?? This is a pre-alpha project, tread carefully ?? A rustlang utility/library for MQTT over QUIC. QUIC allows us to send data over multiple co

null 29 Dec 16, 2022
A high-performance, lightweight, and cross-platform QUIC library

TQUIC English | 中文 TQUIC is a high-performance, lightweight, and cross-platform library for the IETF QUIC protocol. Advantages High performance: TQUIC

Tencent 11 Oct 27, 2023
A small holepunching implementation written in Rust (UDP)

rust-udp-holepunch A small holepunching implementation written in Rust (UDP) Prerequisites Your rendezvous server must lay in a network which doesn't

Amit Katz 8 Dec 26, 2022
The Rust Implementation of libp2p networking stack.

Central repository for work on libp2p This repository is the central place for Rust development of the libp2p spec. Warning: While we are trying our b

libp2p 3k Jan 4, 2023
A pure Rust implementation of WebRTC API

A pure Rust implementation of WebRTC API

WebRTC.rs 2.7k Jan 7, 2023
Backroll is a pure Rust implementation of GGPO rollback networking library.

backroll-rs Backroll is a pure Rust implementation of GGPO rollback networking library. Development Status This is still in an untested alpha stage. A

Hourai Teahouse 273 Dec 28, 2022
Rust implementation of PRECIS Framework: Preparation, Enforcement, and Comparison of Internationalized Strings in Application Protocols

Rust PRECIS Framework libray PRECIS Framework: Preparation, Enforcement, and Comparison of Internationalized Strings in Application Protocols as descr

Santiago Carot-Nemesio 1 Oct 20, 2022
A high performence Socks5 proxy server with bind/reverse support implementation by Rust.

rsocx A high performence Socks5 proxy server with bind/reverse support implementation by Rust Features Async-std No unsafe code Single executable Linu

b23r0 259 Jan 6, 2023
Interactive bind/reverse PTY shell with Windows&Linux support implementation by Rust.

Cliws Lightweight interactive bind/reverse PTY shell with Windows&Linux support implementation by Rust. Features WebSocket Full pty support: VIM, SSH,

b23r0 215 Dec 3, 2021
Rustus - TUS protocol implementation in Rust.

Rustus Tus protocol implementation written in Rust. Features This implementation has several features to make usage as simple as possible. Rustus is r

Pavel Kirilin 74 Jan 1, 2023
An implementation of the ZITADEL gRPC API in Rust.

An implementation of the ZITADEL gRPC API in Rust. Complemented with other useful elements such as ServiceAccount auth.

Christoph Bühler 10 Dec 15, 2022
RakNet Protocol implementation by Rust.

rust-raknet RakNet Protocol implementation by Rust. Raknet is a reliable udp transport protocol that is often used for communication between game clie

b23r0 161 Dec 29, 2022
Implementation of the Docker Registry HTTP API V2 in Rust, that can act as a proxy to other registries

Docker registry server and proxy (I'm bad at creating catchy names, but this one is good enough.) This project aims to implement a Docker Registry HTT

l4p1n (Mathias B.) 2 Dec 30, 2022