created_at2021-02-27 01:45:25.126675
updated_at2023-10-17 23:59:16.73202
descriptionStreaming Network Overlay Connection Arbitration Tunnel
Rust (github:microsoft:rust)




Streaming Network Overlay Connection Arbitration Tunnel License: MIT License: Apache 2.0

snocat is a framework for forwarding streams across authenticated, encrypted QUIC tunnels, from a tunnel aggregator to a dynamic set of clients.

Unlike VPNs, which scale vertically with the number of users connected to one network, snocat is intended to scale horizontally on the number of networks, allowing dynamic provisioning and selection of target networks, with a small number of concurrent users per target.


:warning: This library is under active development, and its API and protocol are extremely unstable

libsnocat allows creation of custom server and client applications atop the snocat protocol.

This allows for greater configurability and extensibility than is possible through snocat-cli.

Custom Server

To create a server:

  • Create a quinn listen endpoint, referred to as its driver
  • Implement a TunnelManager
    • It doesn't have to be TCP, you can forward whatever you'd like!
  • Implement an AuthenticationHandler
  • Implement a Router
  • Instantiate a TunnelServer atop your manager
    • Due to the complexity in writing a TunnelServer without lifetime or parallelism issues, we include a fully asynchronous, stream-oriented implementation, ConcurrentDeferredTunnelServer, but you can build your own if needed.
  • Forward connections to your server, and await graceful shutdown

Server lifecycle is stream oriented, using a monadic flow from incoming connections to connection event outputs.

Sync trait-objects act as dispatchers to various functionality, relying on interior mutability for any state updates within the dispatch handlers.

Custom Client

To create a client:

  • Create a quinn connection to your server's driver
  • Implement an AuthenticationClient
  • Implement a RoutingClient
  • Forward connections from the connection to your RoutingClient, and await graceful shutdown or quinn::endpoint::Endpoint::wait_idle.

Authentication Layer

Authentication is handled by implementing the client and server portions of an Authenticator.

The AuthenticationHandler trait performs server-side authentication, while a matching AuthenticationClient trait is invoked by the client.

There are plans to allow "by name" dispatch to authenticators in the future, allowing multiple to be registered with a server or client, so clients and servers can negotiate a compatible authentication method.

Authentication provides a single, reliable-ordered bidirectional stream, and either side may close the channel at any time to abort authentication.

Routing Layer

Routing is a term used to describe client handling of a server-provided stream, or server handling of a client-provided stream.

A Router receives a stream header and a routing identifier. If a router does not recognize the type identity of the stream header, it can refuse the stream, which leaves the providing side responsible for stream closure.

Streams are bidirectional, and a canonical example is snocat-cli's TCP streaming, which takes a target port and forwards the stream to localhost at that port via TCP.


Details of the protocol will be published in [docs/] when it is stabilized.


For debug usage, SSLKEYLOGFILE and RUST_LOG parameters are supported.

SSLKEYLOGFILE allows interception with Wireshark TLS Decryption and QUIC dissection.

For example usage, snocat-cli debugging is often performed with a command-line such as the following:

SSLKEYLOGFILE=~/keylog.ssl.txt RUST_LOG="trace,quinn=warn,quinn_proto=warn" \
  cargo run -- client --authority $SERVER_CERT \
    --driver localhost:9090 \
    --target $TARGET \
    --san localhost

See in the official project repository for further development and contribution guidance.

Third-Party Dependencies

Primary crates used include the Tokio stack and futures-rs for async-await capabilities, Quinn for its QUIC implementation.

Various other dependencies are included under their respective licenses, and may be found in Cargo.toml.

Notable exceptions from MIT or MIT OR Apache 2.0 licensing in dependencies are the following crates:

  • ring for TLS, distributed under a BoringSSL-variant, ISC-style permissive license
  • untrusted required by ring for parsing of TLS, distributed under an ISC-style permissive license
  • webpki for TLS WebPKI certificate handling, distributed under an ISC-style permissive license
  • memchr, byteorder, regex-automata are licensed under Unlicense OR MIT
  • prost, prost-types, prost-derive, and prost-build, licensed solely under the Apache-2.0 license
  • ryu required by serde_json for floating point parsing from json, licensed under Apache-2.0 OR BSL-1.0

See for license details of individual crates, and links to their project webpages.


This project may contain trademarks or logos for projects, products, or services. Authorized use of Microsoft trademarks or logos is subject to and must follow Microsoft's Trademark & Brand Guidelines. Use of Microsoft trademarks or logos in modified versions of this project must not cause confusion or imply Microsoft sponsorship. Any use of third-party trademarks or logos are subject to those third-party's policies.

Code of Conduct

This project has adopted the Microsoft Open Source Code of Conduct. For more information see the Code of Conduct FAQ or contact with any additional questions or comments.


Copyright (c) Microsoft Corporation. All rights reserved.

Licensed under either of

at your option.


Under the Contributor License Agreement, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.

Commit count: 468

cargo fmt