Thanks for your interest in contributing to noq! noq is a QUIC implementation forked from Quinn, with added support for multipath QUIC, Address discovery and NAT traversal.
| Crate | Purpose |
|---|---|
noq |
Async user-facing API (tokio or smol) |
noq-proto |
Sans-io protocol state machine — no I/O, no clocks |
noq-udp |
Low-level UDP with ECN, GRO/GSO, cmsg |
bench |
Criterion benchmarks |
perf |
noq-perf binary for throughput/latency profiling |
fuzz |
libfuzzer targets |
docs/book |
mdBook source |
The codebase has a deliberate two-tier split:
noq-protois a pure state machine: deterministic, testable in isolation, no sockets, no internal clock driving the state machine — time is always passed in by the caller. Feed it packets and events; it returns frames to transmit and state changes.noqwrapsnoq-protowith async I/O, timers, and a runtime abstraction. Publicnoqtypes re-export everything fromnoq-protoso callers rarely to depend onnoq-protodirectly.
In response to the influx of AI-assisted PRs, we have a new workflow for getting your PRs merged. The intention is to make it easier for developers who are making meaningful contributions to noq to get the attention of maintainers.
Note: please join our [discord][discord] if you are looking to be mentored through a bug or feature!
Here is the general workflow you should follow to contribute to noq:
Open an issue and have a human-to-human discussion with the maintainers
We will automatically close any PRs that do not reference issues labeled ready-for-pr.
Before opening a PR, open or find an issue and discuss the proposed change with a maintainer. When there is reasonable consensus on how to implement the feature or solve the bug, then a PR is welcome. The PR description must link to that issue (for example, Fixes #123 or Refs #123).
You will know that reasonable consensus was reached when the label ready-for-pr is added to the issue.
-
A PR that does not link to an issue will be closed automatically.
-
A linked issue only counts if the label
ready-for-prwas added. Typically this means that a discussion took place between humans and reasonable consensus was reached. -
A PR may still be closed if the PR does not match the scope agreed on in the issue.
We are a handful of folks trying to maintain high-quality open-source software as well as a welcoming community. Please note that if your PR is closed it is not a judgment on you or the code. It just reflects the changing software landscape that we are all currently living through and the different processes that need to exit to respond to those changes.
Please refer to our AI Policy before using AI to assist or generate any issues you open or comments you write.
Sensible exceptions will be made for small changes that don't require issues, such as doc fixes or maintenance chores, at the discretion of the maintainers.
- An issue linked to it with the label
ready-for-pr. Discuss solutions with maintainers in the linked issue before diving in. This helps keep contributors and maintainers aligned. - A title following this pattern:
<type>(<scope>): <description>. If the change is a breaking change it must also include a!:<type>(<scope>)!: <description>.- Types:
typeWhen to use featA new feature testChanges that exclusively affect tests, either by adding new ones or correcting existing ones fixA bug fix docsDocumentation only changes refactorA code change that neither fixes a bug nor adds a feature perfA code change that improves performance depsDependency only updates choreChanges to the build process or auxiliary tools and libraries - Scopes: These mostly mimic the crate. You will likely use one of
noq,proto,udp - Description: A short sentence stating what the changes achieve
- Types:
- A PR description. Please follow the PR template
- A green CI check. Use
cargo maketo catch most issues locally.
- Documentation updates follow the style guide.
- Keep comments and docs at 100 character width.
- Run
cargo make formatto ensure your code follows the formatting rules of this repo.
- Assuming
upstreamis the local name you gave the quinn remote, usegit fetch upstream mainto get the latest changes. - Use
git log --oneline --reverse HEAD..upstream/main, while on updatedmainto check the missing changes. The first change is the oldest one/ first incoming changemaindoes not have - Use
cherry-pickselectively. Dependabot updates should not be cherry-picked, as they need to be fully replicated via the correspondingcargo update -p <dep> --precise <version>. Git can't meaningfully apply these commits only viadiffsinceCargo.lockis automatically generated. - Always use
cherry-pickwith-xe. Use-xto ensure the original commit hash is included in the commit message at the end. Use-eto adapt the commit message to our commits standards. This is necessary to generate a meaningfulCHANGELOG.md - Verify CI status for individual changes. Not everything can be caught via
cargo make, for example due to different targets.
When all changes are done, let's call <quinn-hash> the last commit from
quinn we want to record as merged. Let's call <noq-hash> the last commit
that achieves this merged state, before the actual merge is recorded. Make sure
your syncing branch is not behind main, as this merge will be fast-forwards
one. In your syncing branch HEAD should point to <noq-hash>. Now do
git merge <quinn-hash>to begin the merge processgit checkout <noq-hash> .To update all paths to the state in<noq-hash>- Make sure there are no differences with
<noq-hash>, you might need togit rm -r quinn-protoand similar to achieve this. Thengit diff <noq-hash>should be clean. git merge --continueto finish the merge. Let's call<merge-hash>the resulting commit.git push. Always verify against CI that the merge commit is good to go.- After CI gives you green light, locally merge to
noq's main usinggit merge --ff-only <merge-hash>