From 8399a99adda2c2f7bc2bfc0cdfe3b5b3d62b3803 Mon Sep 17 00:00:00 2001 From: Udip Pant Date: Tue, 30 Apr 2019 09:08:27 -0700 Subject: [PATCH] add overview of MVFST and other info in README Summary: Adds more info on README Reviewed By: siyengar Differential Revision: D15145263 fbshipit-source-id: 93fa6cb37250a08fd78577013d9eb9d20d74430b --- README.md | 97 +++++++++++++++++++++++++++++++++++++++++------------- logo.png | Bin 0 -> 37694 bytes 2 files changed, 75 insertions(+), 22 deletions(-) create mode 100644 logo.png diff --git a/README.md b/README.md index 3f0306442..0b620e3e0 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,45 @@ +![alt text](logo.png "MVFST") + +## Introduction +`mvfst` is a client and server implementation of [IETF QUIC](https://tools.ietf.org/html/draft-ietf-quic-transport-20) protocol in C++ by Facebook. QUIC is a UDP based reliable, multiplexed transport protocol that will become an internet standard. The goal of `mvfst` is to build a performant implementation of the QUIC transport protocol that applications could adapt for use cases on both the internet and the data-center. `mvfst` has been tested at scale on android, iOS apps, as well as servers and has several features to support large scale deployments. + +## Features +**Server features**: +- Multi-threaded UDP socket server with a thread local architecture to be able to scale to multi-core servers +- Customizable Connection-Id routing. The default Connection-Id routing implementation integrates seamlessly with [katran](https://github.com/facebookincubator/katran) +- APIs to enable zero-downtime restarts of servers, so that applications do not have to drop connections when restarting. +- APIs to expose transport and server statistics for debuggability +- Zero-Rtt connection establishment and customizable zero rtt path validation +- Support for UDP Generic segmentation offloading (GSO) for faster UDP writes. + +**Client features**: +- Native happy eyeballs support between ipv4 and ipv6 so that applications do not need to implement it themselves +- Pluggable congestion control and support for turning off congestion control to plug in application specific control algorithms +- QUIC trace APIs to retrieve deep transport level stats. + +## Source Layout +- `quic/api`: Defines API that applications can use to interact with the QUIC transport layer. +- `quic/client`: Client transport implementation +- `quic/server`: Server transport implementation +- `quic/codec`: Read and write codec implementation for the protocol +- `quic/common`: Implementation of common utility functions +- `quic/congestion_control`: Implementation of different congestion control algorithms such as Cubic and Copa +- `quic/flowcontrol`: Implementations of flowcontrol functions +- `quic/handshake`: Implementations cryptographic handshake layer +- `quic/loss`: Implementations of different loss recovery algotithms +- `quic/logging`: Implementation of logging framework +- `quic/happyeyeballs`: Implementation of mechanism to race IPV4 and IPV6 connection and pick a winner +- `quic/state`: Defines and implements both connection and stream level state artifacts and state machines +- `quic/tools`: Implementation of tools such as one to trace transport events within a connection +- `quic/sample`: Example client and server + -## Building +## Dependencies + +`mvfst` largely depends on two libraries: [folly](https://www.github.com/facebook/folly) and [fizz](https://www.github.com/facebookincubator/fizz). + +## Building mvfst ### Ubuntu 16+ @@ -9,24 +48,24 @@ consists of dependencies from [folly](https://github.com/facebook/folly) as well [fizz](https://github.com/facebookincubator/fizz). ``` -sudo apt-get install \ - g++ \ - cmake \ - libboost-all-dev \ - libevent-dev \ +sudo apt-get install \ + g++ \ + cmake \ + libboost-all-dev \ + libevent-dev \ libdouble-conversion-dev \ - libgoogle-glog-dev \ - libgflags-dev \ - libiberty-dev \ - liblz4-dev \ - liblzma-dev \ - libsnappy-dev \ - make \ - zlib1g-dev \ - binutils-dev \ - libjemalloc-dev \ - libssl-dev \ - pkg-config \ + libgoogle-glog-dev \ + libgflags-dev \ + libiberty-dev \ + liblz4-dev \ + liblzma-dev \ + libsnappy-dev \ + make \ + zlib1g-dev \ + binutils-dev \ + libjemalloc-dev \ + libssl-dev \ + pkg-config \ libsodium-dev ``` @@ -47,7 +86,6 @@ built libraries and binaries for `mvfst`. You can also install `mvfst` as well as its dependencies `folly` and `fizz` to a custom directory using the build script, by supplying an `INSTALL_PREFIX` env var. - ``` ./build_helper.sh -i /usr/local ``` @@ -55,19 +93,34 @@ See `./build_helper.sh --help` for more options You might need to run the script as root to install to certain directories. +By default the build script `build_helper.sh` enables the building of test target (i.e. runs with `-DBUILD_TEST=ON` option). Since some of tests in `mvfst` require some test artifacts of Fizz, it is necessary to supply the path of the Fizz src directory (via option `DFIZZ_PROJECT`) to correctly build all test targets in `mvfst`. + +## Run a sample client and server +Building the test targets of `mvfst` (or via `build_helper.sh`) should automatically build the sample client and server binaries as well. You can then spin a simple echo server by running: +``` +./quic/samples/echo -mode=server -host= -port= +``` +and to run a client: +``` +./quic/samples/echo -mode=client -host= -port= +``` +For more options, see +``` +./quic/samples/echo --help +``` ## Contributing -We'd love to have your help in making MVFST better. If you're interested, please +We'd love to have your help in making `mvfst` better. If you're interested, please read our guide to [guide to contributing](CONTRIBUTING.md) ## License -MVFST is MIT licensed, as found in the LICENSE file. +`mvfst` is MIT licensed, as found in the LICENSE file. ## Reporting and Fixing Security Issues Please do not open GitHub issues or pull requests - this makes the problem immediately visible to everyone, including malicious actors. Security issues in -MVFST can be safely reported via Facebook's Whitehat Bug Bounty program: +`mvfst` can be safely reported via Facebook's Whitehat Bug Bounty program: https://www.facebook.com/whitehat diff --git a/logo.png b/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..6de677d0a122d45682b409905f563d9509753c4b GIT binary patch literal 37694 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 V9ZyW-4Y)vl?&+J|snT_h_z#qDJR$%9 literal 0 HcmV?d00001