Bug 1644532 - Update to Neqo 0.4.1 r=dragana,necko-reviewers

Default to using draft 27.

Differential Revision: https://phabricator.services.mozilla.com/D78960
This commit is contained in:
Andy Grover 2020-06-09 19:39:47 +00:00
Родитель 34738f5854
Коммит 2475b7008d
28 изменённых файлов: 714 добавлений и 237 удалений

Просмотреть файл

@ -15,7 +15,7 @@ rev = "e3c3388e6632cf55e08d773b32e58b1cab9b2731"
[source."https://github.com/mozilla/neqo"]
git = "https://github.com/mozilla/neqo"
replace-with = "vendored-sources"
tag = "v0.4.0"
tag = "v0.4.1"
[source."https://github.com/mozilla/mp4parse-rust"]
git = "https://github.com/mozilla/mp4parse-rust"

20
Cargo.lock сгенерированный
Просмотреть файл

@ -3091,8 +3091,8 @@ checksum = "a2983372caf4480544083767bf2d27defafe32af49ab4df3a0b7fc90793a3664"
[[package]]
name = "neqo-common"
version = "0.4.0"
source = "git+https://github.com/mozilla/neqo?tag=v0.4.0#f35a3b7800a7062c8b34cae1bdcbf64733935149"
version = "0.4.1"
source = "git+https://github.com/mozilla/neqo?tag=v0.4.1#0aeafc8cfd0b7a3554170419b38c97948b0fb108"
dependencies = [
"chrono",
"env_logger",
@ -3104,8 +3104,8 @@ dependencies = [
[[package]]
name = "neqo-crypto"
version = "0.4.0"
source = "git+https://github.com/mozilla/neqo?tag=v0.4.0#f35a3b7800a7062c8b34cae1bdcbf64733935149"
version = "0.4.1"
source = "git+https://github.com/mozilla/neqo?tag=v0.4.1#0aeafc8cfd0b7a3554170419b38c97948b0fb108"
dependencies = [
"bindgen",
"log",
@ -3117,8 +3117,8 @@ dependencies = [
[[package]]
name = "neqo-http3"
version = "0.4.0"
source = "git+https://github.com/mozilla/neqo?tag=v0.4.0#f35a3b7800a7062c8b34cae1bdcbf64733935149"
version = "0.4.1"
source = "git+https://github.com/mozilla/neqo?tag=v0.4.1#0aeafc8cfd0b7a3554170419b38c97948b0fb108"
dependencies = [
"log",
"neqo-common",
@ -3131,8 +3131,8 @@ dependencies = [
[[package]]
name = "neqo-qpack"
version = "0.4.0"
source = "git+https://github.com/mozilla/neqo?tag=v0.4.0#f35a3b7800a7062c8b34cae1bdcbf64733935149"
version = "0.4.1"
source = "git+https://github.com/mozilla/neqo?tag=v0.4.1#0aeafc8cfd0b7a3554170419b38c97948b0fb108"
dependencies = [
"lazy_static",
"log",
@ -3146,8 +3146,8 @@ dependencies = [
[[package]]
name = "neqo-transport"
version = "0.4.0"
source = "git+https://github.com/mozilla/neqo?tag=v0.4.0#f35a3b7800a7062c8b34cae1bdcbf64733935149"
version = "0.4.1"
source = "git+https://github.com/mozilla/neqo?tag=v0.4.1#0aeafc8cfd0b7a3554170419b38c97948b0fb108"
dependencies = [
"lazy_static",
"log",

Просмотреть файл

@ -8,17 +8,17 @@ edition = "2018"
name = "neqo_glue"
[dependencies]
neqo-http3 = { tag = "v0.4.0", git = "https://github.com/mozilla/neqo" }
neqo-transport = { tag = "v0.4.0", git = "https://github.com/mozilla/neqo" }
neqo-common = { tag = "v0.4.0", git = "https://github.com/mozilla/neqo" }
neqo-qpack = { tag = "v0.4.0", git = "https://github.com/mozilla/neqo" }
neqo-http3 = { tag = "v0.4.1", git = "https://github.com/mozilla/neqo" }
neqo-transport = { tag = "v0.4.1", git = "https://github.com/mozilla/neqo" }
neqo-common = { tag = "v0.4.1", git = "https://github.com/mozilla/neqo" }
neqo-qpack = { tag = "v0.4.1", git = "https://github.com/mozilla/neqo" }
nserror = { path = "../../../xpcom/rust/nserror" }
nsstring = { path = "../../../xpcom/rust/nsstring" }
xpcom = { path = "../../../xpcom/rust/xpcom" }
thin-vec = { version = "0.1.0", features = ["gecko-ffi"] }
[dependencies.neqo-crypto]
tag = "v0.4.0"
tag = "v0.4.1"
git = "https://github.com/mozilla/neqo"
default-features = false
features = ["gecko"]

Просмотреть файл

@ -8,7 +8,7 @@ use neqo_http3::Error as Http3Error;
use neqo_http3::{Http3Client, Http3ClientEvent, Http3State};
use neqo_qpack::QpackSettings;
use neqo_transport::Error as TransportError;
use neqo_transport::{FixedConnectionIdManager, Output};
use neqo_transport::{FixedConnectionIdManager, Output, QuicVersion};
use nserror::*;
use nsstring::*;
use std::cell::RefCell;
@ -76,6 +76,7 @@ impl NeqoHttp3Conn {
local,
remote,
qpack_settings,
QuicVersion::Draft27,
) {
Ok(c) => c,
Err(_) => return Err(NS_ERROR_INVALID_ARG),

Просмотреть файл

@ -5,16 +5,16 @@ authors = ["Dragana Damjanovic <dragana.damjano@gmail.com>"]
edition = "2018"
[dependencies]
neqo-transport = { tag = "v0.4.0", git = "https://github.com/mozilla/neqo" }
neqo-common = { tag = "v0.4.0", git = "https://github.com/mozilla/neqo" }
neqo-http3 = { tag = "v0.4.0", git = "https://github.com/mozilla/neqo" }
neqo-qpack = { tag = "v0.4.0", git = "https://github.com/mozilla/neqo" }
neqo-transport = { tag = "v0.4.1", git = "https://github.com/mozilla/neqo" }
neqo-common = { tag = "v0.4.1", git = "https://github.com/mozilla/neqo" }
neqo-http3 = { tag = "v0.4.1", git = "https://github.com/mozilla/neqo" }
neqo-qpack = { tag = "v0.4.1", git = "https://github.com/mozilla/neqo" }
mio = "0.6.17"
mio-extras = "2.0.5"
log = "0.4.0"
[dependencies.neqo-crypto]
tag = "v0.4.0"
tag = "v0.4.1"
git = "https://github.com/mozilla/neqo"
default-features = false
features = ["gecko"]

Просмотреть файл

@ -1 +1 @@
{"files":{"Cargo.toml":"1ae9f454f1303aac9492c99376ce4dea910cb22a92b87a8e67184e4e336defd5","src/codec.rs":"c33b458cf1631073587edf6b6bd1baafecc7fe9e18d3eb5c3ddc6aaa00bd70c5","src/datagram.rs":"569f8d9e34d7ee17144bf63d34136ecd9778da0d337e513f338738c50284615e","src/incrdecoder.rs":"8d44c4437461cae023448312cab4045ad6e3f0c9eb8af2383f7132be40a9d917","src/lib.rs":"ae4fd37c38e71ffe5a2df59cc4c6db102724e16fab047ddefb213706c66bade1","src/log.rs":"b8da388073f72a21128d52b0d0c963e07a3d3cf3368438ae3a50be34b8add3a4","src/qlog.rs":"4f131c7e4c2bb5862b33a0d1746348a4f63f9b57cfa7a85dce1b59f80ecfaa7b","src/timer.rs":"706333bf1b07f65df9d18904b1cb269e4b80dee93a9b239dd8cb128b293955ae","tests/log.rs":"480b165b7907ec642c508b303d63005eee1427115d6973a349eaf6b2242ed18d"},"package":null}
{"files":{"Cargo.toml":"f301a07481862634459c8c1c07c4ffa71d6c41835d045814d19343560ee28beb","src/codec.rs":"c33b458cf1631073587edf6b6bd1baafecc7fe9e18d3eb5c3ddc6aaa00bd70c5","src/datagram.rs":"569f8d9e34d7ee17144bf63d34136ecd9778da0d337e513f338738c50284615e","src/incrdecoder.rs":"8d44c4437461cae023448312cab4045ad6e3f0c9eb8af2383f7132be40a9d917","src/lib.rs":"72dbf367239ab7f057d59d23cd8ce6ae2b29a2d3362a9ccb162619d80992da9a","src/log.rs":"b8da388073f72a21128d52b0d0c963e07a3d3cf3368438ae3a50be34b8add3a4","src/qlog.rs":"4f131c7e4c2bb5862b33a0d1746348a4f63f9b57cfa7a85dce1b59f80ecfaa7b","src/timer.rs":"706333bf1b07f65df9d18904b1cb269e4b80dee93a9b239dd8cb128b293955ae","tests/log.rs":"480b165b7907ec642c508b303d63005eee1427115d6973a349eaf6b2242ed18d"},"package":null}

2
third_party/rust/neqo-common/Cargo.toml поставляемый
Просмотреть файл

@ -1,6 +1,6 @@
[package]
name = "neqo-common"
version = "0.4.0"
version = "0.4.1"
authors = ["Bobby Holley <bobbyholley@gmail.com>"]
edition = "2018"
license = "MIT/Apache-2.0"

21
third_party/rust/neqo-common/src/lib.rs поставляемый
Просмотреть файл

@ -41,9 +41,28 @@ pub fn hex(buf: &[u8]) -> String {
ret
}
#[must_use]
pub fn hex_snip_middle(buf: &[u8]) -> String {
const SHOW_LEN: usize = 8;
if buf.len() <= SHOW_LEN * 2 {
hex_with_len(buf)
} else {
let mut ret = String::with_capacity(SHOW_LEN * 2 + 16);
ret.push_str(&format!("[{}]: ", buf.len()));
for b in &buf[..SHOW_LEN] {
ret.push_str(&format!("{:02x}", b));
}
ret.push_str("..");
for b in &buf[buf.len() - SHOW_LEN..] {
ret.push_str(&format!("{:02x}", b));
}
ret
}
}
#[must_use]
pub fn hex_with_len(buf: &[u8]) -> String {
let mut ret = String::with_capacity(10 + buf.len() * 3);
let mut ret = String::with_capacity(10 + buf.len() * 2);
ret.push_str(&format!("[{}]: ", buf.len()));
for b in buf {
ret.push_str(&format!("{:02x}", b));

Просмотреть файл

@ -1 +1 @@
{"files":{"Cargo.toml":"2123157cae77dac2ae0e3f40f08e5720a3662f7c1fdb5259cb1f8a9e72387020","TODO":"ac0f1c2ebcca03f5b3c0cc56c5aedbb030a4b511e438bc07a57361c789f91e9f","bindings/bindings.toml":"0ae7922bb20f2b8cf54b307cd642303e65b00cfbc3e681877e2a7a86f7b22530","bindings/mozpkix.hpp":"77072c8bb0f6eb6bfe8cbadc111dcd92e0c79936d13f2e501aae1e5d289a6675","bindings/nspr_err.h":"2d5205d017b536c2d838bcf9bc4ec79f96dd50e7bb9b73892328781f1ee6629d","bindings/nspr_error.h":"e41c03c77b8c22046f8618832c9569fbcc7b26d8b9bbc35eea7168f35e346889","bindings/nspr_io.h":"085b289849ef0e77f88512a27b4d9bdc28252bd4d39c6a17303204e46ef45f72","bindings/nspr_time.h":"2e637fd338a5cf0fd3fb0070a47f474a34c2a7f4447f31b6875f5a9928d0a261","bindings/nss_ciphers.h":"95ec6344a607558b3c5ba8510f463b6295f3a2fb3f538a01410531045a5f62d1","bindings/nss_init.h":"ef49045063782fb612aff459172cc6a89340f15005808608ade5320ca9974310","bindings/nss_p11.h":"0b81e64fe6db49b2ecff94edd850be111ef99ec11220e88ceb1c67be90143a78","bindings/nss_secerr.h":"713e8368bdae5159af7893cfa517dabfe5103cede051dee9c9557c850a2defc6","bindings/nss_ssl.h":"af222fb957b989e392e762fa2125c82608a0053aff4fb97e556691646c88c335","bindings/nss_sslerr.h":"24b97f092183d8486f774cdaef5030d0249221c78343570d83a4ee5b594210ae","bindings/nss_sslopt.h":"b7807eb7abdad14db6ad7bc51048a46b065a0ea65a4508c95a12ce90e59d1eea","build.rs":"979eeb1d7da5342d3a5fd0836132a37f074711a6056d0dc64a91f86717bbd501","src/aead.rs":"b0ed05d399a32e4c923d4d385e4ae72d675d24c6cc86471f59a4edbe5cb2159a","src/agent.rs":"2841e3ae0b9a86990a44a0ecaa0da061b4eea15d782bd35232367b99482fa1f7","src/agentio.rs":"2ab0ad6349276a8c94dfd85bfaedcad24c8fff464b82f7369c1bd45038f79cfd","src/auth.rs":"71ac7e297a5f872d26cf67b6bbd96e4548ea38374bdd84c1094f76a5de4ed1cb","src/cert.rs":"fd3fd2bbb38754bdcee3898549feae412943c9f719032531c1ad6e61783b5394","src/constants.rs":"c39ee506a10d685fda77c1d2ddf691b595b067b4e1044ac7a21e360119d6002b","src/err.rs":"04f38831ca62d29d8aadfe9daf95fd29e68ece184e6d3e00bfb9ee1d12744033","src/exp.rs":"61586662407359c1ecb8ed4987bc3c702f26ba2e203a091a51b6d6363cbd510f","src/ext.rs":"2a7eb6bc2992679e5c04cf5561a4ce886ecbf549454ed927b32abeb09019632d","src/hkdf.rs":"40e44f4280497ef525c2b4c465f14f06d241150851668b264ee958f74321cfbe","src/hp.rs":"7fce64e0cc3a6a7e744bc797886bcfaa39679f0a81853b2e55ea0f54fb6bf700","src/lib.rs":"5f3c4c05c0a5ecb4e4cfc6c4d242e7603566f287bdb0f0ca46f6a773aa7714e9","src/once.rs":"b9850384899a1a016e839743d3489c0d4d916e1973746ef8c89872105d7d9736","src/p11.rs":"0b62ee5938aefb82e8faee5aa14e990a00442cc9744e8ba22eda80b32030c42c","src/prio.rs":"bc4e97049563b136cb7b39f5171e7909d56a77ed46690aaacb781eeb4a4743e0","src/replay.rs":"40924865994396441a68e6009ecbdf352d6a02fdf539aa65604124e26bffb4d3","src/result.rs":"cef34dfcb907723e195b56501132e4560e250b327783cb5e41201da5b63e9b5c","src/secrets.rs":"acb5befa74e06281c6f80d7298efc58f568bb4e6d949b4225c335e3f392be741","src/selfencrypt.rs":"f8d04728353fcbbdd50ad19217c9fd34974ffa8872c0d9d5d6d896d05f04baa5","src/ssl.rs":"d64c20ed2a0b63c5fa3aee674a622408a89a764ee225098f18d0c61ce6c6df29","src/time.rs":"13231bafe24e3c24b3ca582805929cc6dac017180cff7400e062894f22df5735","tests/aead.rs":"a1d8eb69f5672e064f84dce3d214b347a396718e3de56d57ccc108ee87f1cbc1","tests/agent.rs":"89c21e97bf9c8d893380c1d4ab91f4e12526e1a51acc0f19159e643ef8da2a4f","tests/ext.rs":"5f5de777599cbe1295a4461b32c249de74666edb0a13173f76948f2939963dfd","tests/handshake.rs":"6f12fb9a02d36f64254ffe49385de69fce8bc95b73af80be011f0e065d65a5a3","tests/hkdf.rs":"539235e9dcf2a56b72961a9a04f0080409adf6bf465bfad7c30026421b2d4326","tests/hp.rs":"e52a7d2f4387f2dfe8bfe1da5867e8e0d3eb51e171c6904e18b18c4343536af8","tests/init.rs":"20aad800ac793aaf83059cf860593750509fdedeeff0c08a648e7a5cb398dae0","tests/selfencrypt.rs":"46e9a1a09c2ae577eb106d23a5cdacf762575c0dea1948aedab06ef7389ce713"},"package":null}
{"files":{"Cargo.toml":"14863c8f22576992eaaad97bc9ddbf842f6ba625e48622ce22d9ec22d43b21b4","TODO":"ac0f1c2ebcca03f5b3c0cc56c5aedbb030a4b511e438bc07a57361c789f91e9f","bindings/bindings.toml":"0ae7922bb20f2b8cf54b307cd642303e65b00cfbc3e681877e2a7a86f7b22530","bindings/mozpkix.hpp":"77072c8bb0f6eb6bfe8cbadc111dcd92e0c79936d13f2e501aae1e5d289a6675","bindings/nspr_err.h":"2d5205d017b536c2d838bcf9bc4ec79f96dd50e7bb9b73892328781f1ee6629d","bindings/nspr_error.h":"e41c03c77b8c22046f8618832c9569fbcc7b26d8b9bbc35eea7168f35e346889","bindings/nspr_io.h":"085b289849ef0e77f88512a27b4d9bdc28252bd4d39c6a17303204e46ef45f72","bindings/nspr_time.h":"2e637fd338a5cf0fd3fb0070a47f474a34c2a7f4447f31b6875f5a9928d0a261","bindings/nss_ciphers.h":"95ec6344a607558b3c5ba8510f463b6295f3a2fb3f538a01410531045a5f62d1","bindings/nss_init.h":"ef49045063782fb612aff459172cc6a89340f15005808608ade5320ca9974310","bindings/nss_p11.h":"0b81e64fe6db49b2ecff94edd850be111ef99ec11220e88ceb1c67be90143a78","bindings/nss_secerr.h":"713e8368bdae5159af7893cfa517dabfe5103cede051dee9c9557c850a2defc6","bindings/nss_ssl.h":"af222fb957b989e392e762fa2125c82608a0053aff4fb97e556691646c88c335","bindings/nss_sslerr.h":"24b97f092183d8486f774cdaef5030d0249221c78343570d83a4ee5b594210ae","bindings/nss_sslopt.h":"b7807eb7abdad14db6ad7bc51048a46b065a0ea65a4508c95a12ce90e59d1eea","build.rs":"0be611e6b25a18d5ed724071a3a471c2c5b584649b5fe36de28a56ed8caaf800","src/aead.rs":"b0ed05d399a32e4c923d4d385e4ae72d675d24c6cc86471f59a4edbe5cb2159a","src/agent.rs":"d3fba31bbdc6b58ec6a593be580d00021e95a7e132dba61d381ebc10635b0844","src/agentio.rs":"2ab0ad6349276a8c94dfd85bfaedcad24c8fff464b82f7369c1bd45038f79cfd","src/auth.rs":"71ac7e297a5f872d26cf67b6bbd96e4548ea38374bdd84c1094f76a5de4ed1cb","src/cert.rs":"fd3fd2bbb38754bdcee3898549feae412943c9f719032531c1ad6e61783b5394","src/constants.rs":"c39ee506a10d685fda77c1d2ddf691b595b067b4e1044ac7a21e360119d6002b","src/err.rs":"04f38831ca62d29d8aadfe9daf95fd29e68ece184e6d3e00bfb9ee1d12744033","src/exp.rs":"61586662407359c1ecb8ed4987bc3c702f26ba2e203a091a51b6d6363cbd510f","src/ext.rs":"2a7eb6bc2992679e5c04cf5561a4ce886ecbf549454ed927b32abeb09019632d","src/hkdf.rs":"40e44f4280497ef525c2b4c465f14f06d241150851668b264ee958f74321cfbe","src/hp.rs":"7fce64e0cc3a6a7e744bc797886bcfaa39679f0a81853b2e55ea0f54fb6bf700","src/lib.rs":"5f3c4c05c0a5ecb4e4cfc6c4d242e7603566f287bdb0f0ca46f6a773aa7714e9","src/once.rs":"b9850384899a1a016e839743d3489c0d4d916e1973746ef8c89872105d7d9736","src/p11.rs":"0b62ee5938aefb82e8faee5aa14e990a00442cc9744e8ba22eda80b32030c42c","src/prio.rs":"bc4e97049563b136cb7b39f5171e7909d56a77ed46690aaacb781eeb4a4743e0","src/replay.rs":"40924865994396441a68e6009ecbdf352d6a02fdf539aa65604124e26bffb4d3","src/result.rs":"cef34dfcb907723e195b56501132e4560e250b327783cb5e41201da5b63e9b5c","src/secrets.rs":"acb5befa74e06281c6f80d7298efc58f568bb4e6d949b4225c335e3f392be741","src/selfencrypt.rs":"f8d04728353fcbbdd50ad19217c9fd34974ffa8872c0d9d5d6d896d05f04baa5","src/ssl.rs":"d64c20ed2a0b63c5fa3aee674a622408a89a764ee225098f18d0c61ce6c6df29","src/time.rs":"13231bafe24e3c24b3ca582805929cc6dac017180cff7400e062894f22df5735","tests/aead.rs":"a1d8eb69f5672e064f84dce3d214b347a396718e3de56d57ccc108ee87f1cbc1","tests/agent.rs":"89c21e97bf9c8d893380c1d4ab91f4e12526e1a51acc0f19159e643ef8da2a4f","tests/ext.rs":"5f5de777599cbe1295a4461b32c249de74666edb0a13173f76948f2939963dfd","tests/handshake.rs":"6f12fb9a02d36f64254ffe49385de69fce8bc95b73af80be011f0e065d65a5a3","tests/hkdf.rs":"539235e9dcf2a56b72961a9a04f0080409adf6bf465bfad7c30026421b2d4326","tests/hp.rs":"e52a7d2f4387f2dfe8bfe1da5867e8e0d3eb51e171c6904e18b18c4343536af8","tests/init.rs":"20aad800ac793aaf83059cf860593750509fdedeeff0c08a648e7a5cb398dae0","tests/selfencrypt.rs":"46e9a1a09c2ae577eb106d23a5cdacf762575c0dea1948aedab06ef7389ce713"},"package":null}

2
third_party/rust/neqo-crypto/Cargo.toml поставляемый
Просмотреть файл

@ -1,6 +1,6 @@
[package]
name = "neqo-crypto"
version = "0.4.0"
version = "0.4.1"
authors = ["Martin Thomson <mt@lowentropy.net>"]
edition = "2018"
build = "build.rs"

53
third_party/rust/neqo-crypto/build.rs поставляемый
Просмотреть файл

@ -21,25 +21,31 @@ const BINDINGS_CONFIG: &str = "bindings.toml";
// This is the format of a single section of the configuration file.
#[derive(Deserialize)]
struct Bindings {
// types that are explicitly included
types: Option<Vec<String>>,
// functions that are explicitly included
functions: Option<Vec<String>>,
// variables (and `#define`s) that are explicitly included
variables: Option<Vec<String>>,
// types that should be explicitly marked as opaque
opaque: Option<Vec<String>>,
// enumerations that are turned into a module (without this, the enum is
// mapped using the default, which means that the individual values are
// formed with an underscore as <enum_type>_<enum_value_name>).
enums: Option<Vec<String>>,
/// types that are explicitly included
#[serde(default)]
types: Vec<String>,
/// functions that are explicitly included
#[serde(default)]
functions: Vec<String>,
/// variables (and `#define`s) that are explicitly included
#[serde(default)]
variables: Vec<String>,
/// types that should be explicitly marked as opaque
#[serde(default)]
opaque: Vec<String>,
/// enumerations that are turned into a module (without this, the enum is
/// mapped using the default, which means that the individual values are
/// formed with an underscore as <enum_type>_<enum_value_name>).
#[serde(default)]
enums: Vec<String>,
// Any item that is specifically excluded; if none of the types, functions,
// or variables fields are specified, everything defined will be mapped,
// so this can be used to limit that.
exclude: Option<Vec<String>>,
/// Any item that is specifically excluded; if none of the types, functions,
/// or variables fields are specified, everything defined will be mapped,
/// so this can be used to limit that.
#[serde(default)]
exclude: Vec<String>,
// Whether the file is to be interpreted as C++
/// Whether the file is to be interpreted as C++
#[serde(default)]
cplusplus: bool,
}
@ -253,23 +259,22 @@ fn build_bindings(base: &str, bindings: &Bindings, flags: &[String], gecko: bool
builder = builder.clang_args(flags);
// Apply the configuration.
let empty: Vec<String> = vec![];
for v in bindings.types.as_ref().unwrap_or_else(|| &empty).iter() {
for v in &bindings.types {
builder = builder.whitelist_type(v);
}
for v in bindings.functions.as_ref().unwrap_or_else(|| &empty).iter() {
for v in &bindings.functions {
builder = builder.whitelist_function(v);
}
for v in bindings.variables.as_ref().unwrap_or_else(|| &empty).iter() {
for v in &bindings.variables {
builder = builder.whitelist_var(v);
}
for v in bindings.exclude.as_ref().unwrap_or_else(|| &empty).iter() {
for v in &bindings.exclude {
builder = builder.blacklist_item(v);
}
for v in bindings.opaque.as_ref().unwrap_or_else(|| &empty).iter() {
for v in &bindings.opaque {
builder = builder.opaque_type(v);
}
for v in bindings.enums.as_ref().unwrap_or_else(|| &empty).iter() {
for v in &bindings.enums {
builder = builder.constified_enum_module(v);
}

8
third_party/rust/neqo-crypto/src/agent.rs поставляемый
Просмотреть файл

@ -21,7 +21,7 @@ use crate::secrets::SecretHolder;
use crate::ssl::{self, PRBool};
use crate::time::TimeHolder;
use neqo_common::{hex, matches, qdebug, qinfo, qtrace, qwarn};
use neqo_common::{hex_snip_middle, matches, qdebug, qinfo, qtrace, qwarn};
use std::cell::RefCell;
use std::convert::TryFrom;
use std::ffi::CString;
@ -720,7 +720,11 @@ impl Client {
let resumption = resumption_ptr.as_mut().unwrap();
let mut v = Vec::with_capacity(len as usize);
v.extend_from_slice(std::slice::from_raw_parts(token, len as usize));
qinfo!([format!("{:p}", fd)], "Got resumption token {}", hex(&v));
qinfo!(
[format!("{:p}", fd)],
"Got resumption token {}",
hex_snip_middle(&v)
);
*resumption = Some(v);
ssl::SECSuccess
}

Просмотреть файл

@ -1 +1 @@
{"files":{"Cargo.toml":"e155725388085fb02552cfd19ebc1a5f3391dbd31557f85ad50caa728ce68c19","src/client_events.rs":"8c19986b7372b36d1265d4a848b07b5c334511cbdfc02f313c54e551523c08f5","src/connection.rs":"cebdb535151ec5598161091c6b709c38852aa32f32855cee8f2c6129a2bcb5a0","src/connection_client.rs":"4ce2aec1b869ab4d683dc5599eeb266899768ed13e6fe277fa7bdb8b4df9682e","src/connection_server.rs":"c96e347cbc53a6abb12ef86f548cac52526069884ee97d384aa91a1ae3cd43aa","src/control_stream_local.rs":"03d6259599543da2154388d5e48efbc06271e079429d3d946278c4c58c0521c7","src/control_stream_remote.rs":"121ac329dafc43efbfa3a0d26ab42b164d6a467523bc34193d03b7a0597ffd21","src/hframe.rs":"16bed02bec406f897ca847e0e2e060fa4e0e03d0397fab40e640c24679652228","src/hsettings_frame.rs":"f7cd5dc349c4e3d77b35effae620578492631cf33e7db9c93418a119b90cadc3","src/lib.rs":"fc76582370c384294d08e55f9e3d026ca2645b4418b1e989328f61d2f280ffff","src/push_controller.rs":"36e70602887fe685986cbe7960ec5270feda61b7f5a87474f585248fe13104fd","src/recv_message.rs":"d651428ed86cdea0f54102c3218eb4c7f99aac6fcad739b5538f6fb8fee9c918","src/send_message.rs":"4aa03879c64e9382fc8e6fcdda5c7674878e61a374e99af58139408eaf520c0f","src/server.rs":"b8e815be0e297aa422fe9067e2ff62c55e948258710b605ec82d4f8ea6b95698","src/server_connection_events.rs":"d95c9c441b278d9cc7577e5a2d8c1b00cf2e20f43a538d8c34db39629b415b01","src/server_events.rs":"27f23dc49f649fb66113c5a71345d9af30e7de04f791d4e1928d32c66b47d3f1","src/stream_type_reader.rs":"9eadcdf4ea223258f6a115c3c7e8c37228e4d7baee8eb8eb944175ed91a5cf36","tests/httpconn.rs":"32b5162ad8963a7079704858d537f9d7f3ba40d428620e5bc80fe1845908ce75"},"package":null}
{"files":{"Cargo.toml":"d89c7eef0ce63197af3c1a0cb1c0bba52b04b017358926ffcf9062106fc556f0","src/client_events.rs":"8c19986b7372b36d1265d4a848b07b5c334511cbdfc02f313c54e551523c08f5","src/connection.rs":"cebdb535151ec5598161091c6b709c38852aa32f32855cee8f2c6129a2bcb5a0","src/connection_client.rs":"017b4072ecb6604d223ef910f2dfbaa4caf84e439351bf4feed2a8a7a4869bf6","src/connection_server.rs":"c96e347cbc53a6abb12ef86f548cac52526069884ee97d384aa91a1ae3cd43aa","src/control_stream_local.rs":"03d6259599543da2154388d5e48efbc06271e079429d3d946278c4c58c0521c7","src/control_stream_remote.rs":"121ac329dafc43efbfa3a0d26ab42b164d6a467523bc34193d03b7a0597ffd21","src/hframe.rs":"16bed02bec406f897ca847e0e2e060fa4e0e03d0397fab40e640c24679652228","src/hsettings_frame.rs":"f7cd5dc349c4e3d77b35effae620578492631cf33e7db9c93418a119b90cadc3","src/lib.rs":"fc76582370c384294d08e55f9e3d026ca2645b4418b1e989328f61d2f280ffff","src/push_controller.rs":"36e70602887fe685986cbe7960ec5270feda61b7f5a87474f585248fe13104fd","src/recv_message.rs":"d651428ed86cdea0f54102c3218eb4c7f99aac6fcad739b5538f6fb8fee9c918","src/send_message.rs":"4aa03879c64e9382fc8e6fcdda5c7674878e61a374e99af58139408eaf520c0f","src/server.rs":"b8e815be0e297aa422fe9067e2ff62c55e948258710b605ec82d4f8ea6b95698","src/server_connection_events.rs":"d95c9c441b278d9cc7577e5a2d8c1b00cf2e20f43a538d8c34db39629b415b01","src/server_events.rs":"27f23dc49f649fb66113c5a71345d9af30e7de04f791d4e1928d32c66b47d3f1","src/stream_type_reader.rs":"9eadcdf4ea223258f6a115c3c7e8c37228e4d7baee8eb8eb944175ed91a5cf36","tests/httpconn.rs":"32b5162ad8963a7079704858d537f9d7f3ba40d428620e5bc80fe1845908ce75"},"package":null}

2
third_party/rust/neqo-http3/Cargo.toml поставляемый
Просмотреть файл

@ -1,6 +1,6 @@
[package]
name = "neqo-http3"
version = "0.4.0"
version = "0.4.1"
authors = ["Dragana Damjanovic <dragana.damjano@gmail.com>"]
edition = "2018"
license = "MIT/Apache-2.0"

Просмотреть файл

@ -19,8 +19,8 @@ use neqo_common::{
use neqo_crypto::{agent::CertificateInfo, AuthenticationStatus, SecretAgentInfo};
use neqo_qpack::QpackSettings;
use neqo_transport::{
AppError, Connection, ConnectionEvent, ConnectionIdManager, Output, StreamId, StreamType,
ZeroRttState,
AppError, Connection, ConnectionEvent, ConnectionIdManager, Output, QuicVersion, StreamId,
StreamType, ZeroRttState,
};
use std::cell::RefCell;
use std::fmt::Display;
@ -69,9 +69,17 @@ impl Http3Client {
local_addr: SocketAddr,
remote_addr: SocketAddr,
qpack_settings: QpackSettings,
quic_version: QuicVersion,
) -> Res<Self> {
Ok(Self::new_with_conn(
Connection::new_client(server_name, protocols, cid_manager, local_addr, remote_addr)?,
Connection::new_client(
server_name,
protocols,
cid_manager,
local_addr,
remote_addr,
quic_version,
)?,
qpack_settings,
))
}
@ -595,7 +603,10 @@ mod tests {
use neqo_common::{matches, Encoder};
use neqo_crypto::AntiReplay;
use neqo_qpack::encoder::QPackEncoder;
use neqo_transport::{CloseError, ConnectionEvent, FixedConnectionIdManager, State};
use neqo_transport::{
CloseError, ConnectionEvent, ConnectionIdManager, FixedConnectionIdManager, QuicVersion,
State,
};
use test_fixture::{
default_server, fixture_init, loopback, now, DEFAULT_ALPN, DEFAULT_SERVER_NAME,
};
@ -623,6 +634,7 @@ mod tests {
max_table_size_decoder: 100,
max_blocked_streams: 100,
},
QuicVersion::default(),
)
.expect("create a default client")
}
@ -2967,11 +2979,17 @@ mod tests {
// should result in the server rejecting 0-RTT.
let ar = AntiReplay::new(now(), test_fixture::ANTI_REPLAY_WINDOW, 1, 3)
.expect("setup anti-replay");
let mut cid_mgr = FixedConnectionIdManager::new(10);
let initial_source_cid = cid_mgr.generate_cid();
let mut server = Connection::new_server(
test_fixture::DEFAULT_KEYS,
test_fixture::DEFAULT_ALPN,
&ar,
Rc::new(RefCell::new(FixedConnectionIdManager::new(10))),
Rc::new(RefCell::new(cid_mgr)),
QuicVersion::default(),
initial_source_cid,
)
.unwrap();

Просмотреть файл

@ -1 +1 @@
{"files":{"Cargo.toml":"23a69b4d2c9d585cb41be938442a7003beb73dd75c4ede25151d7ecf9365fde9","src/decoder.rs":"468b51d03aee3363d7998bb9e8a70d998a8279eb0089702a9fe4423f8c577f1e","src/decoder_instructions.rs":"a8e04dff5fc4c658322a10daadab947dc2e41932c00c3f8d387671a86d0516af","src/encoder.rs":"03cc95df1c57972cd8a19ffb77920f8daac52b4e220eac6182d05671d04e9d58","src/encoder_instructions.rs":"4fab8d6a86482139275f81fd30f9f8c462d6312faf0cdb9143fed1a1a514623f","src/header_block.rs":"3be489222ba59d1c9022d9bf813330a5d68f994fd3fe92fe6934f796cbab42f2","src/huffman.rs":"68fa0bada0c35d20f793980596accdcc548970214841f71789290fc334e51fc1","src/huffman_decode_helper.rs":"089ab15eda49eae035c8ac95f780ec495713ce5918dd1e5a5e4a6206e3c65e66","src/huffman_table.rs":"06fea766a6276ac56c7ee0326faed800a742c15fda1f33bf2513e6cc6a5e6d27","src/lib.rs":"4413c57c8707c5fe47cdc4f40b6e2e9baa4f18fae9cecd895c11e509973ccc2a","src/prefix.rs":"8807126dbf4e7aff9afe164072c523b8fbfa0be5d4c57bb8291b510c8f0e8ca5","src/qlog.rs":"ee4eb799cadcd31e2569690ab1f7cbfb22179033ee7aec7ed217749eb0210fc9","src/qpack_send_buf.rs":"8c1b97d17220038c8e040edb5d5bfc39eb72ab50dfa325016e799740acc47558","src/reader.rs":"4bcea0de1d7dc09ec0cdff364d8f62da54bbbe1f6db55a495f943f31369b4074","src/static_table.rs":"fda9d5c6f38f94b0bf92d3afdf8432dce6e27e189736596e16727090c77b78ec","src/table.rs":"fc927a57c02a7556b0ea7152c713cfd84825b14343f809c7ed0cc2a2a011482f"},"package":null}
{"files":{"Cargo.toml":"fd88d05a2e011d4b5ca1145921572ed459695fa9d999239c2bdd2a5f3675fcc2","src/decoder.rs":"468b51d03aee3363d7998bb9e8a70d998a8279eb0089702a9fe4423f8c577f1e","src/decoder_instructions.rs":"a8e04dff5fc4c658322a10daadab947dc2e41932c00c3f8d387671a86d0516af","src/encoder.rs":"03cc95df1c57972cd8a19ffb77920f8daac52b4e220eac6182d05671d04e9d58","src/encoder_instructions.rs":"4fab8d6a86482139275f81fd30f9f8c462d6312faf0cdb9143fed1a1a514623f","src/header_block.rs":"3be489222ba59d1c9022d9bf813330a5d68f994fd3fe92fe6934f796cbab42f2","src/huffman.rs":"68fa0bada0c35d20f793980596accdcc548970214841f71789290fc334e51fc1","src/huffman_decode_helper.rs":"089ab15eda49eae035c8ac95f780ec495713ce5918dd1e5a5e4a6206e3c65e66","src/huffman_table.rs":"06fea766a6276ac56c7ee0326faed800a742c15fda1f33bf2513e6cc6a5e6d27","src/lib.rs":"4413c57c8707c5fe47cdc4f40b6e2e9baa4f18fae9cecd895c11e509973ccc2a","src/prefix.rs":"8807126dbf4e7aff9afe164072c523b8fbfa0be5d4c57bb8291b510c8f0e8ca5","src/qlog.rs":"ee4eb799cadcd31e2569690ab1f7cbfb22179033ee7aec7ed217749eb0210fc9","src/qpack_send_buf.rs":"8c1b97d17220038c8e040edb5d5bfc39eb72ab50dfa325016e799740acc47558","src/reader.rs":"4bcea0de1d7dc09ec0cdff364d8f62da54bbbe1f6db55a495f943f31369b4074","src/static_table.rs":"fda9d5c6f38f94b0bf92d3afdf8432dce6e27e189736596e16727090c77b78ec","src/table.rs":"fc927a57c02a7556b0ea7152c713cfd84825b14343f809c7ed0cc2a2a011482f"},"package":null}

2
third_party/rust/neqo-qpack/Cargo.toml поставляемый
Просмотреть файл

@ -1,6 +1,6 @@
[package]
name = "neqo-qpack"
version = "0.4.0"
version = "0.4.1"
authors = ["Dragana Damjanovic <dragana.damjano@gmail.com>"]
edition = "2018"
license = "MIT/Apache-2.0"

Просмотреть файл

@ -1 +1 @@
{"files":{"Cargo.toml":"0a1d4ce17ba9db0b2a0b55cded951ffb59a4e72298b1ac876adbfc799c07994a","TODO":"d759cb804b32fa9d96ea8d3574a3c4073da9fe6a0b02b708a0e22cce5a5b4a0f","src/cc.rs":"60d6de4376ba77801490a400a90078f93b5300aa24b16838b38a1bad805b784e","src/cid.rs":"54e0f9c330014d296450f80f51b7031eee674b250d4ce24193b6d785b1d27f4f","src/connection.rs":"410937048e364eccd993872950e80b3b65314a61c65e47cdcbbd03d7ffabcb73","src/crypto.rs":"d00318e169b9634ab241e1dad0ec83ecfb93f9944b44891c850108e73f81ccd2","src/dump.rs":"d69ccb0e3b240823b886a791186afbac9f2e26d1f1f67a55dbf86f8cd3e6203e","src/events.rs":"deee6ef1112034582af770212bb70ed2cdcd2b1b8bb167c9118ef39bbf454451","src/flow_mgr.rs":"0b1c6e7587e411635723207ecface6c62d1243599dd017745c61eb94805b9886","src/frame.rs":"5f08b061f8fb7c2cc809116c5638c64d72646d914c688648b39345b775bb0246","src/lib.rs":"70b1b384d538b0e14c1843077848d4a00619e1f8316c23cfb6ba7ec3cb02cee0","src/pace.rs":"2cbc141722d75c87e99eb4e35da1479c47d55d8945f6c252c221543720c283ae","src/packet.rs":"b621ff1521d223345ff54650d94184f54596089b5d34edcfa68b4aae64d6be52","src/path.rs":"140365a03b9e226c0b03a1c3dba6e5235829006168da055c78b69d26bd0c98c7","src/qlog.rs":"92fff8f49c817090a7dbe39060543c4c7a9e45863cf5a430abc2e124d9050d6f","src/recovery.rs":"93e58b57438803709a6468345124655fc3ccc96d13d6514c4fb3e702a15b6f56","src/recv_stream.rs":"0650949aa8baae9e20c57eb2283490b782c41e6c67e9c093fc358145149e386f","src/send_stream.rs":"cd834ebd4386a776d897b1a5e52cad839784e389da8e2543ba1fb57649225cbd","src/server.rs":"84340521f8d29d4e6f6de6af787ce0f4c640df871fad72364d18fb3721151dd9","src/stats.rs":"a276bd9902939091578d3bcc95aa7dd0b32f5d29e528c12e7b93a0ab88474478","src/stream_id.rs":"db11def2ed81ef7c456c7c47827121c0a9ff54ac85228e6db6c790db8944febe","src/tparams.rs":"3c419a9f0fb9cc7edf6ae5b63bab9ecb5abbca3663b4615b1df37447b425f610","src/tracking.rs":"965d0bffc4c6171833a1e3ccb3d7cc31242a0e9f3c5ff77f925aa3a6594b167f","tests/conn_vectors.rs":"3de474009e75e0d283792daae4cb0eac7a1be00a4a6cfab6132c775fbefb1363","tests/connection.rs":"a93985c199a9ef987106f4a20b35ebf803cdbbb855c07b1362b403eed7101ef8","tests/server.rs":"1daefe9fea17ab9f45c57b805d357538d115068e168dc4d6bfc46f71403a986f"},"package":null}
{"files":{"Cargo.toml":"0607e358f61d26baaca0fec7926a772ade4be70c19a63ac20d3a4c144b22ebb4","TODO":"d759cb804b32fa9d96ea8d3574a3c4073da9fe6a0b02b708a0e22cce5a5b4a0f","src/cc.rs":"60d6de4376ba77801490a400a90078f93b5300aa24b16838b38a1bad805b784e","src/cid.rs":"208b1c847d23892287be59869e48a699ef027a84c45832e89df525df0c165d00","src/connection.rs":"d8a7923002494a768f04371a47cdddcf86b434df5700ca6f288c46f351c4c704","src/crypto.rs":"d00318e169b9634ab241e1dad0ec83ecfb93f9944b44891c850108e73f81ccd2","src/dump.rs":"d69ccb0e3b240823b886a791186afbac9f2e26d1f1f67a55dbf86f8cd3e6203e","src/events.rs":"deee6ef1112034582af770212bb70ed2cdcd2b1b8bb167c9118ef39bbf454451","src/flow_mgr.rs":"0b1c6e7587e411635723207ecface6c62d1243599dd017745c61eb94805b9886","src/frame.rs":"5f08b061f8fb7c2cc809116c5638c64d72646d914c688648b39345b775bb0246","src/lib.rs":"57f1018f31dd26241a2048bf9475fd883cf5904c227264aa7ede3cfcf9ecde91","src/pace.rs":"2cbc141722d75c87e99eb4e35da1479c47d55d8945f6c252c221543720c283ae","src/packet.rs":"8cf2913a333f1a994476fb1b15911ea894ecaa93c64ea22eb9b05ee4fe97aaf0","src/path.rs":"2dffade2760f76141708c57765a8b9e53ac2eac02662a02e2cb0e6eef5e97922","src/qlog.rs":"29d7348914766153eaf8395806a51c1f7a2af6322e982ba49500d3982198caeb","src/recovery.rs":"93e58b57438803709a6468345124655fc3ccc96d13d6514c4fb3e702a15b6f56","src/recv_stream.rs":"0650949aa8baae9e20c57eb2283490b782c41e6c67e9c093fc358145149e386f","src/send_stream.rs":"cd834ebd4386a776d897b1a5e52cad839784e389da8e2543ba1fb57649225cbd","src/server.rs":"09656965611aefa5ef277b113126fe20f958e91f331403d327dbdf2651468101","src/stats.rs":"a276bd9902939091578d3bcc95aa7dd0b32f5d29e528c12e7b93a0ab88474478","src/stream_id.rs":"db11def2ed81ef7c456c7c47827121c0a9ff54ac85228e6db6c790db8944febe","src/tparams.rs":"dae3d882156bb0842a946f7f03fa908536ee531d03e6725c1d845446a5d2e393","src/tracking.rs":"965d0bffc4c6171833a1e3ccb3d7cc31242a0e9f3c5ff77f925aa3a6594b167f","tests/conn_vectors.rs":"3de474009e75e0d283792daae4cb0eac7a1be00a4a6cfab6132c775fbefb1363","tests/connection.rs":"a93985c199a9ef987106f4a20b35ebf803cdbbb855c07b1362b403eed7101ef8","tests/server.rs":"9a8ba031ee547327e1423fa1441af840dd7cc0b4705c42a735dc7e12aef2e137"},"package":null}

2
third_party/rust/neqo-transport/Cargo.toml поставляемый
Просмотреть файл

@ -1,6 +1,6 @@
[package]
name = "neqo-transport"
version = "0.4.0"
version = "0.4.1"
authors = ["EKR <ekr@rtfm.com>", "Andy Grover <agrover@mozilla.com>"]
edition = "2018"
license = "MIT/Apache-2.0"

9
third_party/rust/neqo-transport/src/cid.rs поставляемый
Просмотреть файл

@ -11,6 +11,7 @@ use neqo_crypto::random;
use std::borrow::Borrow;
use std::cmp::max;
use std::convert::AsRef;
pub const MAX_CONNECTION_ID_LEN: usize = 20;
@ -33,11 +34,17 @@ impl ConnectionId {
Self::generate(len)
}
pub fn as_ref(&self) -> ConnectionIdRef {
pub fn as_cid_ref(&self) -> ConnectionIdRef {
ConnectionIdRef::from(&self.cid[..])
}
}
impl AsRef<[u8]> for ConnectionId {
fn as_ref(&self) -> &[u8] {
self.borrow()
}
}
impl Borrow<[u8]> for ConnectionId {
fn borrow(&self) -> &[u8] {
&self.cid

Просмотреть файл

@ -19,8 +19,8 @@ use std::time::{Duration, Instant};
use smallvec::SmallVec;
use neqo_common::{
hex, matches, qdebug, qerror, qinfo, qlog::NeqoQlog, qtrace, qwarn, Datagram, Decoder, Encoder,
Role,
hex, hex_snip_middle, matches, qdebug, qerror, qinfo, qlog::NeqoQlog, qtrace, qwarn, Datagram,
Decoder, Encoder, Role,
};
use neqo_crypto::agent::CertificateInfo;
use neqo_crypto::{
@ -37,7 +37,9 @@ use crate::frame::{
AckRange, CloseError, Frame, FrameType, StreamType, FRAME_TYPE_CONNECTION_CLOSE_APPLICATION,
FRAME_TYPE_CONNECTION_CLOSE_TRANSPORT,
};
use crate::packet::{DecryptedPacket, PacketBuilder, PacketNumber, PacketType, PublicPacket};
use crate::packet::{
DecryptedPacket, PacketBuilder, PacketNumber, PacketType, PublicPacket, QuicVersion,
};
use crate::path::Path;
use crate::qlog;
use crate::recovery::{LossRecovery, RecoveryToken, SendProfile, GRANULARITY};
@ -209,14 +211,14 @@ impl ConnectionIdManager for FixedConnectionIdManager {
struct RetryInfo {
token: Vec<u8>,
odcid: ConnectionId,
retry_source_cid: ConnectionId,
}
impl RetryInfo {
fn new(odcid: ConnectionId) -> Self {
fn new(retry_source_cid: ConnectionId, token: Vec<u8>) -> Self {
Self {
token: Vec::new(),
odcid,
token,
retry_source_cid,
}
}
}
@ -285,13 +287,14 @@ impl IdleTimeout {
}
}
/// StateManagement manages whether we need to send HANDSHAKE_DONE and CONNECTION_CLOSE.
/// `StateSignaling` manages whether we need to send HANDSHAKE_DONE and CONNECTION_CLOSE.
/// Valid state transitions are:
/// * Idle -> HandshakeDone: at the server when the handshake completes
/// * HandshakeDone -> Idle: when a HANDSHAKE_DONE frame is sent
/// * Idle/HandshakeDone -> Closing/Draining: when closing or draining
/// * Closing/Draining -> CloseSent: after sending CONNECTION_CLOSE
/// * CloseSent -> Closing: any time a new CONNECTION_CLOSE is needed
/// * -> Reset: from any state in case of a stateless reset
#[derive(Debug, Clone, PartialEq)]
enum StateSignaling {
Idle,
@ -302,6 +305,7 @@ enum StateSignaling {
/// This state saves the frame that might need to be sent again.
/// If it is `None`, then we are draining and don't send.
CloseSent(Option<Frame>),
Reset,
}
impl StateSignaling {
@ -341,7 +345,9 @@ impl StateSignaling {
frame_type: FrameType,
message: impl AsRef<str>,
) {
*self = Self::Closing(Self::make_close_frame(error, frame_type, message));
if *self != Self::Reset {
*self = Self::Closing(Self::make_close_frame(error, frame_type, message));
}
}
pub fn drain(
@ -350,7 +356,9 @@ impl StateSignaling {
frame_type: FrameType,
message: impl AsRef<str>,
) {
*self = Self::Draining(Self::make_close_frame(error, frame_type, message));
if *self != Self::Reset {
*self = Self::Draining(Self::make_close_frame(error, frame_type, message));
}
}
/// If a close is pending, take a frame.
@ -379,6 +387,11 @@ impl StateSignaling {
*self = Self::Closing(frame);
}
}
/// We just got a stateless reset. Terminate.
pub fn reset(&mut self) {
*self = Self::Reset;
}
}
/// A QUIC Connection
@ -411,6 +424,15 @@ pub struct Connection {
/// During the handshake at the server, it also includes the randomized DCID pick by the client.
valid_cids: Vec<ConnectionId>,
retry_info: Option<RetryInfo>,
/// Since we need to communicate this to our peer in tparams, setting this
/// value is part of constructing the struct.
local_initial_source_cid: ConnectionId,
/// Checked against tparam value from peer
remote_initial_source_cid: Option<ConnectionId>,
/// Checked against tparam value from peer
remote_original_destination_cid: Option<ConnectionId>,
pub(crate) crypto: Crypto,
pub(crate) acks: AckTracker,
idle_timeout: IdleTimeout,
@ -425,6 +447,8 @@ pub struct Connection {
token: Option<Vec<u8>>,
stats: Stats,
qlog: Option<NeqoQlog>,
quic_version: QuicVersion,
}
impl Debug for Connection {
@ -445,6 +469,7 @@ impl Connection {
cid_manager: CidMgr,
local_addr: SocketAddr,
remote_addr: SocketAddr,
quic_version: QuicVersion,
) -> Res<Self> {
let dcid = ConnectionId::generate_initial();
let scid = cid_manager.borrow_mut().generate_cid();
@ -454,10 +479,17 @@ impl Connection {
cid_manager,
None,
protocols,
Some(Path::new(local_addr, remote_addr, scid, dcid.clone())),
);
Some(Path::new(
local_addr,
remote_addr,
scid.clone(),
dcid.clone(),
)),
quic_version,
scid,
)?;
c.crypto.states.init(Role::Client, &dcid);
c.retry_info = Some(RetryInfo::new(dcid));
c.remote_original_destination_cid = Some(dcid);
Ok(c)
}
@ -467,15 +499,19 @@ impl Connection {
protocols: &[impl AsRef<str>],
anti_replay: &AntiReplay,
cid_manager: CidMgr,
quic_version: QuicVersion,
local_initial_source_cid: ConnectionId,
) -> Res<Self> {
Ok(Self::new(
Self::new(
Role::Server,
Server::new(certs)?.into(),
cid_manager,
Some(anti_replay),
protocols,
None,
))
quic_version,
local_initial_source_cid,
)
}
fn set_tp_defaults(tps: &mut TransportParameters) {
@ -498,6 +534,7 @@ impl Connection {
tps.set_empty(tparams::DISABLE_MIGRATION);
}
#[allow(clippy::too_many_arguments)]
fn new(
role: Role,
agent: Agent,
@ -505,13 +542,19 @@ impl Connection {
anti_replay: Option<&AntiReplay>,
protocols: &[impl AsRef<str>],
path: Option<Path>,
) -> Self {
quic_version: QuicVersion,
local_initial_source_cid: ConnectionId,
) -> Res<Self> {
let tphandler = Rc::new(RefCell::new(TransportParametersHandler::default()));
Self::set_tp_defaults(&mut tphandler.borrow_mut().local);
let crypto = Crypto::new(agent, protocols, tphandler.clone(), anti_replay)
.expect("TLS should be configured successfully");
tphandler.borrow_mut().local.set_bytes(
tparams::INITIAL_SOURCE_CONNECTION_ID,
local_initial_source_cid.to_vec(),
);
Self {
let crypto = Crypto::new(agent, protocols, tphandler.clone(), anti_replay)?;
Ok(Self {
role,
state: State::Init,
cid_manager,
@ -520,6 +563,9 @@ impl Connection {
tps: tphandler,
zero_rtt_state: ZeroRttState::Init,
retry_info: None,
local_initial_source_cid,
remote_initial_source_cid: None,
remote_original_destination_cid: None,
crypto,
acks: AckTracker::default(),
idle_timeout: IdleTimeout::default(),
@ -534,7 +580,8 @@ impl Connection {
token: None,
stats: Stats::default(),
qlog: None,
}
quic_version,
})
}
/// Get the local path.
@ -564,13 +611,25 @@ impl Connection {
}
}
/// Set the connection ID that was originally chosen by the client.
pub(crate) fn original_connection_id(&mut self, odcid: &ConnectionId) {
/// Set the dest connection ID that was originally chosen by the client.
pub(crate) fn set_original_destination_cid(&mut self, odcid: ConnectionId) {
assert_eq!(self.role, Role::Server);
qtrace!([self], "Called set_original_destination_cid {}", odcid);
self.tps
.borrow_mut()
.local
.set_bytes(tparams::ORIGINAL_CONNECTION_ID, odcid.to_vec());
.set_bytes(tparams::ORIGINAL_DESTINATION_CONNECTION_ID, odcid.to_vec());
self.remote_original_destination_cid = Some(odcid);
}
/// Set the connection ID that was sent in retry.
pub(crate) fn set_retry_source_cid(&mut self, retry_source_cid: ConnectionId) {
assert_eq!(self.role, Role::Server);
qtrace!([self], "Called set_retry_source_cid {}", retry_source_cid);
self.tps.borrow_mut().local.set_bytes(
tparams::RETRY_SOURCE_CONNECTION_ID,
retry_source_cid.to_vec(),
);
}
/// Set ALPN preferences. Strings that appear earlier in the list are given
@ -612,7 +671,7 @@ impl Connection {
.encode(enc_inner);
});
enc.encode(&t[..]);
qinfo!("resumption token {}", hex(&enc[..]));
qinfo!("resumption token {}", hex_snip_middle(&enc[..]));
Some(enc.into())
}
None => None,
@ -630,7 +689,7 @@ impl Connection {
qerror!([self], "set token in state {:?}", self.state);
return Err(Error::ConnectionState);
}
qinfo!([self], "resumption token {}", hex(token));
qinfo!([self], "resumption token {}", hex_snip_middle(token));
let mut dec = Decoder::from(token);
let smoothed_rtt = match dec.decode_varint() {
@ -791,8 +850,8 @@ impl Connection {
/// Call in to process activity on the connection. Either new packets have
/// arrived or a timeout has expired (or both).
pub fn process_input(&mut self, dgram: Datagram, now: Instant) {
let res = self.input(dgram, now);
pub fn process_input(&mut self, d: Datagram, now: Instant) {
let res = self.input(d, now);
self.absorb_error(now, res);
self.cleanup_streams();
}
@ -899,9 +958,8 @@ impl Connection {
}
fn handle_retry(&mut self, packet: PublicPacket) -> Res<()> {
qdebug!([self], "received Retry");
debug_assert!(self.retry_info.is_some());
if !self.retry_info.as_ref().unwrap().token.is_empty() {
qinfo!([self], "received Retry");
if self.retry_info.is_some() {
qinfo!([self], "Dropping extra Retry");
self.stats.dropped_rx += 1;
return Ok(());
@ -911,7 +969,7 @@ impl Connection {
self.stats.dropped_rx += 1;
return Ok(());
}
if !packet.is_valid_retry(&self.retry_info.as_ref().unwrap().odcid) {
if !packet.is_valid_retry(&self.remote_original_destination_cid.as_ref().unwrap()) {
qinfo!([self], "Dropping Retry with bad integrity tag");
self.stats.dropped_rx += 1;
return Ok(());
@ -923,12 +981,19 @@ impl Connection {
qinfo!([self], "No path, but we received a Retry");
return Err(Error::InternalError);
};
self.retry_info.as_mut().unwrap().token = packet.token().to_vec();
qinfo!(
[self],
"Valid Retry received, token={}",
hex(packet.token())
"Valid Retry received, token={} scid={}",
hex(packet.token()),
packet.scid()
);
self.retry_info = Some(RetryInfo::new(
ConnectionId::from(packet.scid()),
packet.token().to_vec(),
));
let lost_packets = self.loss_recovery.retry();
self.handle_lost_packets(&lost_packets);
@ -946,6 +1011,45 @@ impl Connection {
}
}
fn token_equal(a: &[u8; 16], b: &[u8; 16]) -> bool {
// rustc might decide to optimize this and make this non-constant-time
// with respect to `t`, but it doesn't appear to currently.
let mut c = 0;
for (&a, &b) in a.iter().zip(b) {
c |= a ^ b;
}
c == 0
}
fn is_stateless_reset(&self, d: &Datagram) -> bool {
if d.len() < 16 {
return false;
}
let token = <&[u8; 16]>::try_from(&d[d.len() - 16..]).unwrap();
// TODO(mt) only check the path that matches the datagram.
self.path
.as_ref()
.map(|p| p.reset_token())
.flatten()
.map_or(false, |t| Self::token_equal(t, token))
}
fn check_stateless_reset(&mut self, d: &Datagram, now: Instant) -> Res<()> {
if self.is_stateless_reset(d) {
// Failing to process a packet in a datagram might
// indicate that there is a stateless reset present.
qdebug!([self], "Stateless reset: {}", hex(&d[d.len() - 16..]));
self.state_signaling.reset();
self.set_state(State::Draining {
error: ConnectionError::Transport(Error::StatelessReset),
timeout: self.get_closing_period_time(now),
});
Err(Error::StatelessReset)
} else {
Ok(())
}
}
fn input(&mut self, d: Datagram, now: Instant) -> Res<Vec<(Frame, PNSpace)>> {
let mut slc = &d[..];
let mut frames = Vec::new();
@ -958,22 +1062,33 @@ impl Connection {
match PublicPacket::decode(slc, self.cid_manager.borrow().as_decoder()) {
Ok((packet, remainder)) => (packet, remainder),
Err(e) => {
qdebug!([self], "Garbage packet: {} {}", e, hex(slc));
qdebug!([self], "Garbage packet: {}", e);
qtrace!([self], "Garbage packet contents: {}", hex(slc));
self.stats.dropped_rx += 1;
return Ok(frames);
break;
}
}; // TODO(mt) use in place of res, and allow errors
};
self.stats.packets_rx += 1;
match (packet.packet_type(), &self.state, &self.role) {
(PacketType::Initial, State::Init, Role::Server) => {
if !packet.is_valid_initial() {
self.stats.dropped_rx += 1;
return Ok(frames);
break;
}
qinfo!([self], "Received valid Initial packet");
qinfo!(
[self],
"Received valid Initial packet with scid {:?} dcid {:?}",
packet.scid(),
packet.dcid()
);
self.set_state(State::WaitInitial);
self.loss_recovery.start_pacer(now);
self.crypto.states.init(self.role, &packet.dcid());
self.remote_initial_source_cid = Some(ConnectionId::from(packet.scid()));
if self.remote_original_destination_cid.is_none() {
self.set_original_destination_cid(ConnectionId::from(packet.dcid()));
}
}
(PacketType::VersionNegotiation, State::WaitInitial, Role::Client) => {
self.set_state(State::Closed(ConnectionError::Transport(
@ -983,14 +1098,14 @@ impl Connection {
}
(PacketType::Retry, State::WaitInitial, Role::Client) => {
self.handle_retry(packet)?;
return Ok(frames);
break;
}
(PacketType::VersionNegotiation, ..)
| (PacketType::Retry, ..)
| (PacketType::OtherVersion, ..) => {
qwarn!("dropping {:?}", packet.packet_type());
self.stats.dropped_rx += 1;
return Ok(frames);
break;
}
_ => {}
};
@ -999,14 +1114,14 @@ impl Connection {
State::Init => {
qinfo!([self], "Received message while in Init state");
self.stats.dropped_rx += 1;
return Ok(frames);
break;
}
State::WaitInitial => {}
State::Handshaking | State::Connected | State::Confirmed => {
if !self.is_valid_cid(packet.dcid()) {
qinfo!([self], "Ignoring packet with CID {:?}", packet.dcid());
self.stats.dropped_rx += 1;
return Ok(frames);
break;
}
if self.role == Role::Server && packet.packet_type() == PacketType::Handshake {
// Server has received a Handshake packet -> discard Initial keys and states
@ -1017,12 +1132,12 @@ impl Connection {
// Don't bother processing the packet. Instead ask to get a
// new close frame.
self.state_signaling.send_close();
return Ok(frames);
break;
}
State::Draining { .. } | State::Closed(..) => {
// Do nothing.
self.stats.dropped_rx += 1;
return Ok(frames);
break;
}
}
@ -1030,7 +1145,6 @@ impl Connection {
let pto = self.loss_recovery.pto();
let payload = packet.decrypt(&mut self.crypto.states, now + pto);
slc = remainder;
if let Ok(payload) = payload {
// TODO(ekr@rtfm.com): Have the server blow away the initial
// crypto state if this fails? Otherwise, we will get a panic
@ -1059,7 +1173,14 @@ impl Connection {
// If the state isn't available, or we can't decrypt the packet, drop
// the rest of the datagram on the floor, but don't generate an error.
self.stats.dropped_rx += 1;
if slc.len() == d.len() {
self.check_stateless_reset(&d, now)?
}
}
slc = remainder;
}
if slc.len() == d.len() {
self.check_stateless_reset(&d, now)?
}
Ok(frames)
}
@ -1122,7 +1243,7 @@ impl Connection {
fn initialize_path(&mut self, packet: &PublicPacket, d: &Datagram) {
debug_assert!(self.path.is_none());
let mut p = Path::from_datagram(&d, ConnectionId::from(packet.scid()));
p.add_local_cid(self.cid_manager.borrow_mut().generate_cid());
p.add_local_cid(self.local_initial_source_cid.clone());
self.path = Some(p);
}
@ -1131,6 +1252,7 @@ impl Connection {
assert_eq!(packet.packet_type(), PacketType::Initial);
// A server needs to accept the client's selected CID during the handshake.
self.valid_cids.push(ConnectionId::from(packet.dcid()));
// Install a path.
self.initialize_path(packet, d);
@ -1149,6 +1271,7 @@ impl Connection {
.find(|p| p.received_on(&d))
.expect("should have a path for sending Initial");
p.set_remote_cid(packet.scid());
self.remote_initial_source_cid = Some(ConnectionId::from(packet.scid()));
}
self.set_state(State::Handshaking);
Ok(())
@ -1195,6 +1318,7 @@ impl Connection {
encoder: Encoder,
tx: &CryptoDxState,
retry_info: &Option<RetryInfo>,
quic_version: QuicVersion,
) -> (PacketType, PacketNumber, PacketBuilder) {
let pt = match space {
PNSpace::Initial => PacketType::Initial,
@ -1218,7 +1342,13 @@ impl Connection {
path.local_cid(),
);
PacketBuilder::long(encoder, pt, path.remote_cid(), path.local_cid())
PacketBuilder::long(
encoder,
pt,
quic_version,
path.remote_cid(),
path.local_cid(),
)
};
if pt == PacketType::Initial {
builder.initial_token(if let Some(info) = retry_info {
@ -1247,7 +1377,8 @@ impl Connection {
continue;
}
let (_, _, mut builder) = Self::build_packet_header(path, *space, encoder, tx, &None);
let (_, _, mut builder) =
Self::build_packet_header(path, *space, encoder, tx, &None, self.quic_version);
// ConnectionError::Application is only allowed at 1RTT.
if *space == PNSpace::ApplicationData {
frame.marshal(&mut builder);
@ -1339,8 +1470,14 @@ impl Connection {
};
let header_start = encoder.len();
let (pt, pn, mut builder) =
Self::build_packet_header(path, *space, encoder, tx, &self.retry_info);
let (pt, pn, mut builder) = Self::build_packet_header(
path,
*space,
encoder,
tx,
&self.retry_info,
self.quic_version,
);
let payload_start = builder.len();
// Work out if we have space left.
@ -1486,28 +1623,142 @@ impl Connection {
}
}
fn validate_odcid(&mut self) -> Res<()> {
// Here we drop our Retry state then validate it.
if let Some(info) = self.retry_info.take() {
if info.token.is_empty() {
Ok(())
} else {
let tph = self.tps.borrow();
let tp = tph.remote().get_bytes(tparams::ORIGINAL_CONNECTION_ID);
if let Some(odcid_tp) = tp {
if odcid_tp[..] == info.odcid[..] {
Ok(())
} else {
Err(Error::InvalidRetry)
}
} else {
Err(Error::InvalidRetry)
/// Process the final set of transport parameters.
fn process_tps(&mut self) -> Res<()> {
self.validate_cids()?;
if let Some(token) = self
.tps
.borrow()
.remote
.as_ref()
.unwrap()
.get_bytes(tparams::STATELESS_RESET_TOKEN)
{
let reset_token = <[u8; 16]>::try_from(token).unwrap().to_owned();
self.path.as_mut().unwrap().set_reset_token(reset_token);
}
self.set_initial_limits();
Ok(())
}
fn validate_cids(&mut self) -> Res<()> {
match self.quic_version {
QuicVersion::Draft27 => self.validate_cids_draft_27(),
_ => self.validate_cids_draft_28_plus(),
}
}
fn validate_cids_draft_27(&mut self) -> Res<()> {
if let Some(info) = &self.retry_info {
debug_assert!(!info.token.is_empty());
let tph = self.tps.borrow();
let tp = tph
.remote()
.get_bytes(tparams::ORIGINAL_DESTINATION_CONNECTION_ID);
if self
.remote_original_destination_cid
.as_ref()
.map(ConnectionId::as_cid_ref)
!= tp.map(ConnectionIdRef::from)
{
return Err(Error::InvalidRetry);
}
}
Ok(())
}
fn validate_cids_draft_28_plus(&mut self) -> Res<()> {
let tph = self.tps.borrow();
let remote_tps = tph.remote.as_ref().unwrap();
let tp = remote_tps.get_bytes(tparams::INITIAL_SOURCE_CONNECTION_ID);
match tp {
None => {
qwarn!(
"{} ISCID test failed: ISCID not found in tparams",
self.role
);
return Err(Error::ProtocolViolation);
}
Some(tp) => {
if self
.remote_initial_source_cid
.as_ref()
.unwrap()
.as_cid_ref()
!= ConnectionIdRef::from(tp)
{
qwarn!(
"{} ISCID test failed: self cid {:?} != tp cid {}",
self.role,
self.remote_initial_source_cid,
hex(&tp)
);
return Err(Error::ProtocolViolation);
}
}
} else {
debug_assert_eq!(self.role, Role::Server);
Ok(())
}
if self.role == Role::Client {
let tp = remote_tps.get_bytes(tparams::ORIGINAL_DESTINATION_CONNECTION_ID);
match tp {
None => {
qwarn!(
"{} ODCID test failed: ODCID not found in tparams",
self.role
);
return Err(Error::ProtocolViolation);
}
Some(tp) => {
if self
.remote_original_destination_cid
.as_ref()
.map(ConnectionId::as_cid_ref)
!= Some(ConnectionIdRef::from(tp))
{
qwarn!(
"{} ODCID test failed: self cid {:?} != tp cid {}",
self.role,
self.remote_original_destination_cid,
hex(&tp)
);
return Err(Error::ProtocolViolation);
}
}
}
let tp = remote_tps.get_bytes(tparams::RETRY_SOURCE_CONNECTION_ID);
match (&tp, &self.retry_info) {
(None, None) => {}
(None, Some(_ri)) => {
qwarn!(
"{} RSCID test failed: RSCID not found in tparams",
self.role
);
return Err(Error::ProtocolViolation);
}
(Some(_tp), None) => {
qwarn!(
"{} RSCID test failed: tparam found but no retry packet received",
self.role
);
return Err(Error::ProtocolViolation);
}
(Some(tp), Some(ri)) => {
if **tp != *ri.retry_source_cid {
qwarn!(
"{} RSCID test failed. self cid {:?} != tp cid {}",
self.role,
ri.retry_source_cid,
hex(&**tp),
);
return Err(Error::ProtocolViolation);
}
}
}
}
Ok(())
}
fn handshake(&mut self, now: Instant, space: PNSpace, data: Option<&[u8]>) -> Res<()> {
@ -1860,8 +2111,7 @@ impl Connection {
// Setting application keys has to occur after 0-RTT rejection.
let pto = self.loss_recovery.pto();
self.crypto.install_application_keys(now + pto)?;
self.validate_odcid()?;
self.set_initial_limits();
self.process_tps()?;
self.set_state(State::Connected);
if self.role == Role::Server {
self.state_signaling.handshake_done();
@ -2286,16 +2536,23 @@ mod tests {
Rc::new(RefCell::new(FixedConnectionIdManager::new(3))),
loopback(),
loopback(),
QuicVersion::default(),
)
.expect("create a default client")
}
pub fn default_server() -> Connection {
fixture_init();
let mut cid_mgr = FixedConnectionIdManager::new(5);
let local_initial_source_cid = cid_mgr.generate_cid();
Connection::new_server(
test_fixture::DEFAULT_KEYS,
test_fixture::DEFAULT_ALPN,
&test_fixture::anti_replay(),
Rc::new(RefCell::new(FixedConnectionIdManager::new(5))),
Rc::new(RefCell::new(cid_mgr)),
QuicVersion::default(),
local_initial_source_cid,
)
.expect("create a default server")
}
@ -2627,6 +2884,7 @@ mod tests {
Rc::new(RefCell::new(FixedConnectionIdManager::new(9))),
loopback(),
loopback(),
QuicVersion::default(),
)
.unwrap();
let mut server = default_server();
@ -2878,11 +3136,17 @@ mod tests {
// should result in the server rejecting 0-RTT.
let ar = AntiReplay::new(now(), test_fixture::ANTI_REPLAY_WINDOW, 1, 3)
.expect("setup anti-replay");
let mut cid_mgr = FixedConnectionIdManager::new(10);
let local_initial_source_cid = cid_mgr.generate_cid();
let mut server = Connection::new_server(
test_fixture::DEFAULT_KEYS,
test_fixture::DEFAULT_ALPN,
&ar,
Rc::new(RefCell::new(FixedConnectionIdManager::new(10))),
Rc::new(RefCell::new(cid_mgr)),
QuicVersion::default(),
local_initial_source_cid,
)
.unwrap();
@ -3235,11 +3499,17 @@ mod tests {
#[test]
fn test_crypto_frame_split() {
let mut client = default_client();
let mut cid_mgr = FixedConnectionIdManager::new(6);
let local_initial_source_cid = cid_mgr.generate_cid();
let mut server = Connection::new_server(
test_fixture::LONG_CERT_KEYS,
test_fixture::DEFAULT_ALPN,
&test_fixture::anti_replay(),
Rc::new(RefCell::new(FixedConnectionIdManager::new(6))),
Rc::new(RefCell::new(cid_mgr)),
QuicVersion::default(),
local_initial_source_cid,
)
.expect("create a server");
@ -5083,4 +5353,21 @@ mod tests {
);
assert_eq!(1, client.stats().dropped_rx);
}
/// Test that a client can handle a stateless reset correctly.
#[test]
fn stateless_reset_client() {
let mut client = default_client();
let mut server = default_server();
server
.set_local_tparam(
tparams::STATELESS_RESET_TOKEN,
TransportParameter::Bytes(vec![77; 16]),
)
.unwrap();
connect_force_idle(&mut client, &mut server);
client.process_input(Datagram::new(loopback(), loopback(), vec![77; 21]), now());
assert!(matches!(client.state(), State::Draining { .. }));
}
}

7
third_party/rust/neqo-transport/src/lib.rs поставляемый
Просмотреть файл

@ -35,12 +35,9 @@ pub use self::connection::{Connection, FixedConnectionIdManager, Output, State,
pub use self::events::{ConnectionEvent, ConnectionEvents};
pub use self::frame::CloseError;
pub use self::frame::StreamType;
pub use self::packet::QuicVersion;
pub use self::stream_id::StreamId;
/// The supported version of the QUIC protocol.
pub type Version = u32;
pub const QUIC_VERSION: Version = 0xff00_0000 + 27;
const LOCAL_IDLE_TIMEOUT: std::time::Duration = std::time::Duration::from_secs(30); // 30 second
type TransportError = u64;
@ -89,12 +86,12 @@ pub enum Error {
PacketNumberOverlap,
PeerApplicationError(AppError),
PeerError(TransportError),
StatelessReset,
TooMuchData,
UnexpectedMessage,
UnknownFrameType,
VersionNegotiation,
WrongRole,
KeysDiscarded,
}
impl Error {

133
third_party/rust/neqo-transport/src/packet.rs поставляемый
Просмотреть файл

@ -8,7 +8,7 @@
use crate::cid::{ConnectionId, ConnectionIdDecoder, ConnectionIdRef, MAX_CONNECTION_ID_LEN};
use crate::crypto::{CryptoDxState, CryptoStates};
use crate::tracking::PNSpace;
use crate::{Error, Res, Version, QUIC_VERSION};
use crate::{Error, Res};
use neqo_common::{hex, hex_with_len, qerror, qtrace, Decoder, Encoder};
use neqo_crypto::{aead::Aead, hkdf, random, TLS_AES_128_GCM_SHA256, TLS_VERSION_1_3};
@ -37,6 +37,7 @@ const SAMPLE_SIZE: usize = 16;
const SAMPLE_OFFSET: usize = 4;
pub type PacketNumber = u64;
type Version = u32;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum PacketType {
@ -62,6 +63,41 @@ impl PacketType {
}
}
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum QuicVersion {
Draft27,
Draft28,
}
impl QuicVersion {
pub fn as_u32(self) -> Version {
match self {
Self::Draft27 => 0xff00_0000 + 27,
Self::Draft28 => 0xff00_0000 + 28,
}
}
}
impl Default for QuicVersion {
fn default() -> Self {
Self::Draft28
}
}
impl TryFrom<Version> for QuicVersion {
type Error = Error;
fn try_from(ver: Version) -> Res<Self> {
if ver == 0xff00_0000 + 27 {
Ok(Self::Draft27)
} else if ver == 0xff00_0000 + 28 {
Ok(Self::Draft28)
} else {
Err(Error::VersionNegotiation)
}
}
}
/// The AEAD used for Retry is fixed, so use this.
fn make_retry_aead() -> Aead {
#[cfg(debug_assertions)]
@ -131,12 +167,13 @@ impl PacketBuilder {
pub fn long(
mut encoder: Encoder,
pt: PacketType,
quic_version: QuicVersion,
dcid: &ConnectionId,
scid: &ConnectionId,
) -> Self {
let header_start = encoder.len();
encoder.encode_byte(PACKET_BIT_LONG | PACKET_BIT_FIXED_QUIC | pt.code() << 4);
encoder.encode_uint(4, QUIC_VERSION);
encoder.encode_uint(4, quic_version.as_u32());
encoder.encode_vec(1, dcid);
encoder.encode_vec(1, scid);
Self {
@ -239,7 +276,13 @@ impl PacketBuilder {
/// As this is a simple packet, this is just an associated function.
/// As Retry is odd (it has to be constructed with leading bytes),
/// this returns a Vec<u8> rather than building on an encoder.
pub fn retry(dcid: &[u8], scid: &[u8], token: &[u8], odcid: &[u8]) -> Res<Vec<u8>> {
pub fn retry(
quic_version: QuicVersion,
dcid: &[u8],
scid: &[u8],
token: &[u8],
odcid: &[u8],
) -> Res<Vec<u8>> {
let mut encoder = Encoder::default();
encoder.encode_vec(1, odcid);
let start = encoder.len();
@ -249,7 +292,7 @@ impl PacketBuilder {
| (PACKET_TYPE_RETRY << 4)
| (random(1)[0] & 0xf),
);
encoder.encode_uint(4, QUIC_VERSION);
encoder.encode_uint(4, quic_version.as_u32());
encoder.encode_vec(1, dcid);
encoder.encode_vec(1, scid);
debug_assert_ne!(token.len(), 0);
@ -277,7 +320,8 @@ impl PacketBuilder {
encoder.encode(&[0; 4]); // Zero version == VN.
encoder.encode_vec(1, dcid);
encoder.encode_vec(1, scid);
encoder.encode_uint(4, QUIC_VERSION);
encoder.encode_uint(4, QuicVersion::Draft27.as_u32());
encoder.encode_uint(4, QuicVersion::Draft28.as_u32());
// Add a greased version, using the randomness already generated.
for g in &mut grease[..4] {
*g = *g & 0xf0 | 0x0a;
@ -321,6 +365,8 @@ pub struct PublicPacket<'a> {
token: &'a [u8],
/// The size of the header, not including the packet number.
header_len: usize,
/// Protocol version, if present in header.
quic_version: Option<QuicVersion>,
/// A reference to the entire packet, including the header.
data: &'a [u8],
}
@ -382,6 +428,7 @@ impl<'a> PublicPacket<'a> {
scid: None,
token: &[],
header_len,
quic_version: None,
data,
},
&[],
@ -405,14 +452,17 @@ impl<'a> PublicPacket<'a> {
scid: Some(scid),
token: &[],
header_len: decoder.offset(),
quic_version: None,
data,
},
&[],
));
}
// Check that this is a long header from this version.
if version != QUIC_VERSION {
// Check that this is a long header from a supported version.
let quic_version = if let Ok(v) = QuicVersion::try_from(version) {
v
} else {
return Ok((
Self {
packet_type: PacketType::OtherVersion,
@ -420,11 +470,13 @@ impl<'a> PublicPacket<'a> {
scid: Some(scid),
token: &[],
header_len: decoder.offset(),
quic_version: None,
data,
},
&[],
));
}
};
if (first & PACKET_BIT_FIXED_QUIC) != PACKET_BIT_FIXED_QUIC {
return Err(Error::InvalidPacket);
}
@ -450,6 +502,7 @@ impl<'a> PublicPacket<'a> {
scid: Some(scid),
token,
header_len,
quic_version: Some(quic_version),
data,
},
remainder,
@ -509,6 +562,10 @@ impl<'a> PublicPacket<'a> {
self.token
}
pub fn version(&self) -> Option<QuicVersion> {
self.quic_version
}
fn decode_pn(expected: PacketNumber, pn: u64, w: usize) -> PacketNumber {
let window = 1_u64 << (w * 8);
let candidate = (expected & !(window - 1)) | pn;
@ -656,7 +713,7 @@ impl Deref for DecryptedPacket {
mod tests {
use super::*;
use crate::crypto::{CryptoDxState, CryptoStates};
use crate::FixedConnectionIdManager;
use crate::{FixedConnectionIdManager, QuicVersion};
use neqo_common::Encoder;
use test_fixture::{fixture_init, now};
@ -678,15 +735,15 @@ mod tests {
0xda, 0x1a, 0x00, 0x2b, 0x00, 0x02, 0x03, 0x04,
];
const SAMPLE_INITIAL: &[u8] = &[
0xc9, 0xff, 0x00, 0x00, 0x1b, 0x00, 0x08, 0xf0, 0x67, 0xa5, 0x50, 0x2a, 0x42, 0x62, 0xb5,
0xc9, 0xff, 0x00, 0x00, 0x1c, 0x00, 0x08, 0xf0, 0x67, 0xa5, 0x50, 0x2a, 0x42, 0x62, 0xb5,
0x00, 0x40, 0x74, 0x16, 0x8b, 0xf2, 0x2b, 0x70, 0x02, 0x59, 0x6f, 0x99, 0xae, 0x67, 0xab,
0xf6, 0x5a, 0x58, 0x52, 0xf5, 0x4f, 0x58, 0xc3, 0x7c, 0x80, 0x86, 0x82, 0xe2, 0xe4, 0x04,
0x92, 0xd8, 0xa3, 0x89, 0x9f, 0xb0, 0x4f, 0xc0, 0xaf, 0xe9, 0xaa, 0xbc, 0x87, 0x67, 0xb1,
0x8a, 0x0a, 0xa4, 0x93, 0x53, 0x74, 0x26, 0x37, 0x3b, 0x48, 0xd5, 0x02, 0x21, 0x4d, 0xd8,
0x56, 0xd6, 0x3b, 0x78, 0xce, 0xe3, 0x7b, 0xc6, 0x64, 0xb3, 0xfe, 0x86, 0xd4, 0x87, 0xac,
0x7a, 0x77, 0xc5, 0x30, 0x38, 0xa3, 0xcd, 0x32, 0xf0, 0xb5, 0x00, 0x4d, 0x9f, 0x57, 0x54,
0xc4, 0xf7, 0xf2, 0xd1, 0xf3, 0x5c, 0xf3, 0xf7, 0x11, 0x63, 0x51, 0xc9, 0x2b, 0xd8, 0xc3,
0xa9, 0x52, 0x8d, 0x2b, 0x6a, 0xca, 0x20, 0xf0, 0x80, 0x47, 0xd9, 0xf0, 0x17, 0xf0,
0xc4, 0xf7, 0xf2, 0xd1, 0xf3, 0x5c, 0xf3, 0xf7, 0x11, 0x63, 0x51, 0xc9, 0x2b, 0xda, 0x5b,
0x23, 0xc8, 0x10, 0x34, 0xab, 0x74, 0xf5, 0x4c, 0xb1, 0xbd, 0x72, 0x95, 0x12, 0x56,
];
#[test]
@ -702,6 +759,7 @@ mod tests {
let mut builder = PacketBuilder::long(
Encoder::new(),
PacketType::Initial,
QuicVersion::default(),
&ConnectionId::from(&[][..]),
&ConnectionId::from(SERVER_CID),
);
@ -736,7 +794,7 @@ mod tests {
fn disallow_long_dcid() {
let mut enc = Encoder::new();
enc.encode_byte(PACKET_BIT_LONG | PACKET_BIT_FIXED_QUIC);
enc.encode_uint(4, QUIC_VERSION);
enc.encode_uint(4, QuicVersion::default().as_u32());
enc.encode_vec(1, &[0x00; MAX_CONNECTION_ID_LEN + 1]);
enc.encode_vec(1, &[]);
enc.encode(&[0xff; 40]); // junk
@ -748,7 +806,7 @@ mod tests {
fn disallow_long_scid() {
let mut enc = Encoder::new();
enc.encode_byte(PACKET_BIT_LONG | PACKET_BIT_FIXED_QUIC);
enc.encode_uint(4, QUIC_VERSION);
enc.encode_uint(4, QuicVersion::default().as_u32());
enc.encode_vec(1, &[]);
enc.encode_vec(1, &[0x00; MAX_CONNECTION_ID_LEN + 2]);
enc.encode(&[0xff; 40]); // junk
@ -819,6 +877,7 @@ mod tests {
let mut builder = PacketBuilder::long(
Encoder::new(),
PacketType::Handshake,
QuicVersion::default(),
&ConnectionId::from(SERVER_CID),
&ConnectionId::from(CLIENT_CID),
);
@ -845,6 +904,7 @@ mod tests {
let mut builder = PacketBuilder::long(
Encoder::new(),
PacketType::Initial,
QuicVersion::default(),
&ConnectionId::from(&[][..]),
&ConnectionId::from(SERVER_CID),
);
@ -854,17 +914,34 @@ mod tests {
assert!(encoder.is_empty());
}
const SAMPLE_RETRY: &[u8] = &[
const SAMPLE_RETRY_27: &[u8] = &[
0xff, 0xff, 0x00, 0x00, 0x1b, 0x00, 0x08, 0xf0, 0x67, 0xa5, 0x50, 0x2a, 0x42, 0x62, 0xb5,
0x74, 0x6f, 0x6b, 0x65, 0x6e, 0xa5, 0x23, 0xcb, 0x5b, 0xa5, 0x24, 0x69, 0x5f, 0x65, 0x69,
0xf2, 0x93, 0xa1, 0x35, 0x9d, 0x8e,
];
const SAMPLE_RETRY_28: &[u8] = &[
0xff, 0xff, 0x00, 0x00, 0x1c, 0x00, 0x08, 0xf0, 0x67, 0xa5, 0x50, 0x2a, 0x42, 0x62, 0xb5,
0x74, 0x6f, 0x6b, 0x65, 0x6e, 0xf7, 0x1a, 0x5f, 0x12, 0xaf, 0xe3, 0xec, 0xf8, 0x00, 0x1a,
0x92, 0x0e, 0x6f, 0xdf, 0x1d, 0x63,
];
const RETRY_TOKEN: &[u8] = b"token";
fn pick_retry_version() -> (&'static [u8], QuicVersion) {
if random(1)[0] % 2 == 0 {
(SAMPLE_RETRY_27, QuicVersion::Draft27)
} else {
(SAMPLE_RETRY_28, QuicVersion::Draft28)
}
}
#[test]
fn build_retry() {
fn build_retry_single() {
fixture_init();
let retry = PacketBuilder::retry(&[], SERVER_CID, RETRY_TOKEN, CLIENT_CID).unwrap();
let (sample_retry, quic_version) = pick_retry_version();
let retry =
PacketBuilder::retry(quic_version, &[], SERVER_CID, RETRY_TOKEN, CLIENT_CID).unwrap();
let (packet, remainder) = PublicPacket::decode(&retry, &cid_mgr()).unwrap();
assert!(packet.is_valid_retry(&ConnectionId::from(CLIENT_CID)));
@ -872,21 +949,22 @@ mod tests {
// The builder adds randomness, which makes expectations hard.
// So only do a full check when that randomness matches up.
if retry[0] == SAMPLE_RETRY[0] {
assert_eq!(&retry, &SAMPLE_RETRY);
if retry[0] == sample_retry[0] {
assert_eq!(&retry, &sample_retry);
} else {
// Otherwise, just check that the header is OK.
assert_eq!(retry[0] & 0xf0, 0xf0);
let header_range = 1..retry.len() - 16;
assert_eq!(&retry[header_range.clone()], &SAMPLE_RETRY[header_range]);
assert_eq!(&retry[header_range.clone()], &sample_retry[header_range]);
}
}
#[test]
fn decode_retry() {
fixture_init();
let (sample_retry, _) = pick_retry_version();
let (packet, remainder) =
PublicPacket::decode(SAMPLE_RETRY, &FixedConnectionIdManager::new(5)).unwrap();
PublicPacket::decode(sample_retry, &FixedConnectionIdManager::new(5)).unwrap();
assert!(packet.is_valid_retry(&ConnectionId::from(CLIENT_CID)));
assert!(packet.dcid().is_empty());
assert_eq!(&packet.scid()[..], SERVER_CID);
@ -899,7 +977,7 @@ mod tests {
// Run the build_retry test a few times.
// This increases the chance that the full comparison happens.
for _ in 0..32 {
build_retry();
build_retry_single();
}
}
@ -907,16 +985,17 @@ mod tests {
#[test]
fn invalid_retry() {
fixture_init();
let (sample_retry, _) = pick_retry_version();
let cid_mgr = FixedConnectionIdManager::new(5);
let odcid = ConnectionId::from(CLIENT_CID);
assert!(PublicPacket::decode(&[], &cid_mgr).is_err());
let (packet, remainder) = PublicPacket::decode(SAMPLE_RETRY, &cid_mgr).unwrap();
let (packet, remainder) = PublicPacket::decode(sample_retry, &cid_mgr).unwrap();
assert!(remainder.is_empty());
assert!(packet.is_valid_retry(&odcid));
let mut damaged_retry = SAMPLE_RETRY.to_vec();
let mut damaged_retry = sample_retry.to_vec();
let last = damaged_retry.len() - 1;
damaged_retry[last] ^= 66;
let (packet, remainder) = PublicPacket::decode(&damaged_retry, &cid_mgr).unwrap();
@ -938,8 +1017,8 @@ mod tests {
const SAMPLE_VN: &[u8] = &[
0x80, 0x00, 0x00, 0x00, 0x00, 0x08, 0xf0, 0x67, 0xa5, 0x50, 0x2a, 0x42, 0x62, 0xb5, 0x08,
0x83, 0x94, 0xc8, 0xf0, 0x3e, 0x51, 0x57, 0x08, 0xff, 0x00, 0x00, 0x1b, 0x0a, 0x0a, 0x0a,
0x0a,
0x83, 0x94, 0xc8, 0xf0, 0x3e, 0x51, 0x57, 0x08, 0xff, 0x00, 0x00, 0x1b, 0xff, 0x00, 0x00,
0x1c, 0x0a, 0x0a, 0x0a, 0x0a,
];
#[test]
@ -975,7 +1054,7 @@ mod tests {
enc.encode_vec(1, BIG_DCID);
enc.encode_vec(1, BIG_SCID);
enc.encode_uint(4, 0x1a2a_3a4a_u64);
enc.encode_uint(4, QUIC_VERSION);
enc.encode_uint(4, QuicVersion::default().as_u32());
enc.encode_uint(4, 0x5a6a_7a8a_u64);
let (packet, remainder) =

15
third_party/rust/neqo-transport/src/path.rs поставляемый
Просмотреть файл

@ -25,6 +25,7 @@ pub struct Path {
remote: SocketAddr,
local_cids: Vec<ConnectionId>,
remote_cid: ConnectionId,
reset_token: Option<[u8; 16]>,
}
impl Path {
@ -40,6 +41,7 @@ impl Path {
remote,
local_cids: vec![local_cid],
remote_cid,
reset_token: None,
}
}
@ -50,6 +52,7 @@ impl Path {
remote: d.source(),
local_cids: Vec::new(),
remote_cid,
reset_token: None,
}
}
@ -80,7 +83,7 @@ impl Path {
self.local_cids.first().as_ref().unwrap()
}
/// Set the remote connection ID based on the peer's valid.
/// Set the remote connection ID based on the peer's choice.
pub fn set_remote_cid(&mut self, cid: &ConnectionIdRef) {
self.remote_cid = ConnectionId::from(cid);
}
@ -90,6 +93,16 @@ impl Path {
&self.remote_cid
}
/// Set the stateless reset token for the connection ID that is currently in use.
pub fn set_reset_token(&mut self, token: [u8; 16]) {
self.reset_token = Some(token);
}
/// Access the reset token.
pub fn reset_token(&self) -> Option<&[u8; 16]> {
self.reset_token.as_ref()
}
/// Make a datagram.
pub fn datagram<V: Into<Vec<u8>>>(&self, payload: V) -> Datagram {
Datagram::new(self.local, self.remote, payload)

12
third_party/rust/neqo-transport/src/qlog.rs поставляемый
Просмотреть файл

@ -16,7 +16,7 @@ use crate::frame::{self, Frame};
use crate::packet::{DecryptedPacket, PacketNumber, PacketType};
use crate::path::Path;
use crate::tparams::{self, TransportParametersHandler};
use crate::{Res, QUIC_VERSION};
use crate::{QuicVersion, Res};
pub fn connection_tparams_set(
qlog: &mut Option<NeqoQlog>,
@ -31,15 +31,15 @@ pub fn connection_tparams_set(
None,
None,
None,
if let Some(ocid) = remote.get_bytes(tparams::ORIGINAL_CONNECTION_ID) {
if let Some(ocid) = remote.get_bytes(tparams::ORIGINAL_DESTINATION_CONNECTION_ID) {
// Cannot use packet::ConnectionId's Display trait implementation
// because it does not include the 0x prefix.
Some(hex(&ocid))
Some(hex(ocid))
} else {
None
},
if let Some(srt) = remote.get_bytes(tparams::STATELESS_RESET_TOKEN) {
Some(hex(&srt))
Some(hex(srt))
} else {
None
},
@ -49,7 +49,7 @@ pub fn connection_tparams_set(
None
},
Some(remote.get_integer(tparams::IDLE_TIMEOUT)),
Some(remote.get_integer(tparams::MAX_PACKET_SIZE)),
Some(remote.get_integer(tparams::MAX_UDP_PAYLOAD_SIZE)),
Some(remote.get_integer(tparams::ACK_DELAY_EXPONENT)),
Some(remote.get_integer(tparams::MAX_ACK_DELAY)),
// TODO(hawkinsw@obs.cr): We do not yet handle ACTIVE_CONNECTION_ID_LIMIT in tparams yet.
@ -163,7 +163,7 @@ fn connection_started(qlog: &mut Option<NeqoQlog>, path: &Path) -> Res<()> {
Some("QUIC".into()),
path.local_address().port().into(),
path.remote_address().port().into(),
Some(format!("{:x}", QUIC_VERSION)),
Some(format!("{:x}", QuicVersion::default().as_u32())),
Some(format!("{}", path.local_cid())),
Some(format!("{}", path.remote_cid())),
))?;

53
third_party/rust/neqo-transport/src/server.rs поставляемый
Просмотреть файл

@ -19,7 +19,7 @@ use neqo_crypto::{
use crate::cid::{ConnectionId, ConnectionIdDecoder, ConnectionIdManager, ConnectionIdRef};
use crate::connection::{Connection, Output, State};
use crate::packet::{PacketBuilder, PacketType, PublicPacket};
use crate::Res;
use crate::{QuicVersion, Res};
use std::cell::RefCell;
use std::collections::{HashMap, HashSet, VecDeque};
@ -324,13 +324,14 @@ impl Server {
token: Vec<u8>,
dgram: Datagram,
now: Instant,
quic_version: QuicVersion,
) -> Option<Datagram> {
qdebug!([self], "Handle initial packet");
match self.retry.validate(&token, dgram.source(), now) {
RetryTokenResult::Invalid => None,
RetryTokenResult::Pass => self.connection_attempt(dcid, None, dgram, now),
RetryTokenResult::Pass => self.connection_attempt(dcid, None, dgram, now, quic_version),
RetryTokenResult::Valid(orig_dcid) => {
self.connection_attempt(dcid, Some(orig_dcid), dgram, now)
self.connection_attempt(dcid, Some(orig_dcid), dgram, now, quic_version)
}
RetryTokenResult::Validate => {
qinfo!([self], "Send retry for {:?}", dcid);
@ -343,7 +344,7 @@ impl Server {
return None;
};
let new_dcid = self.cid_manager.borrow_mut().generate_cid();
let packet = PacketBuilder::retry(&scid, &new_dcid, &token, &dcid);
let packet = PacketBuilder::retry(quic_version, &scid, &new_dcid, &token, &dcid);
if let Ok(p) = packet {
let retry = Datagram::new(dgram.destination(), dgram.source(), p);
Some(retry)
@ -361,6 +362,7 @@ impl Server {
orig_dcid: Option<ConnectionId>,
dgram: Datagram,
now: Instant,
quic_version: QuicVersion,
) -> Option<Datagram> {
let attempt_key = AttemptKey {
remote_address: dgram.source(),
@ -375,7 +377,7 @@ impl Server {
let c = Rc::clone(c);
self.process_connection(c, Some(dgram), now)
} else {
self.accept_connection(attempt_key, orig_dcid, dgram, now)
self.accept_connection(attempt_key, dcid, orig_dcid, dgram, now, quic_version)
}
}
@ -432,13 +434,18 @@ impl Server {
fn accept_connection(
&mut self,
attempt_key: AttemptKey,
dcid: ConnectionId,
orig_dcid: Option<ConnectionId>,
dgram: Datagram,
now: Instant,
quic_version: QuicVersion,
) -> Option<Datagram> {
qinfo!([self], "Accept connection {:?}", attempt_key);
// The internal connection ID manager that we use is not used directly.
// Instead, wrap it so that we can save connection IDs.
let local_initial_source_cid = self.cid_manager.borrow_mut().generate_cid();
let cid_mgr = Rc::new(RefCell::new(ServerConnectionIdManager {
c: None,
cid_manager: self.cid_manager.clone(),
@ -449,12 +456,16 @@ impl Server {
&self.certs,
&self.protocols,
&self.anti_replay,
cid_mgr.clone(),
self.cid_manager.clone(),
quic_version,
local_initial_source_cid.clone(),
);
if let Ok(mut c) = sconn {
if let Some(odcid) = orig_dcid {
c.original_connection_id(&odcid);
// There was a retry.
c.set_original_destination_cid(odcid);
c.set_retry_source_cid(dcid);
}
c.set_qlog(self.create_qlog_trace(&attempt_key));
let c = Rc::new(RefCell::new(ServerConnectionState {
@ -463,6 +474,7 @@ impl Server {
active_attempt: Some(attempt_key.clone()),
}));
cid_mgr.borrow_mut().c = Some(c.clone());
cid_mgr.borrow_mut().insert_cid(local_initial_source_cid);
let previous_attempt = self.active_attempts.insert(attempt_key, c.clone());
debug_assert!(previous_attempt.is_none());
self.process_connection(c, Some(dgram), now)
@ -507,7 +519,8 @@ impl Server {
let dcid = ConnectionId::from(packet.dcid());
let scid = ConnectionId::from(packet.scid());
let token = packet.token().to_vec();
self.handle_initial(dcid, scid, token, dgram, now)
let quic_version = packet.version().expect("Initial must have version field");
self.handle_initial(dcid, scid, token, dgram, now, quic_version)
}
PacketType::OtherVersion => {
let vn = PacketBuilder::version_negotiation(packet.scid(), packet.dcid());
@ -622,24 +635,32 @@ struct ServerConnectionIdManager {
cid_manager: CidMgr,
}
impl ServerConnectionIdManager {
fn insert_cid(&mut self, cid: ConnectionId) {
assert!(!cid.is_empty());
let v = self
.connections
.borrow_mut()
.insert(cid, self.c.as_ref().unwrap().clone());
if let Some(v) = v {
debug_assert!(Rc::ptr_eq(&v, self.c.as_ref().unwrap()));
}
}
}
impl ConnectionIdDecoder for ServerConnectionIdManager {
fn decode_cid<'a>(&self, dec: &mut Decoder<'a>) -> Option<ConnectionIdRef<'a>> {
self.cid_manager.borrow_mut().decode_cid(dec)
}
}
impl ConnectionIdManager for ServerConnectionIdManager {
fn generate_cid(&mut self) -> ConnectionId {
let cid = self.cid_manager.borrow_mut().generate_cid();
assert!(!cid.is_empty());
let v = self
.connections
.borrow_mut()
.insert(cid.clone(), self.c.as_ref().unwrap().clone());
if let Some(v) = v {
debug_assert!(Rc::ptr_eq(&v, self.c.as_ref().unwrap()));
}
self.insert_cid(cid.clone());
cid
}
fn as_decoder(&self) -> &dyn ConnectionIdDecoder {
self
}

Просмотреть файл

@ -27,20 +27,23 @@ macro_rules! tpids {
};
}
tpids! {
ORIGINAL_CONNECTION_ID = 0,
IDLE_TIMEOUT = 1,
STATELESS_RESET_TOKEN = 2,
MAX_PACKET_SIZE = 3,
INITIAL_MAX_DATA = 4,
INITIAL_MAX_STREAM_DATA_BIDI_LOCAL = 5,
INITIAL_MAX_STREAM_DATA_BIDI_REMOTE = 6,
INITIAL_MAX_STREAM_DATA_UNI = 7,
INITIAL_MAX_STREAMS_BIDI = 8,
INITIAL_MAX_STREAMS_UNI = 9,
ACK_DELAY_EXPONENT = 10,
MAX_ACK_DELAY = 11,
DISABLE_MIGRATION = 12,
PREFERRED_ADDRESS = 13,
ORIGINAL_DESTINATION_CONNECTION_ID = 0x00,
IDLE_TIMEOUT = 0x01,
STATELESS_RESET_TOKEN = 0x02,
MAX_UDP_PAYLOAD_SIZE = 0x03,
INITIAL_MAX_DATA = 0x04,
INITIAL_MAX_STREAM_DATA_BIDI_LOCAL = 0x05,
INITIAL_MAX_STREAM_DATA_BIDI_REMOTE = 0x06,
INITIAL_MAX_STREAM_DATA_UNI = 0x07,
INITIAL_MAX_STREAMS_BIDI = 0x08,
INITIAL_MAX_STREAMS_UNI = 0x09,
ACK_DELAY_EXPONENT = 0x0a,
MAX_ACK_DELAY = 0x0b,
DISABLE_MIGRATION = 0x0c,
PREFERRED_ADDRESS = 0x0d,
ACTIVE_CONNECTION_ID_LIMIT = 0x0e,
INITIAL_SOURCE_CONNECTION_ID = 0x0f,
RETRY_SOURCE_CONNECTION_ID = 0x10,
}
#[derive(Clone, Debug, PartialEq)]
@ -52,6 +55,7 @@ pub enum TransportParameter {
impl TransportParameter {
fn encode(&self, enc: &mut Encoder, tp: TransportParameterId) {
qdebug!("TP encoded; type 0x{:02x} val {:?}", tp, self);
enc.encode_varint(tp);
match self {
Self::Bytes(a) => {
@ -80,7 +84,9 @@ impl TransportParameter {
qtrace!("TP {:x} length {:x}", tp, content.len());
let mut d = Decoder::from(content);
let value = match tp {
ORIGINAL_CONNECTION_ID => Self::Bytes(d.decode_remainder().to_vec()),
ORIGINAL_DESTINATION_CONNECTION_ID
| INITIAL_SOURCE_CONNECTION_ID
| RETRY_SOURCE_CONNECTION_ID => Self::Bytes(d.decode_remainder().to_vec()),
STATELESS_RESET_TOKEN => {
if d.remaining() != 16 {
return Err(Error::TransportParameterError);
@ -102,7 +108,7 @@ impl TransportParameter {
_ => return Err(Error::StreamLimitError),
},
MAX_PACKET_SIZE => match d.decode_varint() {
MAX_UDP_PAYLOAD_SIZE => match d.decode_varint() {
Some(v) if v >= 1200 => Self::Integer(v),
_ => return Err(Error::TransportParameterError),
},
@ -111,6 +117,10 @@ impl TransportParameter {
Some(v) if v <= 20 => Self::Integer(v),
_ => return Err(Error::TransportParameterError),
},
ACTIVE_CONNECTION_ID_LIMIT => match d.decode_varint() {
Some(v) if v <= 2 => Self::Integer(v),
_ => return Err(Error::TransportParameterError),
},
DISABLE_MIGRATION => Self::Empty,
// Skip.
@ -119,7 +129,7 @@ impl TransportParameter {
if d.remaining() > 0 {
return Err(Error::TooMuchData);
}
qtrace!("TP decoded; type {:x} val {:?}", tp, value);
qdebug!("TP decoded; type 0x{:02x} val {:?}", tp, value);
Ok(Some((tp, value)))
}
}
@ -174,9 +184,10 @@ impl TransportParameters {
| INITIAL_MAX_STREAM_DATA_UNI
| INITIAL_MAX_STREAMS_BIDI
| INITIAL_MAX_STREAMS_UNI => 0,
MAX_PACKET_SIZE => 65527,
MAX_UDP_PAYLOAD_SIZE => 65527,
ACK_DELAY_EXPONENT => 3,
MAX_ACK_DELAY => 25,
ACTIVE_CONNECTION_ID_LIMIT => 2,
_ => panic!("Transport parameter not known or not an Integer"),
};
match self.params.get(&tp) {
@ -186,7 +197,7 @@ impl TransportParameters {
}
}
// Get an integer type or a default.
// Set an integer type or a default.
pub fn set_integer(&mut self, tp: TransportParameterId, value: u64) {
match tp {
IDLE_TIMEOUT
@ -196,31 +207,38 @@ impl TransportParameters {
| INITIAL_MAX_STREAM_DATA_UNI
| INITIAL_MAX_STREAMS_BIDI
| INITIAL_MAX_STREAMS_UNI
| MAX_PACKET_SIZE
| MAX_UDP_PAYLOAD_SIZE
| ACK_DELAY_EXPONENT
| MAX_ACK_DELAY => {
| MAX_ACK_DELAY
| ACTIVE_CONNECTION_ID_LIMIT => {
self.set(tp, TransportParameter::Integer(value));
}
_ => panic!("Transport parameter not known"),
}
}
pub fn get_bytes(&self, tp: TransportParameterId) -> Option<Vec<u8>> {
pub fn get_bytes(&self, tp: TransportParameterId) -> Option<&[u8]> {
match tp {
ORIGINAL_CONNECTION_ID | STATELESS_RESET_TOKEN => {}
ORIGINAL_DESTINATION_CONNECTION_ID
| INITIAL_SOURCE_CONNECTION_ID
| RETRY_SOURCE_CONNECTION_ID
| STATELESS_RESET_TOKEN => {}
_ => panic!("Transport parameter not known or not type bytes"),
}
match self.params.get(&tp) {
None => None,
Some(TransportParameter::Bytes(x)) => Some(x.to_vec()),
Some(TransportParameter::Bytes(x)) => Some(&x),
_ => panic!("Internal error"),
}
}
pub fn set_bytes(&mut self, tp: TransportParameterId, value: Vec<u8>) {
match tp {
ORIGINAL_CONNECTION_ID | STATELESS_RESET_TOKEN => {
ORIGINAL_DESTINATION_CONNECTION_ID
| INITIAL_SOURCE_CONNECTION_ID
| RETRY_SOURCE_CONNECTION_ID
| STATELESS_RESET_TOKEN => {
self.set(tp, TransportParameter::Bytes(value));
}
_ => panic!("Transport parameter not known or not type bytes"),
@ -256,11 +274,14 @@ impl TransportParameters {
// Skip checks for these, which don't affect 0-RTT.
if matches!(
*k,
ORIGINAL_CONNECTION_ID
ORIGINAL_DESTINATION_CONNECTION_ID
| INITIAL_SOURCE_CONNECTION_ID
| RETRY_SOURCE_CONNECTION_ID
| STATELESS_RESET_TOKEN
| IDLE_TIMEOUT
| ACK_DELAY_EXPONENT
| MAX_ACK_DELAY
| ACTIVE_CONNECTION_ID_LIMIT
) {
continue;
}
@ -388,11 +409,12 @@ mod tests {
use super::*;
#[test]
fn test_basic_tps() {
fn basic_tps() {
const RESET_TOKEN: &[u8] = &[1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 7, 8];
let mut tps = TransportParameters::default();
tps.set(
STATELESS_RESET_TOKEN,
TransportParameter::Bytes(vec![1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 7, 8]),
TransportParameter::Bytes(RESET_TOKEN.to_vec()),
);
tps.params
.insert(INITIAL_MAX_STREAMS_BIDI, TransportParameter::Integer(10));
@ -406,13 +428,15 @@ mod tests {
println!("TPS = {:?}", tps);
assert_eq!(tps2.get_integer(IDLE_TIMEOUT), 0); // Default
assert_eq!(tps2.get_integer(MAX_ACK_DELAY), 25); // Default
assert_eq!(tps2.get_integer(ACTIVE_CONNECTION_ID_LIMIT), 2); // Default
assert_eq!(tps2.get_integer(INITIAL_MAX_STREAMS_BIDI), 10); // Sent
assert_eq!(
tps2.get_bytes(STATELESS_RESET_TOKEN),
Some(vec![1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 7, 8])
);
assert_eq!(tps2.get_bytes(ORIGINAL_CONNECTION_ID), None);
assert_eq!(tps2.was_sent(ORIGINAL_CONNECTION_ID), false);
assert_eq!(tps2.get_bytes(STATELESS_RESET_TOKEN), Some(RESET_TOKEN));
assert_eq!(tps2.get_bytes(ORIGINAL_DESTINATION_CONNECTION_ID), None);
assert_eq!(tps2.get_bytes(INITIAL_SOURCE_CONNECTION_ID), None);
assert_eq!(tps2.get_bytes(RETRY_SOURCE_CONNECTION_ID), None);
assert_eq!(tps2.was_sent(ORIGINAL_DESTINATION_CONNECTION_ID), false);
assert_eq!(tps2.was_sent(INITIAL_SOURCE_CONNECTION_ID), false);
assert_eq!(tps2.was_sent(RETRY_SOURCE_CONNECTION_ID), false);
assert_eq!(tps2.was_sent(STATELESS_RESET_TOKEN), true);
let mut enc = Encoder::default();
@ -430,6 +454,7 @@ mod tests {
);
tps_a.set(IDLE_TIMEOUT, TransportParameter::Integer(10));
tps_a.set(MAX_ACK_DELAY, TransportParameter::Integer(22));
tps_a.set(ACTIVE_CONNECTION_ID_LIMIT, TransportParameter::Integer(33));
let mut tps_b = TransportParameters::default();
assert!(tps_a.ok_for_0rtt(&tps_b));
@ -441,6 +466,7 @@ mod tests {
);
tps_b.set(IDLE_TIMEOUT, TransportParameter::Integer(100));
tps_b.set(MAX_ACK_DELAY, TransportParameter::Integer(2));
tps_b.set(ACTIVE_CONNECTION_ID_LIMIT, TransportParameter::Integer(44));
assert!(tps_a.ok_for_0rtt(&tps_b));
assert!(tps_b.ok_for_0rtt(&tps_a));
}
@ -455,7 +481,7 @@ mod tests {
INITIAL_MAX_STREAM_DATA_UNI,
INITIAL_MAX_STREAMS_BIDI,
INITIAL_MAX_STREAMS_UNI,
MAX_PACKET_SIZE,
MAX_UDP_PAYLOAD_SIZE,
];
for i in INTEGER_KEYS {
tps_a.set(*i, TransportParameter::Integer(12));

Просмотреть файл

@ -17,8 +17,8 @@ use neqo_crypto::{
};
use neqo_transport::{
server::{ActiveConnectionRef, Server},
Connection, ConnectionError, Error, FixedConnectionIdManager, Output, State, StreamType,
QUIC_VERSION,
Connection, ConnectionError, Error, FixedConnectionIdManager, Output, QuicVersion, State,
StreamType,
};
use test_fixture::{self, assertions, default_client, now};
@ -210,7 +210,7 @@ fn drop_non_initial() {
let mut header = neqo_common::Encoder::with_capacity(1200);
header
.encode_byte(0xfa)
.encode_uint(4, QUIC_VERSION)
.encode_uint(4, QuicVersion::default().as_u32())
.encode_vec(1, CID)
.encode_vec(1, CID);
let mut bogus_data: Vec<u8> = header.into();
@ -225,7 +225,7 @@ fn drop_non_initial() {
}
#[test]
fn retry() {
fn retry_basic() {
let mut server = default_server();
server.set_retry_required(true);
let mut client = default_client();
@ -601,7 +601,7 @@ fn mitm_retry() {
assert!(matches!(
*client.state(),
State::Closing{
error: ConnectionError::Transport(Error::InvalidRetry),
error: ConnectionError::Transport(Error::ProtocolViolation),
..
}
));
@ -630,7 +630,7 @@ fn bad_client_initial() {
let mut header_enc = Encoder::new();
header_enc
.encode_byte(0xc0) // Initial with 1 byte packet number.
.encode_uint(4, QUIC_VERSION)
.encode_uint(4, QuicVersion::default().as_u32())
.encode_vec(1, dcid)
.encode_vec(1, scid)
.encode_vvec(&[])
@ -713,7 +713,7 @@ fn version_negotiation() {
let mut found = false;
while dec.remaining() > 0 {
let v = dec.decode_uint(4).expect("supported version");
found |= v == u64::from(QUIC_VERSION);
found |= v == u64::from(QuicVersion::default().as_u32());
}
assert!(found, "valid version not found");