mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-25 05:41:12 +00:00
Backed out changeset 83204ae613b7 (bug 1724196) for causing topcrash bug 1724408.
This commit is contained in:
parent
cf6459027c
commit
52c9905518
@ -15,7 +15,7 @@ rev = "85551909b95a5cf553a85dbcddfa5f117cfbbe0e"
|
||||
[source."https://github.com/mozilla/neqo"]
|
||||
git = "https://github.com/mozilla/neqo"
|
||||
replace-with = "vendored-sources"
|
||||
tag = "v0.4.29"
|
||||
tag = "v0.4.28"
|
||||
|
||||
[source."https://github.com/mozilla/mp4parse-rust"]
|
||||
git = "https://github.com/mozilla/mp4parse-rust"
|
||||
|
20
Cargo.lock
generated
20
Cargo.lock
generated
@ -3340,8 +3340,8 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "neqo-common"
|
||||
version = "0.4.29"
|
||||
source = "git+https://github.com/mozilla/neqo?tag=v0.4.29#bac542bad66ad6210864220f477fc655db1b4653"
|
||||
version = "0.4.28"
|
||||
source = "git+https://github.com/mozilla/neqo?tag=v0.4.28#c3d909e40d2ee68e2937b7dac1831a27520bf460"
|
||||
dependencies = [
|
||||
"chrono",
|
||||
"env_logger",
|
||||
@ -3353,8 +3353,8 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "neqo-crypto"
|
||||
version = "0.4.29"
|
||||
source = "git+https://github.com/mozilla/neqo?tag=v0.4.29#bac542bad66ad6210864220f477fc655db1b4653"
|
||||
version = "0.4.28"
|
||||
source = "git+https://github.com/mozilla/neqo?tag=v0.4.28#c3d909e40d2ee68e2937b7dac1831a27520bf460"
|
||||
dependencies = [
|
||||
"bindgen",
|
||||
"log",
|
||||
@ -3366,8 +3366,8 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "neqo-http3"
|
||||
version = "0.4.29"
|
||||
source = "git+https://github.com/mozilla/neqo?tag=v0.4.29#bac542bad66ad6210864220f477fc655db1b4653"
|
||||
version = "0.4.28"
|
||||
source = "git+https://github.com/mozilla/neqo?tag=v0.4.28#c3d909e40d2ee68e2937b7dac1831a27520bf460"
|
||||
dependencies = [
|
||||
"log",
|
||||
"neqo-common",
|
||||
@ -3380,8 +3380,8 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "neqo-qpack"
|
||||
version = "0.4.29"
|
||||
source = "git+https://github.com/mozilla/neqo?tag=v0.4.29#bac542bad66ad6210864220f477fc655db1b4653"
|
||||
version = "0.4.28"
|
||||
source = "git+https://github.com/mozilla/neqo?tag=v0.4.28#c3d909e40d2ee68e2937b7dac1831a27520bf460"
|
||||
dependencies = [
|
||||
"lazy_static",
|
||||
"log",
|
||||
@ -3394,8 +3394,8 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "neqo-transport"
|
||||
version = "0.4.29"
|
||||
source = "git+https://github.com/mozilla/neqo?tag=v0.4.29#bac542bad66ad6210864220f477fc655db1b4653"
|
||||
version = "0.4.28"
|
||||
source = "git+https://github.com/mozilla/neqo?tag=v0.4.28#c3d909e40d2ee68e2937b7dac1831a27520bf460"
|
||||
dependencies = [
|
||||
"indexmap",
|
||||
"lazy_static",
|
||||
|
@ -8,10 +8,10 @@ edition = "2018"
|
||||
name = "neqo_glue"
|
||||
|
||||
[dependencies]
|
||||
neqo-http3 = { tag = "v0.4.29", git = "https://github.com/mozilla/neqo" }
|
||||
neqo-transport = { tag = "v0.4.29", git = "https://github.com/mozilla/neqo" }
|
||||
neqo-common = { tag = "v0.4.29", git = "https://github.com/mozilla/neqo" }
|
||||
neqo-qpack = { tag = "v0.4.29", git = "https://github.com/mozilla/neqo" }
|
||||
neqo-http3 = { tag = "v0.4.28", git = "https://github.com/mozilla/neqo" }
|
||||
neqo-transport = { tag = "v0.4.28", git = "https://github.com/mozilla/neqo" }
|
||||
neqo-common = { tag = "v0.4.28", git = "https://github.com/mozilla/neqo" }
|
||||
neqo-qpack = { tag = "v0.4.28", git = "https://github.com/mozilla/neqo" }
|
||||
nserror = { path = "../../../xpcom/rust/nserror" }
|
||||
nsstring = { path = "../../../xpcom/rust/nsstring" }
|
||||
xpcom = { path = "../../../xpcom/rust/xpcom" }
|
||||
@ -20,7 +20,7 @@ log = "0.4.0"
|
||||
qlog = "0.4.0"
|
||||
|
||||
[dependencies.neqo-crypto]
|
||||
tag = "v0.4.29"
|
||||
tag = "v0.4.28"
|
||||
git = "https://github.com/mozilla/neqo"
|
||||
default-features = false
|
||||
features = ["gecko"]
|
||||
|
@ -5,17 +5,17 @@ authors = ["Dragana Damjanovic <dragana.damjano@gmail.com>"]
|
||||
edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
neqo-transport = { tag = "v0.4.29", git = "https://github.com/mozilla/neqo" }
|
||||
neqo-common = { tag = "v0.4.29", git = "https://github.com/mozilla/neqo" }
|
||||
neqo-http3 = { tag = "v0.4.29", git = "https://github.com/mozilla/neqo" }
|
||||
neqo-qpack = { tag = "v0.4.29", git = "https://github.com/mozilla/neqo" }
|
||||
neqo-transport = { tag = "v0.4.28", git = "https://github.com/mozilla/neqo" }
|
||||
neqo-common = { tag = "v0.4.28", git = "https://github.com/mozilla/neqo" }
|
||||
neqo-http3 = { tag = "v0.4.28", git = "https://github.com/mozilla/neqo" }
|
||||
neqo-qpack = { tag = "v0.4.28", git = "https://github.com/mozilla/neqo" }
|
||||
mio = "0.6.17"
|
||||
mio-extras = "2.0.5"
|
||||
log = "0.4.0"
|
||||
base64 = "0.10"
|
||||
|
||||
[dependencies.neqo-crypto]
|
||||
tag = "v0.4.29"
|
||||
tag = "v0.4.28"
|
||||
git = "https://github.com/mozilla/neqo"
|
||||
default-features = false
|
||||
features = ["gecko"]
|
||||
|
@ -1 +1 @@
|
||||
{"files":{"Cargo.toml":"e52b805b7f979978260661cd09a21138295b2813ed9adaf143ba7de4ba4f5092","build.rs":"a17b1bb1bd3de3fc958f72d4d1357f7bc4432faa26640c95b5fbfccf40579d67","src/codec.rs":"a20011436df6c4c5620b2fc9d45c10b8f4ce0922b8593c8bfb2355a41670687d","src/datagram.rs":"569f8d9e34d7ee17144bf63d34136ecd9778da0d337e513f338738c50284615e","src/event.rs":"f60fee9f4b09ef47ff5e4bfa21c07e45ffd5873c292f2605f24d834070127d62","src/header.rs":"b7d4eeb40952b36f71ae1f37ce82c9617af8b84c171576de4eca9d50a3071103","src/hrtime.rs":"45a608ce9f00e2666ce95422a278c6dc0ff4e229b114e7bcf0b4c0d9dc61ad56","src/incrdecoder.rs":"ddbeadb4712133281f706cdf828047ca97502e9fe26b7359961040ebe3535e09","src/lib.rs":"e19efc395a902d1584e66cddf1c3beedbfd1a0487457ba6a18e60bcd84132be4","src/log.rs":"b69e492af85e65866cb6588138e8a337dd897d3ce399cb4e9fb8cc04ac042b7f","src/qlog.rs":"e59c4e6dcf9c70553dd6f58da41ff2053ea67b008cac186742140352f5044130","src/timer.rs":"147d82795f0f5c660d93ffb3249524461a34c58bef73c0f6bcbae365e7ae2f2d","tests/log.rs":"480b165b7907ec642c508b303d63005eee1427115d6973a349eaf6b2242ed18d"},"package":null}
|
||||
{"files":{"Cargo.toml":"0dc0aa7be23729800173d4ca20d36cebe93b1a6ca6f3067671bf5525c2331103","build.rs":"a17b1bb1bd3de3fc958f72d4d1357f7bc4432faa26640c95b5fbfccf40579d67","src/codec.rs":"a20011436df6c4c5620b2fc9d45c10b8f4ce0922b8593c8bfb2355a41670687d","src/datagram.rs":"569f8d9e34d7ee17144bf63d34136ecd9778da0d337e513f338738c50284615e","src/event.rs":"f60fee9f4b09ef47ff5e4bfa21c07e45ffd5873c292f2605f24d834070127d62","src/header.rs":"b7d4eeb40952b36f71ae1f37ce82c9617af8b84c171576de4eca9d50a3071103","src/hrtime.rs":"45a608ce9f00e2666ce95422a278c6dc0ff4e229b114e7bcf0b4c0d9dc61ad56","src/incrdecoder.rs":"ddbeadb4712133281f706cdf828047ca97502e9fe26b7359961040ebe3535e09","src/lib.rs":"e19efc395a902d1584e66cddf1c3beedbfd1a0487457ba6a18e60bcd84132be4","src/log.rs":"b69e492af85e65866cb6588138e8a337dd897d3ce399cb4e9fb8cc04ac042b7f","src/qlog.rs":"e59c4e6dcf9c70553dd6f58da41ff2053ea67b008cac186742140352f5044130","src/timer.rs":"147d82795f0f5c660d93ffb3249524461a34c58bef73c0f6bcbae365e7ae2f2d","tests/log.rs":"480b165b7907ec642c508b303d63005eee1427115d6973a349eaf6b2242ed18d"},"package":null}
|
2
third_party/rust/neqo-common/Cargo.toml
vendored
2
third_party/rust/neqo-common/Cargo.toml
vendored
@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "neqo-common"
|
||||
version = "0.4.29"
|
||||
version = "0.4.28"
|
||||
authors = ["Bobby Holley <bobbyholley@gmail.com>"]
|
||||
edition = "2018"
|
||||
license = "MIT/Apache-2.0"
|
||||
|
@ -1 +1 @@
|
||||
{"files":{"Cargo.toml":"a58df5c54966fe47c4c7c7aac56771451956ca189efae0da5b97a25d28f9ff8f","TODO":"ac0f1c2ebcca03f5b3c0cc56c5aedbb030a4b511e438bc07a57361c789f91e9f","bindings/bindings.toml":"26f85b25967a21522c7185914c8a31afee3e93bf5c5548341b27f708ea1ecede","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":"238238eca9a6428996b96ac2a4d6aa5f206b2892f6e9922e12e74e34fe39d47e","src/aead.rs":"140f77ffb5016836c970c39c6c3a42db9581a14b797b9cd05386d0dd0831fe63","src/aead_fuzzing.rs":"4e60d5a2ee6dedfd08602fa36318239e731244825df2cb801ca1d88f5f2a41c1","src/agent.rs":"9c413275bfa0a6f0c736d9925b4d5978d6b8c8a8ddb1c047b60e69ae1820858e","src/agentio.rs":"995e54772d6000d2773a2c57d67fc80756cab47dacfb4915e1ee49c5906d8495","src/auth.rs":"e821dac1511691151a6e64b7c7130a07d941dffad4529b2631f20ddd07d3f20c","src/cert.rs":"94450b248eed218b9227861ed81e557a543c0c88868fe1a434dc9c9f0f9651ae","src/constants.rs":"998e77bee88197a240032c1bfbddcff417a25ba82e576a0d2fe18ee9b63cefc7","src/ech.rs":"1d7b8760cd4e3cb2800fc9ff5fb2b1c89170fd379e43a9e1c626b7df0a59c6d3","src/err.rs":"38482dc0184802a5a503f540456f3af829641179eba32ed8ee7cc5d6a0afc6b3","src/exp.rs":"61586662407359c1ecb8ed4987bc3c702f26ba2e203a091a51b6d6363cbd510f","src/ext.rs":"361277879194dc32f741b8d1894afe5fd3fcc8eb244f7dd5914eeb959b85717d","src/hkdf.rs":"8d05bffddbd9950baa1d4920d42d29e3970caa308b32c1e59b9704dc257d87ab","src/hp.rs":"46a2023c421d89fda8d09b356b648272857fd20ee5cf5829143ac88402b32e4b","src/lib.rs":"2e486b5b18dcc6bf624080396e5f401fb0bed63db6dcd5e11c7614b7ce1bc196","src/once.rs":"b9850384899a1a016e839743d3489c0d4d916e1973746ef8c89872105d7d9736","src/p11.rs":"3e01b513b982fbc0b75bd66deeab8a9a355ede753091d2076c06111d36ecaf02","src/prio.rs":"38664072cafc4f7ce2dfe2e1e029afe87c423e01a60066c25a736644cb0ce379","src/replay.rs":"6c6a41c4d837ecd14e0dda05e9bf9a2eb6f3f4c3cc6eb8e41156dbd6bf3b1113","src/result.rs":"cef34dfcb907723e195b56501132e4560e250b327783cb5e41201da5b63e9b5c","src/secrets.rs":"48790a330994d892742048000bd12460b7eee2c3daaa444481b8527406d0a4c7","src/selfencrypt.rs":"036a6a22bd0ce9ee849a986f6faad4a550de3551bd53de1f71a7d7d9b4206e5b","src/ssl.rs":"821dbe19590a8716327628a1df7ba4184a9df454227eac60f0e793bc426fc315","src/time.rs":"b71fa74ad979d78765dd037c12f5e97eefb9fefc91be8f7c6f45e74b66ac11fc","tests/aead.rs":"98a737643ca41b2f36f6eda5a5dcb2acd420650ef22ab0a8cbed16c423734cc7","tests/agent.rs":"c191782187cb344186195fe377d9f351f2454e5b437f8d4ad88ec3edc8608a5d","tests/ext.rs":"eba9f03accdd598e38292ac88263a81b367d60d5a736a43117a3663de105ec48","tests/handshake.rs":"6ea3e5b3bc889d201b55f959b658a848c0ada54c956bda087b2ac8897a24a786","tests/hkdf.rs":"539235e9dcf2a56b72961a9a04f0080409adf6bf465bfad7c30026421b2d4326","tests/hp.rs":"e52a7d2f4387f2dfe8bfe1da5867e8e0d3eb51e171c6904e18b18c4343536af8","tests/init.rs":"baf680de62f5b06f38a112192a2e9a2ac9492f2cdbdf5f4b749ef18c94c9ac35","tests/selfencrypt.rs":"1125c858ec4e0a6994f34d162aa066cb003c61b324f268529ea04bcb641347cb"},"package":null}
|
||||
{"files":{"Cargo.toml":"d69edddfbe830720c227d018226a493ca524cc421f862d443ac32407b477490b","TODO":"ac0f1c2ebcca03f5b3c0cc56c5aedbb030a4b511e438bc07a57361c789f91e9f","bindings/bindings.toml":"26f85b25967a21522c7185914c8a31afee3e93bf5c5548341b27f708ea1ecede","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":"238238eca9a6428996b96ac2a4d6aa5f206b2892f6e9922e12e74e34fe39d47e","src/aead.rs":"140f77ffb5016836c970c39c6c3a42db9581a14b797b9cd05386d0dd0831fe63","src/aead_fuzzing.rs":"4e60d5a2ee6dedfd08602fa36318239e731244825df2cb801ca1d88f5f2a41c1","src/agent.rs":"9c413275bfa0a6f0c736d9925b4d5978d6b8c8a8ddb1c047b60e69ae1820858e","src/agentio.rs":"995e54772d6000d2773a2c57d67fc80756cab47dacfb4915e1ee49c5906d8495","src/auth.rs":"e821dac1511691151a6e64b7c7130a07d941dffad4529b2631f20ddd07d3f20c","src/cert.rs":"94450b248eed218b9227861ed81e557a543c0c88868fe1a434dc9c9f0f9651ae","src/constants.rs":"998e77bee88197a240032c1bfbddcff417a25ba82e576a0d2fe18ee9b63cefc7","src/ech.rs":"1d7b8760cd4e3cb2800fc9ff5fb2b1c89170fd379e43a9e1c626b7df0a59c6d3","src/err.rs":"38482dc0184802a5a503f540456f3af829641179eba32ed8ee7cc5d6a0afc6b3","src/exp.rs":"61586662407359c1ecb8ed4987bc3c702f26ba2e203a091a51b6d6363cbd510f","src/ext.rs":"361277879194dc32f741b8d1894afe5fd3fcc8eb244f7dd5914eeb959b85717d","src/hkdf.rs":"8d05bffddbd9950baa1d4920d42d29e3970caa308b32c1e59b9704dc257d87ab","src/hp.rs":"46a2023c421d89fda8d09b356b648272857fd20ee5cf5829143ac88402b32e4b","src/lib.rs":"2e486b5b18dcc6bf624080396e5f401fb0bed63db6dcd5e11c7614b7ce1bc196","src/once.rs":"b9850384899a1a016e839743d3489c0d4d916e1973746ef8c89872105d7d9736","src/p11.rs":"3e01b513b982fbc0b75bd66deeab8a9a355ede753091d2076c06111d36ecaf02","src/prio.rs":"38664072cafc4f7ce2dfe2e1e029afe87c423e01a60066c25a736644cb0ce379","src/replay.rs":"6c6a41c4d837ecd14e0dda05e9bf9a2eb6f3f4c3cc6eb8e41156dbd6bf3b1113","src/result.rs":"cef34dfcb907723e195b56501132e4560e250b327783cb5e41201da5b63e9b5c","src/secrets.rs":"48790a330994d892742048000bd12460b7eee2c3daaa444481b8527406d0a4c7","src/selfencrypt.rs":"036a6a22bd0ce9ee849a986f6faad4a550de3551bd53de1f71a7d7d9b4206e5b","src/ssl.rs":"821dbe19590a8716327628a1df7ba4184a9df454227eac60f0e793bc426fc315","src/time.rs":"b71fa74ad979d78765dd037c12f5e97eefb9fefc91be8f7c6f45e74b66ac11fc","tests/aead.rs":"98a737643ca41b2f36f6eda5a5dcb2acd420650ef22ab0a8cbed16c423734cc7","tests/agent.rs":"c191782187cb344186195fe377d9f351f2454e5b437f8d4ad88ec3edc8608a5d","tests/ext.rs":"eba9f03accdd598e38292ac88263a81b367d60d5a736a43117a3663de105ec48","tests/handshake.rs":"6ea3e5b3bc889d201b55f959b658a848c0ada54c956bda087b2ac8897a24a786","tests/hkdf.rs":"539235e9dcf2a56b72961a9a04f0080409adf6bf465bfad7c30026421b2d4326","tests/hp.rs":"e52a7d2f4387f2dfe8bfe1da5867e8e0d3eb51e171c6904e18b18c4343536af8","tests/init.rs":"baf680de62f5b06f38a112192a2e9a2ac9492f2cdbdf5f4b749ef18c94c9ac35","tests/selfencrypt.rs":"1125c858ec4e0a6994f34d162aa066cb003c61b324f268529ea04bcb641347cb"},"package":null}
|
2
third_party/rust/neqo-crypto/Cargo.toml
vendored
2
third_party/rust/neqo-crypto/Cargo.toml
vendored
@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "neqo-crypto"
|
||||
version = "0.4.29"
|
||||
version = "0.4.28"
|
||||
authors = ["Martin Thomson <mt@lowentropy.net>"]
|
||||
edition = "2018"
|
||||
build = "build.rs"
|
||||
|
@ -1 +1 @@
|
||||
{"files":{"Cargo.toml":"ac05a11304488e4ffb9bc8c5606df8903b2cc73b8337a44ea0bbf4293ee87cf5","src/client_events.rs":"18a8df593a7bfca802b401b97815436727a6a5b605be66dd3ab345b3ff645f9a","src/connection.rs":"f09c389a324dcd5b79cf34d9c21d9d2039a6700badb883945ec619287c8f690c","src/connection_client.rs":"7d5e77e20a008442e5df5c510c24186532bdbb8861561bf6e7645d7f40cf23b5","src/connection_server.rs":"259293df507af4257b00a654066902c5c5ecf41ec5ca04956905f12df784fa1f","src/control_stream_local.rs":"9be459bf678ebf5d9ffe73b5c0a47188ed4dc5b2780483c0ae7a0f9e90d9edb7","src/control_stream_remote.rs":"cc04bb2a6d622e841dbbab0611ca2e704172dcbb970192736dce96aecb97ab1f","src/hframe.rs":"8c8d9d646b3a6cd889e654a2a137f9e128432e4bbdcb151683bacb8182f7ebde","src/lib.rs":"497c84151b5198fc589f8754f52126a154098388d72990526de33ba25962d4e7","src/push_controller.rs":"35c5688e053157830c55b9133f6190349826143590f13a6b55768a79320313a7","src/push_stream.rs":"52024d01dbda0492e1487441a15edf17d24cf7ff4fe660707974b1e060eba1b5","src/qlog.rs":"29c0e3c4c9571eb7fe905967edeb1c4bc236b1e35a0e0f11a4a847f1d246681d","src/qpack_decoder_receiver.rs":"c8e1b84b52c097a798d6fb03c8321f676f31d68bc4000041b5dcb5797f8d66ac","src/qpack_encoder_receiver.rs":"11f6bc3e9170e952d92b583659c48764c375fa66cfa97fb115298a6021e84cfb","src/recv_message.rs":"6a94c793a2d8f021849e3caec7e6e59a30a1831341a00ecddcde2943b66d8a0f","src/send_message.rs":"7276268e5b190a1dc019d74034dad8a3c0c4b8cb409a135c733c038f9ccff6ff","src/server.rs":"8a998eb2d1409415248d7c290ca0e09e664d1adbf3588ab42aec633d27b35e0d","src/server_connection_events.rs":"762ddb87f700abe91ae1ae78ebbb87a88da0c0a341748b0751b01099870e9985","src/server_events.rs":"c8cdd838129ef6b1e77ba63608d20f6d297bca4e67f26a077d1c015a5e2a3b82","src/settings.rs":"467bd6991ec30e483195855f997f0bea3671a15b1a5b82e271f62ae424e0b2c3","src/stream_type_reader.rs":"a5022499b8e15ef76abd9dee55461919ee3fc1324f763abf113ca0d199c9325d","tests/httpconn.rs":"93a7c027ca6e61fe2a5612cf917fa25695dc752bdc750c3d4c176ea85a19815c"},"package":null}
|
||||
{"files":{"Cargo.toml":"78a2344ee20bc49a5feaeca71cf8f20b3a1acdca2e9c12f61b24a593e8ab58cd","src/client_events.rs":"18a8df593a7bfca802b401b97815436727a6a5b605be66dd3ab345b3ff645f9a","src/connection.rs":"8942eee838c78d8fde23c02e4699d17da586a25b9ccbc3d5d4675501cb2e2ee6","src/connection_client.rs":"2ce36d2d10944d128188a30594ab4c79ae41051bf6127dfbfe60a1da43506493","src/connection_server.rs":"259293df507af4257b00a654066902c5c5ecf41ec5ca04956905f12df784fa1f","src/control_stream_local.rs":"9be459bf678ebf5d9ffe73b5c0a47188ed4dc5b2780483c0ae7a0f9e90d9edb7","src/control_stream_remote.rs":"cc04bb2a6d622e841dbbab0611ca2e704172dcbb970192736dce96aecb97ab1f","src/hframe.rs":"8c8d9d646b3a6cd889e654a2a137f9e128432e4bbdcb151683bacb8182f7ebde","src/lib.rs":"497c84151b5198fc589f8754f52126a154098388d72990526de33ba25962d4e7","src/push_controller.rs":"35c5688e053157830c55b9133f6190349826143590f13a6b55768a79320313a7","src/push_stream.rs":"52024d01dbda0492e1487441a15edf17d24cf7ff4fe660707974b1e060eba1b5","src/qlog.rs":"29c0e3c4c9571eb7fe905967edeb1c4bc236b1e35a0e0f11a4a847f1d246681d","src/qpack_decoder_receiver.rs":"c8e1b84b52c097a798d6fb03c8321f676f31d68bc4000041b5dcb5797f8d66ac","src/qpack_encoder_receiver.rs":"11f6bc3e9170e952d92b583659c48764c375fa66cfa97fb115298a6021e84cfb","src/recv_message.rs":"6a94c793a2d8f021849e3caec7e6e59a30a1831341a00ecddcde2943b66d8a0f","src/send_message.rs":"7276268e5b190a1dc019d74034dad8a3c0c4b8cb409a135c733c038f9ccff6ff","src/server.rs":"8a998eb2d1409415248d7c290ca0e09e664d1adbf3588ab42aec633d27b35e0d","src/server_connection_events.rs":"762ddb87f700abe91ae1ae78ebbb87a88da0c0a341748b0751b01099870e9985","src/server_events.rs":"c8cdd838129ef6b1e77ba63608d20f6d297bca4e67f26a077d1c015a5e2a3b82","src/settings.rs":"467bd6991ec30e483195855f997f0bea3671a15b1a5b82e271f62ae424e0b2c3","src/stream_type_reader.rs":"9d00ce19947aba78b1f6e6b5ec8e125dca80af842b431b14f93a22d3772ecad2","tests/httpconn.rs":"93a7c027ca6e61fe2a5612cf917fa25695dc752bdc750c3d4c176ea85a19815c"},"package":null}
|
2
third_party/rust/neqo-http3/Cargo.toml
vendored
2
third_party/rust/neqo-http3/Cargo.toml
vendored
@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "neqo-http3"
|
||||
version = "0.4.29"
|
||||
version = "0.4.28"
|
||||
authors = ["Dragana Damjanovic <dragana.damjano@gmail.com>"]
|
||||
edition = "2018"
|
||||
license = "MIT/Apache-2.0"
|
||||
|
@ -208,8 +208,6 @@ impl Http3Connection {
|
||||
.insert(stream_id, Box::new(NewStreamTypeReader::new(stream_id)));
|
||||
}
|
||||
|
||||
#[allow(unknown_lints, renamed_and_removed_lints, clippy::unknown_clippy_lints)] // Until we require rust 1.51.
|
||||
#[allow(clippy::option_if_let_else)] // False positive as borrow scope isn't lexical here.
|
||||
fn stream_receive(&mut self, conn: &mut Connection, stream_id: u64) -> Res<ReceiveOutput> {
|
||||
qtrace!([self], "Readable stream {}.", stream_id);
|
||||
|
||||
|
154
third_party/rust/neqo-http3/src/connection_client.rs
vendored
154
third_party/rust/neqo-http3/src/connection_client.rs
vendored
@ -291,7 +291,6 @@ impl Http3Client {
|
||||
.conn
|
||||
.stream_create(StreamType::BiDi)
|
||||
.map_err(|e| Error::map_stream_create_errors(&e))?;
|
||||
self.conn.stream_keep_alive(id, true)?;
|
||||
|
||||
// Transform pseudo-header fields
|
||||
let mut final_headers = vec![
|
||||
@ -440,13 +439,10 @@ impl Http3Client {
|
||||
push_id: u64,
|
||||
buf: &mut [u8],
|
||||
) -> Res<(usize, bool)> {
|
||||
let stream_id = self
|
||||
.push_handler
|
||||
.borrow_mut()
|
||||
.get_active_stream_id(push_id)
|
||||
.ok_or(Error::InvalidStreamId)?;
|
||||
self.conn.stream_keep_alive(stream_id, true)?;
|
||||
self.read_response_data(now, stream_id, buf)
|
||||
let stream_id = self.push_handler.borrow_mut().get_active_stream_id(push_id);
|
||||
stream_id.map_or(Err(Error::InvalidStreamId), |id| {
|
||||
self.read_response_data(now, id, buf)
|
||||
})
|
||||
}
|
||||
|
||||
pub fn process(&mut self, dgram: Option<Datagram>, now: Instant) -> Output {
|
||||
@ -763,7 +759,7 @@ mod tests {
|
||||
use crate::qpack_encoder_receiver::EncoderRecvStream;
|
||||
use crate::settings::{HSetting, HSettingType, H3_RESERVED_SETTINGS};
|
||||
use crate::{Http3Server, RecvStream};
|
||||
use neqo_common::{event::Provider, qtrace, Datagram, Decoder, Encoder};
|
||||
use neqo_common::{event::Provider, Datagram, Decoder, Encoder};
|
||||
use neqo_crypto::{AllowZeroRtt, AntiReplay, ResumptionToken};
|
||||
use neqo_qpack::encoder::QPackEncoder;
|
||||
use neqo_transport::tparams::{self, TransportParameter};
|
||||
@ -818,7 +814,6 @@ mod tests {
|
||||
|
||||
// Encoder stream data
|
||||
const ENCODER_STREAM_DATA: &[u8] = &[0x2];
|
||||
const ENCODER_STREAM_CAP_INSTRUCTION: &[u8] = &[0x3f, 0x45];
|
||||
|
||||
// Encoder stream data with a change capacity instruction(0x3f, 0x45 = change capacity to 100)
|
||||
// This data will be send when 0-RTT is used and we already have a max_table_capacity from
|
||||
@ -934,9 +929,7 @@ mod tests {
|
||||
|
||||
pub fn create_control_stream(&mut self) {
|
||||
// Create control stream
|
||||
let control = self.conn.stream_create(StreamType::UniDi).unwrap();
|
||||
qtrace!(["TestServer"], "control stream: {}", control);
|
||||
self.control_stream_id = Some(control);
|
||||
self.control_stream_id = Some(self.conn.stream_create(StreamType::UniDi).unwrap());
|
||||
// Send stream type on the control stream.
|
||||
assert_eq!(
|
||||
self.conn
|
||||
@ -1133,7 +1126,7 @@ mod tests {
|
||||
assert!(client.events().any(connected));
|
||||
|
||||
assert_eq!(client.state(), Http3State::Connected);
|
||||
server.conn.process_input(out.dgram().unwrap(), now());
|
||||
mem::drop(server.conn.process(out.dgram(), now()));
|
||||
assert!(server.conn.state().connected());
|
||||
}
|
||||
|
||||
@ -1147,8 +1140,8 @@ mod tests {
|
||||
|
||||
fn send_and_receive_client_settings(client: &mut Http3Client, server: &mut TestServer) {
|
||||
// send and receive client settings
|
||||
let dgram = client.process(None, now()).dgram();
|
||||
server.conn.process_input(dgram.unwrap(), now());
|
||||
let out = client.process(None, now());
|
||||
mem::drop(server.conn.process(out.dgram(), now()));
|
||||
server.check_client_control_qpack_streams_no_resumption();
|
||||
}
|
||||
|
||||
@ -1162,8 +1155,8 @@ mod tests {
|
||||
|
||||
server.create_qpack_streams();
|
||||
// Send the server's control and qpack streams data.
|
||||
let dgram = server.conn.process(None, now()).dgram();
|
||||
client.process_input(dgram.unwrap(), now());
|
||||
let out = server.conn.process(None, now());
|
||||
client.process(out.dgram(), now());
|
||||
|
||||
// assert no error occured.
|
||||
assert_eq!(client.state(), Http3State::Connected);
|
||||
@ -1277,8 +1270,8 @@ mod tests {
|
||||
) -> u64 {
|
||||
let request_stream_id = make_request(client, close_sending_side, &[]);
|
||||
|
||||
let dgram = client.process(None, now()).dgram();
|
||||
server.conn.process_input(dgram.unwrap(), now());
|
||||
let out = client.process(None, now());
|
||||
mem::drop(server.conn.process(out.dgram(), now()));
|
||||
|
||||
// find the new request/response stream and send frame v on it.
|
||||
while let Some(e) = server.conn.next_event() {
|
||||
@ -1288,28 +1281,18 @@ mod tests {
|
||||
assert_eq!(stream_id.stream_type(), StreamType::BiDi);
|
||||
}
|
||||
ConnectionEvent::RecvStreamReadable { stream_id } => {
|
||||
if stream_id == CLIENT_SIDE_ENCODER_STREAM_ID {
|
||||
server.read_and_check_stream_data(
|
||||
stream_id,
|
||||
ENCODER_STREAM_CAP_INSTRUCTION,
|
||||
false,
|
||||
);
|
||||
} else {
|
||||
assert_eq!(stream_id, request_stream_id);
|
||||
server.read_and_check_stream_data(
|
||||
stream_id,
|
||||
EXPECTED_REQUEST_HEADER_FRAME,
|
||||
close_sending_side,
|
||||
);
|
||||
}
|
||||
assert_eq!(stream_id, request_stream_id);
|
||||
server.read_and_check_stream_data(
|
||||
stream_id,
|
||||
EXPECTED_REQUEST_HEADER_FRAME,
|
||||
close_sending_side,
|
||||
);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
let dgram = server.conn.process_output(now()).dgram();
|
||||
if let Some(d) = dgram {
|
||||
client.process_input(d, now());
|
||||
}
|
||||
let out = server.conn.process(None, now());
|
||||
client.process(out.dgram(), now());
|
||||
request_stream_id
|
||||
}
|
||||
|
||||
@ -1990,44 +1973,6 @@ mod tests {
|
||||
client.close(now(), 0, "");
|
||||
}
|
||||
|
||||
/// Force both endpoints into an idle state.
|
||||
/// Do this by opening unidirectional streams at both endpoints and sending
|
||||
/// a partial unidirectional stream type (which the receiver has to buffer),
|
||||
/// then delivering packets out of order.
|
||||
/// This forces the receiver to create an acknowledgment, which will allow
|
||||
/// the peer to become idle.
|
||||
fn force_idle(client: &mut Http3Client, server: &mut TestServer) {
|
||||
// Send a partial unidirectional stream ID.
|
||||
// Note that this can't close the stream as that causes the receiver
|
||||
// to send `MAX_STREAMS`, which would prevent it from becoming idle.
|
||||
fn dgram(c: &mut Connection) -> Datagram {
|
||||
let stream = c.stream_create(StreamType::UniDi).unwrap();
|
||||
let _ = c.stream_send(stream, &[0xc0]).unwrap();
|
||||
c.process_output(now()).dgram().unwrap()
|
||||
}
|
||||
|
||||
let d1 = dgram(&mut client.conn);
|
||||
let d2 = dgram(&mut client.conn);
|
||||
server.conn.process_input(d2, now());
|
||||
server.conn.process_input(d1, now());
|
||||
let d3 = dgram(&mut server.conn);
|
||||
let d4 = dgram(&mut server.conn);
|
||||
client.process_input(d4, now());
|
||||
client.process_input(d3, now());
|
||||
let ack = client.process_output(now()).dgram();
|
||||
server.conn.process_input(ack.unwrap(), now());
|
||||
}
|
||||
|
||||
/// The client should keep a connection alive if it has unanswered requests.
|
||||
#[test]
|
||||
fn fetch_keep_alive() {
|
||||
let (mut client, mut server, _request_stream_id) = connect_and_send_request(true);
|
||||
force_idle(&mut client, &mut server);
|
||||
|
||||
let idle_timeout = ConnectionParameters::default().get_idle_timeout();
|
||||
assert_eq!(client.process_output(now()).callback(), idle_timeout / 2);
|
||||
}
|
||||
|
||||
// Helper function: read response when a server sends HTTP_RESPONSE_2.
|
||||
fn read_response(client: &mut Http3Client, server: &mut Connection, request_stream_id: u64) {
|
||||
let out = server.process(None, now());
|
||||
@ -4347,7 +4292,8 @@ mod tests {
|
||||
let _ = server.conn.stream_send(request_stream_id, &[0, 0]).unwrap();
|
||||
server.conn.stream_close_send(request_stream_id).unwrap();
|
||||
let dgram = server.conn.process_output(now()).dgram();
|
||||
client.process_input(dgram.unwrap(), now());
|
||||
let dgram = client.process(dgram, now()).dgram();
|
||||
server.conn.process_input(dgram.unwrap(), now());
|
||||
|
||||
let data_readable_event = |e: &_| matches!(e, Http3ClientEvent::DataReadable { stream_id } if *stream_id == request_stream_id);
|
||||
assert_eq!(client.events().filter(data_readable_event).count(), 1);
|
||||
@ -4458,52 +4404,6 @@ mod tests {
|
||||
assert_eq!(client.cancel_push(0), Err(Error::InvalidStreamId));
|
||||
}
|
||||
|
||||
/// We can't keep the connection alive on the basis of a push promise,
|
||||
/// nor do we want to if the push promise is not interesting to the client.
|
||||
/// We do the next best thing, which is keep any push stream alive if the
|
||||
/// client reads from it.
|
||||
#[test]
|
||||
fn push_keep_alive() {
|
||||
let (mut client, mut server, request_stream_id) = connect_and_send_request(true);
|
||||
let idle_timeout = ConnectionParameters::default().get_idle_timeout();
|
||||
|
||||
// Promise a push and deliver, but don't close the stream.
|
||||
send_push_promise(&mut server.conn, request_stream_id, 0);
|
||||
server_send_response_and_exchange_packet(
|
||||
&mut client,
|
||||
&mut server,
|
||||
request_stream_id,
|
||||
HTTP_RESPONSE_2,
|
||||
true,
|
||||
);
|
||||
read_response_and_push_events(
|
||||
&mut client,
|
||||
&[PushPromiseInfo {
|
||||
push_id: 0,
|
||||
ref_stream_id: request_stream_id,
|
||||
}],
|
||||
&[], // No push streams yet.
|
||||
request_stream_id,
|
||||
);
|
||||
|
||||
// The client will become idle here.
|
||||
force_idle(&mut client, &mut server);
|
||||
assert_eq!(client.process_output(now()).callback(), idle_timeout);
|
||||
|
||||
// Reading push data will stop the client from being idle.
|
||||
let _ = send_push_data(&mut server.conn, 0, false);
|
||||
let dgram = server.conn.process_output(now()).dgram();
|
||||
client.process_input(dgram.unwrap(), now());
|
||||
|
||||
let mut buf = [0; 16];
|
||||
let (read, fin) = client.push_read_data(now(), 0, &mut buf).unwrap();
|
||||
assert!(read < buf.len());
|
||||
assert!(!fin);
|
||||
|
||||
force_idle(&mut client, &mut server);
|
||||
assert_eq!(client.process_output(now()).callback(), idle_timeout / 2);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn push_multiple() {
|
||||
// Connect and send a request
|
||||
@ -5782,7 +5682,7 @@ mod tests {
|
||||
assert_eq!(server.encoder.borrow_mut().stats().stream_cancelled_recv, 0);
|
||||
let out = client.process(None, now());
|
||||
mem::drop(server.conn.process(out.dgram(), now()));
|
||||
mem::drop(server.encoder_receiver.receive(&mut server.conn).unwrap());
|
||||
let _ = server.encoder_receiver.receive(&mut server.conn).unwrap();
|
||||
assert_eq!(server.encoder.borrow_mut().stats().stream_cancelled_recv, 1);
|
||||
}
|
||||
|
||||
@ -5819,7 +5719,7 @@ mod tests {
|
||||
assert_eq!(server.encoder.borrow_mut().stats().stream_cancelled_recv, 0);
|
||||
let out = client.process(None, now());
|
||||
mem::drop(server.conn.process(out.dgram(), now()));
|
||||
mem::drop(server.encoder_receiver.receive(&mut server.conn).unwrap());
|
||||
let _ = server.encoder_receiver.receive(&mut server.conn).unwrap();
|
||||
assert_eq!(server.encoder.borrow_mut().stats().stream_cancelled_recv, 0);
|
||||
}
|
||||
|
||||
@ -5875,7 +5775,7 @@ mod tests {
|
||||
|
||||
let out = client.process(None, now());
|
||||
mem::drop(server.conn.process(out.dgram(), now()));
|
||||
mem::drop(server.encoder_receiver.receive(&mut server.conn).unwrap());
|
||||
let _ = server.encoder_receiver.receive(&mut server.conn).unwrap();
|
||||
assert_eq!(server.encoder.borrow_mut().stats().stream_cancelled_recv, 1);
|
||||
}
|
||||
|
||||
@ -5889,7 +5789,7 @@ mod tests {
|
||||
assert_eq!(server.encoder.borrow_mut().stats().stream_cancelled_recv, 0);
|
||||
let out = client.process(None, now());
|
||||
mem::drop(server.conn.process(out.dgram(), now()));
|
||||
mem::drop(server.encoder_receiver.receive(&mut server.conn).unwrap());
|
||||
let _ = server.encoder_receiver.receive(&mut server.conn).unwrap();
|
||||
assert_eq!(server.encoder.borrow_mut().stats().stream_cancelled_recv, 0);
|
||||
}
|
||||
|
||||
|
@ -134,7 +134,7 @@ mod tests {
|
||||
self.decoder.receive(&mut self.conn_c).unwrap(),
|
||||
ReceiveOutput::NoOutput
|
||||
);
|
||||
assert!(!self.decoder.done());
|
||||
assert_eq!(self.decoder.done(), false);
|
||||
}
|
||||
self.conn_s
|
||||
.stream_send(self.stream_id, &enc[enc.len() - 1..])
|
||||
|
@ -1 +1 @@
|
||||
{"files":{"Cargo.toml":"15c60e64fb35778b880a684a9874d61a909abae736c8e100dc71e6a87002ae61","src/decoder.rs":"6ccf96c55b6cb8b787be30f6edcb75f1ce59867ccd111c7b78079ad5d89a8fe9","src/decoder_instructions.rs":"b2e466fc35272ab94772ae15c293dc4f85dc25a14888fc254a18650706876aac","src/encoder.rs":"647e565b89f3f1979628ca27c705b56a6dc660d4b5c2800f5425314870df46f0","src/encoder_instructions.rs":"56474d63efdc441e012efa23ed447a38503581442a49c1306e1b4f7acade79d7","src/header_block.rs":"d6bde101aceb9dac058bf462529a0cc971d2350afe044c52cd79b41e29de07df","src/huffman.rs":"e275c4b6dfd8503fc710c0fcb38f1be1bafbd8577b310026aad0e284653bebdd","src/huffman_decode_helper.rs":"2970c57f052878b727c2f764490c54184f5c2608e1d6aa961c3b01509e290122","src/huffman_table.rs":"06fea766a6276ac56c7ee0326faed800a742c15fda1f33bf2513e6cc6a5e6d27","src/lib.rs":"dde264a71d7bec4a2ff780355c86cb1a8ab08dbf4e929f65a3fd16ea9a4e2ebc","src/prefix.rs":"72c587c40aef4ed38cf13b2de91091d671611679be2a9da6f0b24abafaf50dc5","src/qlog.rs":"7618085e27bb3fb1f4d1c73ba501b9a293723293c4020b7cc4129676eb278131","src/qpack_send_buf.rs":"c59309ca5a14bf6ca5e9206a5c1add78843b9d125b83b15767754c884ded58b0","src/reader.rs":"a97c5d94cba1756735e389b127b9397b5ee673855cedbe7a34894e306ee64434","src/static_table.rs":"fda9d5c6f38f94b0bf92d3afdf8432dce6e27e189736596e16727090c77b78ec","src/stats.rs":"624dfa3b40858c304097bb0ce5b1be1bb4d7916b1abfc222f1aa705907009730","src/table.rs":"f7091bdd9ad1f8fe3b2298a7dbfd3d285c212d69569cda54f9bcf251cb758a21"},"package":null}
|
||||
{"files":{"Cargo.toml":"b9343135387a48e72585cb5f48bee7674bdb13e50f35c74e091f33282576735f","src/decoder.rs":"6ccf96c55b6cb8b787be30f6edcb75f1ce59867ccd111c7b78079ad5d89a8fe9","src/decoder_instructions.rs":"b2e466fc35272ab94772ae15c293dc4f85dc25a14888fc254a18650706876aac","src/encoder.rs":"4bbb9277af1fa86a1502beff84903640ff5938ed5aed72c9199d1cfa963494ba","src/encoder_instructions.rs":"56474d63efdc441e012efa23ed447a38503581442a49c1306e1b4f7acade79d7","src/header_block.rs":"d6bde101aceb9dac058bf462529a0cc971d2350afe044c52cd79b41e29de07df","src/huffman.rs":"e275c4b6dfd8503fc710c0fcb38f1be1bafbd8577b310026aad0e284653bebdd","src/huffman_decode_helper.rs":"2970c57f052878b727c2f764490c54184f5c2608e1d6aa961c3b01509e290122","src/huffman_table.rs":"06fea766a6276ac56c7ee0326faed800a742c15fda1f33bf2513e6cc6a5e6d27","src/lib.rs":"dde264a71d7bec4a2ff780355c86cb1a8ab08dbf4e929f65a3fd16ea9a4e2ebc","src/prefix.rs":"72c587c40aef4ed38cf13b2de91091d671611679be2a9da6f0b24abafaf50dc5","src/qlog.rs":"7618085e27bb3fb1f4d1c73ba501b9a293723293c4020b7cc4129676eb278131","src/qpack_send_buf.rs":"c59309ca5a14bf6ca5e9206a5c1add78843b9d125b83b15767754c884ded58b0","src/reader.rs":"a97c5d94cba1756735e389b127b9397b5ee673855cedbe7a34894e306ee64434","src/static_table.rs":"fda9d5c6f38f94b0bf92d3afdf8432dce6e27e189736596e16727090c77b78ec","src/stats.rs":"624dfa3b40858c304097bb0ce5b1be1bb4d7916b1abfc222f1aa705907009730","src/table.rs":"f7091bdd9ad1f8fe3b2298a7dbfd3d285c212d69569cda54f9bcf251cb758a21"},"package":null}
|
2
third_party/rust/neqo-qpack/Cargo.toml
vendored
2
third_party/rust/neqo-qpack/Cargo.toml
vendored
@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "neqo-qpack"
|
||||
version = "0.4.29"
|
||||
version = "0.4.28"
|
||||
authors = ["Dragana Damjanovic <dragana.damjano@gmail.com>"]
|
||||
edition = "2018"
|
||||
license = "MIT/Apache-2.0"
|
||||
|
2
third_party/rust/neqo-qpack/src/encoder.rs
vendored
2
third_party/rust/neqo-qpack/src/encoder.rs
vendored
@ -415,7 +415,7 @@ impl QPackEncoder {
|
||||
if !static_table && ref_entries.insert(index) {
|
||||
self.table.add_ref(index);
|
||||
}
|
||||
} else if can_block && !encoder_blocked {
|
||||
} else if can_block & !encoder_blocked {
|
||||
// Insert using an InsertWithNameLiteral instruction. This entry name does not match any name in the
|
||||
// tables therefore we cannot use any other instruction.
|
||||
match self.send_and_insert(conn, &name, &value) {
|
||||
|
File diff suppressed because one or more lines are too long
2
third_party/rust/neqo-transport/Cargo.toml
vendored
2
third_party/rust/neqo-transport/Cargo.toml
vendored
@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "neqo-transport"
|
||||
version = "0.4.29"
|
||||
version = "0.4.28"
|
||||
authors = ["EKR <ekr@rtfm.com>", "Andy Grover <agrover@mozilla.com>"]
|
||||
edition = "2018"
|
||||
license = "MIT/Apache-2.0"
|
||||
|
@ -7,6 +7,8 @@
|
||||
use std::cmp::{max, min};
|
||||
use std::time::{Duration, Instant};
|
||||
|
||||
pub const LOCAL_IDLE_TIMEOUT: Duration = Duration::from_secs(30);
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
/// There's a little bit of different behavior for resetting idle timeout. See
|
||||
/// -transport 10.2 ("Idle Timeout").
|
||||
@ -22,15 +24,23 @@ enum IdleTimeoutState {
|
||||
pub struct IdleTimeout {
|
||||
timeout: Duration,
|
||||
state: IdleTimeoutState,
|
||||
keep_alive_outstanding: bool,
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
impl IdleTimeout {
|
||||
pub fn new(timeout: Duration) -> Self {
|
||||
Self {
|
||||
timeout,
|
||||
state: IdleTimeoutState::Init,
|
||||
keep_alive_outstanding: false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for IdleTimeout {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
timeout: LOCAL_IDLE_TIMEOUT,
|
||||
state: IdleTimeoutState::Init,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -40,19 +50,12 @@ impl IdleTimeout {
|
||||
self.timeout = min(self.timeout, peer_timeout);
|
||||
}
|
||||
|
||||
pub fn expiry(&self, now: Instant, pto: Duration, keep_alive: bool) -> Instant {
|
||||
pub fn expiry(&self, now: Instant, pto: Duration) -> Instant {
|
||||
let start = match self.state {
|
||||
IdleTimeoutState::Init => now,
|
||||
IdleTimeoutState::PacketReceived(t) | IdleTimeoutState::AckElicitingPacketSent(t) => t,
|
||||
};
|
||||
let delay = if keep_alive {
|
||||
// For a keep-alive timer, wait for half the timeout interval, but be sure
|
||||
// not to wait too little or we will send many unnecessary probes.
|
||||
max(self.timeout / 2, pto)
|
||||
} else {
|
||||
max(self.timeout, pto * 3)
|
||||
};
|
||||
start + delay
|
||||
start + max(self.timeout, pto * 3)
|
||||
}
|
||||
|
||||
pub fn on_packet_sent(&mut self, now: Instant) {
|
||||
@ -82,19 +85,6 @@ impl IdleTimeout {
|
||||
}
|
||||
|
||||
pub fn expired(&self, now: Instant, pto: Duration) -> bool {
|
||||
now >= self.expiry(now, pto, false)
|
||||
}
|
||||
|
||||
pub fn send_keep_alive(&mut self, now: Instant, pto: Duration) -> bool {
|
||||
if !self.keep_alive_outstanding && now >= self.expiry(now, pto, true) {
|
||||
self.keep_alive_outstanding = true;
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
pub fn lost_keep_alive(&mut self) {
|
||||
self.keep_alive_outstanding = false;
|
||||
now >= self.expiry(now, pto)
|
||||
}
|
||||
}
|
||||
|
@ -64,6 +64,7 @@ mod state;
|
||||
pub mod test_internal;
|
||||
|
||||
use idle::IdleTimeout;
|
||||
pub use idle::LOCAL_IDLE_TIMEOUT;
|
||||
use params::PreferredAddressConfig;
|
||||
pub use params::{ConnectionParameters, ACK_RATIO_SCALE};
|
||||
use saved::SavedDatagrams;
|
||||
@ -378,7 +379,7 @@ impl Connection {
|
||||
saved_datagrams: SavedDatagrams::default(),
|
||||
crypto,
|
||||
acks: AckTracker::default(),
|
||||
idle_timeout: IdleTimeout::new(conn_params.get_idle_timeout()),
|
||||
idle_timeout: IdleTimeout::default(),
|
||||
streams: Streams::new(tphandler, role, events.clone()),
|
||||
connection_ids: ConnectionIdStore::default(),
|
||||
state_signaling: StateSignaling::Idle,
|
||||
@ -896,9 +897,8 @@ impl Connection {
|
||||
let rtt = path.rtt();
|
||||
let pto = rtt.pto(PacketNumberSpace::ApplicationData);
|
||||
|
||||
let keep_alive = self.streams.need_keep_alive();
|
||||
let idle_time = self.idle_timeout.expiry(now, pto, keep_alive);
|
||||
qtrace!([self], "Idle/keepalive timer {:?}", idle_time);
|
||||
let idle_time = self.idle_timeout.expiry(now, pto);
|
||||
qtrace!([self], "Idle timer {:?}", idle_time);
|
||||
delays.push(idle_time);
|
||||
|
||||
if let Some(lr_time) = self.loss_recovery.next_timeout(rtt) {
|
||||
@ -1859,53 +1859,6 @@ impl Connection {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
// Maybe send a probe. Return true if the packet was ack-eliciting.
|
||||
fn maybe_probe(
|
||||
&mut self,
|
||||
path: &PathRef,
|
||||
force_probe: bool,
|
||||
builder: &mut PacketBuilder,
|
||||
ack_end: usize,
|
||||
tokens: &mut Vec<RecoveryToken>,
|
||||
now: Instant,
|
||||
) -> bool {
|
||||
// Anything written after an ACK already elicits acknowledgment.
|
||||
// If we need to probe and nothing has been written, send a PING.
|
||||
if builder.len() > ack_end {
|
||||
return true;
|
||||
}
|
||||
let probe = if force_probe {
|
||||
// The packet might be empty, but we need to probe.
|
||||
true
|
||||
} else {
|
||||
let pto = path.borrow().rtt().pto(PacketNumberSpace::ApplicationData);
|
||||
if !builder.packet_empty() {
|
||||
// The packet only contains an ACK. Check whether we want to
|
||||
// force an ACK with a PING so we can stop tracking packets.
|
||||
self.loss_recovery.should_probe(pto, now)
|
||||
} else if self.streams.need_keep_alive() {
|
||||
// We need to keep the connection alive, including sending
|
||||
// a PING again.
|
||||
let keep_alive = self.idle_timeout.send_keep_alive(now, pto);
|
||||
if keep_alive {
|
||||
tokens.push(RecoveryToken::KeepAlive);
|
||||
}
|
||||
keep_alive
|
||||
} else {
|
||||
false
|
||||
}
|
||||
};
|
||||
if probe {
|
||||
// Nothing ack-eliciting and we need to probe; send PING.
|
||||
debug_assert_ne!(builder.remaining(), 0);
|
||||
builder.encode_varint(crate::frame::FRAME_TYPE_PING);
|
||||
let stats = &mut self.stats.borrow_mut().frame_tx;
|
||||
stats.ping += 1;
|
||||
stats.all += 1;
|
||||
}
|
||||
probe
|
||||
}
|
||||
|
||||
/// Write frames to the provided builder. Returns a list of tokens used for
|
||||
/// tracking loss or acknowledgment, whether any frame was ACK eliciting, and
|
||||
/// whether the packet was padded.
|
||||
@ -1958,17 +1911,40 @@ impl Connection {
|
||||
}
|
||||
}
|
||||
|
||||
// Maybe send a probe now, either to probe for losses or to keep the connection live.
|
||||
let force_probe = profile.should_probe(space);
|
||||
let ack_eliciting = self.maybe_probe(path, force_probe, builder, ack_end, &mut tokens, now);
|
||||
let stats = &mut self.stats.borrow_mut().frame_tx;
|
||||
// Anything written after an ACK already elicits acknowledgment.
|
||||
// If we need to probe and nothing has been written, send a PING.
|
||||
if builder.len() == ack_end {
|
||||
let probe = if profile.should_probe(space) {
|
||||
// The packet might be empty, but we need to probe.
|
||||
true
|
||||
} else if !builder.packet_empty() {
|
||||
// The packet only contains an ACK. Check whether we want to
|
||||
// force an ACK with a PING so we can stop tracking packets.
|
||||
let pto = path.borrow().rtt().pto(PacketNumberSpace::ApplicationData);
|
||||
self.loss_recovery.should_probe(pto, now)
|
||||
} else {
|
||||
false
|
||||
};
|
||||
if probe {
|
||||
// Nothing ack-eliciting and we need to probe; send PING.
|
||||
debug_assert_ne!(builder.remaining(), 0);
|
||||
builder.encode_varint(crate::frame::FRAME_TYPE_PING);
|
||||
if builder.len() > builder.limit() {
|
||||
return Err(Error::InternalError(11));
|
||||
}
|
||||
stats.ping += 1;
|
||||
stats.all += 1;
|
||||
}
|
||||
}
|
||||
// If this is not the primary path, this should be ack-eliciting.
|
||||
let ack_eliciting = builder.len() > ack_end;
|
||||
debug_assert!(primary || ack_eliciting);
|
||||
|
||||
// Add padding. Only pad 1-RTT packets so that we don't prevent coalescing.
|
||||
// And avoid padding packets that otherwise only contain ACK because adding PADDING
|
||||
// causes those packets to consume congestion window, which is not tracked (yet).
|
||||
// And avoid padding if we don't have a full MTU available.
|
||||
let stats = &mut self.stats.borrow_mut().frame_tx;
|
||||
let padded = if ack_eliciting && full_mtu && builder.pad() {
|
||||
stats.padding += 1;
|
||||
stats.all += 1;
|
||||
@ -2209,11 +2185,9 @@ impl Connection {
|
||||
|
||||
let max_ad = Duration::from_millis(remote.get_integer(tparams::MAX_ACK_DELAY));
|
||||
let min_ad = if remote.has_value(tparams::MIN_ACK_DELAY) {
|
||||
let min_ad = Duration::from_micros(remote.get_integer(tparams::MIN_ACK_DELAY));
|
||||
if min_ad > max_ad {
|
||||
return Err(Error::TransportParameterError);
|
||||
}
|
||||
Some(min_ad)
|
||||
Some(Duration::from_micros(
|
||||
remote.get_integer(tparams::MIN_ACK_DELAY),
|
||||
))
|
||||
} else {
|
||||
None
|
||||
};
|
||||
@ -2520,7 +2494,6 @@ impl Connection {
|
||||
RecoveryToken::NewConnectionId(ncid) => self.cid_manager.lost(ncid),
|
||||
RecoveryToken::RetireConnectionId(seqno) => self.paths.lost_retire_cid(*seqno),
|
||||
RecoveryToken::AckFrequency(rate) => self.paths.lost_ack_frequency(rate),
|
||||
RecoveryToken::KeepAlive => self.idle_timeout.lost_keep_alive(),
|
||||
_ => unreachable!("All other tokens are for streams"),
|
||||
}
|
||||
}
|
||||
@ -2788,17 +2761,6 @@ impl Connection {
|
||||
stream.set_stream_max_data(max_data);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Mark a receive stream as being important enough to keep the connection alive
|
||||
/// (if `keep` is `true`) or no longer important (if `keep` is `false`). If any
|
||||
/// stream is marked this way, PING frames will be used to keep the connection
|
||||
/// alive, even when there is no activity.
|
||||
/// # Errors
|
||||
/// Returns `InvalidStreamId` if a stream does not exist or the receiving
|
||||
/// side is closed.
|
||||
pub fn stream_keep_alive(&mut self, stream_id: u64, keep: bool) -> Res<()> {
|
||||
self.streams.keep_alive(stream_id.into(), keep)
|
||||
}
|
||||
}
|
||||
|
||||
impl EventProvider for Connection {
|
||||
|
@ -4,7 +4,7 @@
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
use crate::connection::{ConnectionIdManager, Role, LOCAL_ACTIVE_CID_LIMIT};
|
||||
use crate::connection::{ConnectionIdManager, Role, LOCAL_ACTIVE_CID_LIMIT, LOCAL_IDLE_TIMEOUT};
|
||||
use crate::recv_stream::RECV_BUFFER_SIZE;
|
||||
use crate::rtt::GRANULARITY;
|
||||
use crate::stream_id::StreamType;
|
||||
@ -12,7 +12,6 @@ use crate::tparams::{self, PreferredAddress, TransportParameter, TransportParame
|
||||
use crate::tracking::DEFAULT_ACK_DELAY;
|
||||
use crate::{CongestionControlAlgorithm, QuicVersion, Res};
|
||||
use std::convert::TryFrom;
|
||||
use std::time::Duration;
|
||||
|
||||
const LOCAL_MAX_DATA: u64 = 0x3FFF_FFFF_FFFF_FFFF; // 2^62-1
|
||||
const LOCAL_STREAM_LIMIT_BIDI: u64 = 16;
|
||||
@ -22,8 +21,6 @@ pub const ACK_RATIO_SCALE: u8 = 10;
|
||||
/// By default, aim to have the peer acknowledge 4 times per round trip time.
|
||||
/// See `ConnectionParameters.ack_ratio` for more.
|
||||
const DEFAULT_ACK_RATIO: u8 = 4 * ACK_RATIO_SCALE;
|
||||
/// The local value for the idle timeout period.
|
||||
const DEFAULT_IDLE_TIMEOUT: Duration = Duration::from_secs(30);
|
||||
|
||||
/// What to do with preferred addresses.
|
||||
#[derive(Debug, Clone)]
|
||||
@ -62,8 +59,6 @@ pub struct ConnectionParameters {
|
||||
/// acknowledgments every round trip, set the value to `5 * ACK_RATIO_SCALE`.
|
||||
/// Values less than `ACK_RATIO_SCALE` are clamped to `ACK_RATIO_SCALE`.
|
||||
ack_ratio: u8,
|
||||
/// The duration of the idle timeout for the connection.
|
||||
idle_timeout: Duration,
|
||||
preferred_address: PreferredAddressConfig,
|
||||
}
|
||||
|
||||
@ -79,7 +74,6 @@ impl Default for ConnectionParameters {
|
||||
max_streams_bidi: LOCAL_STREAM_LIMIT_BIDI,
|
||||
max_streams_uni: LOCAL_STREAM_LIMIT_UNI,
|
||||
ack_ratio: DEFAULT_ACK_RATIO,
|
||||
idle_timeout: DEFAULT_IDLE_TIMEOUT,
|
||||
preferred_address: PreferredAddressConfig::Default,
|
||||
}
|
||||
}
|
||||
@ -120,8 +114,6 @@ impl ConnectionParameters {
|
||||
}
|
||||
}
|
||||
|
||||
/// # Panics
|
||||
/// If v > 2^60 (the maximum allowed by the protocol).
|
||||
pub fn max_streams(mut self, stream_type: StreamType, v: u64) -> Self {
|
||||
assert!(v <= (1 << 60), "max_streams is too large");
|
||||
match stream_type {
|
||||
@ -136,8 +128,7 @@ impl ConnectionParameters {
|
||||
}
|
||||
|
||||
/// Get the maximum stream data that we will accept on different types of streams.
|
||||
/// # Panics
|
||||
/// If `StreamType::UniDi` and `false` are passed as that is not a valid combination.
|
||||
/// Asserts if `StreamType::UniDi` and `false` are passed as that is not a valid combination.
|
||||
pub fn get_max_stream_data(&self, stream_type: StreamType, remote: bool) -> u64 {
|
||||
match (stream_type, remote) {
|
||||
(StreamType::BiDi, false) => self.max_stream_data_bidi_local,
|
||||
@ -150,11 +141,8 @@ impl ConnectionParameters {
|
||||
}
|
||||
|
||||
/// Set the maximum stream data that we will accept on different types of streams.
|
||||
/// # Panics
|
||||
/// If `StreamType::UniDi` and `false` are passed as that is not a valid combination
|
||||
/// or if v >= 62 (the maximum allowed by the protocol).
|
||||
/// Asserts if `StreamType::UniDi` and `false` are passed as that is not a valid combination.
|
||||
pub fn max_stream_data(mut self, stream_type: StreamType, remote: bool, v: u64) -> Self {
|
||||
assert!(v < (1 << 62), "max stream data is too large");
|
||||
match (stream_type, remote) {
|
||||
(StreamType::BiDi, false) => {
|
||||
self.max_stream_data_bidi_local = v;
|
||||
@ -197,18 +185,6 @@ impl ConnectionParameters {
|
||||
self.ack_ratio
|
||||
}
|
||||
|
||||
/// # Panics
|
||||
/// If `timeout` is 2^62 milliseconds or more.
|
||||
pub fn idle_timeout(mut self, timeout: Duration) -> Self {
|
||||
assert!(timeout.as_millis() < (1 << 62), "idle timeout is too long");
|
||||
self.idle_timeout = timeout;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn get_idle_timeout(&self) -> Duration {
|
||||
self.idle_timeout
|
||||
}
|
||||
|
||||
pub fn create_transport_parameter(
|
||||
&self,
|
||||
role: Role,
|
||||
@ -216,6 +192,10 @@ impl ConnectionParameters {
|
||||
) -> Res<TransportParametersHandler> {
|
||||
let mut tps = TransportParametersHandler::default();
|
||||
// default parameters
|
||||
tps.local.set_integer(
|
||||
tparams::IDLE_TIMEOUT,
|
||||
u64::try_from(LOCAL_IDLE_TIMEOUT.as_millis()).unwrap(),
|
||||
);
|
||||
tps.local.set_integer(
|
||||
tparams::ACTIVE_CONNECTION_ID_LIMIT,
|
||||
u64::try_from(LOCAL_ACTIVE_CID_LIMIT).unwrap(),
|
||||
@ -250,10 +230,6 @@ impl ConnectionParameters {
|
||||
.set_integer(tparams::INITIAL_MAX_STREAMS_BIDI, self.max_streams_bidi);
|
||||
tps.local
|
||||
.set_integer(tparams::INITIAL_MAX_STREAMS_UNI, self.max_streams_uni);
|
||||
tps.local.set_integer(
|
||||
tparams::IDLE_TIMEOUT,
|
||||
u64::try_from(self.idle_timeout.as_millis()).unwrap_or(0),
|
||||
);
|
||||
if let PreferredAddressConfig::Address(preferred) = &self.preferred_address {
|
||||
if role == Role::Server {
|
||||
let (cid, srt) = cid_manager.preferred_address_cid()?;
|
||||
|
@ -12,7 +12,11 @@ use neqo_common::{qdebug, qinfo, Datagram};
|
||||
|
||||
/// The number of datagrams that are saved during the handshake when
|
||||
/// keys to decrypt them are not yet available.
|
||||
const MAX_SAVED_DATAGRAMS: usize = 4;
|
||||
///
|
||||
/// This value exceeds what should be possible to send during the handshake.
|
||||
/// Neither endpoint should have enough congestion window to send this
|
||||
/// much before the handshake completes.
|
||||
const MAX_SAVED_DATAGRAMS: usize = 32;
|
||||
|
||||
pub struct SavedDatagram {
|
||||
/// The datagram.
|
||||
|
@ -4,7 +4,7 @@
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
use super::super::{Connection, Output, State};
|
||||
use super::super::{Connection, Output, State, LOCAL_IDLE_TIMEOUT};
|
||||
use super::{
|
||||
assert_error, connect, connect_force_idle, connect_with_rtt, default_client, default_server,
|
||||
get_tokens, handshake, maybe_authenticate, send_something, CountingConnectionIdGenerator,
|
||||
@ -14,8 +14,7 @@ use crate::connection::AddressValidation;
|
||||
use crate::events::ConnectionEvent;
|
||||
use crate::path::PATH_MTU_V6;
|
||||
use crate::server::ValidateAddress;
|
||||
use crate::tparams::{TransportParameter, MIN_ACK_DELAY};
|
||||
use crate::tracking::DEFAULT_ACK_DELAY;
|
||||
use crate::tparams::TransportParameter;
|
||||
use crate::{
|
||||
ConnectionError, ConnectionParameters, EmptyConnectionIdGenerator, Error, QuicVersion,
|
||||
StreamType,
|
||||
@ -26,7 +25,6 @@ use neqo_crypto::{
|
||||
constants::TLS_CHACHA20_POLY1305_SHA256, generate_ech_keys, AuthenticationStatus,
|
||||
};
|
||||
use std::cell::RefCell;
|
||||
use std::convert::TryFrom;
|
||||
use std::mem;
|
||||
use std::net::{IpAddr, Ipv6Addr, SocketAddr};
|
||||
use std::rc::Rc;
|
||||
@ -533,7 +531,7 @@ fn reorder_handshake() {
|
||||
#[test]
|
||||
fn reorder_1rtt() {
|
||||
const RTT: Duration = Duration::from_millis(100);
|
||||
const PACKETS: usize = 4; // Many, but not enough to overflow cwnd.
|
||||
const PACKETS: usize = 6; // Many, but not enough to overflow cwnd.
|
||||
let mut client = default_client();
|
||||
let mut server = default_server();
|
||||
let mut now = now();
|
||||
@ -632,8 +630,7 @@ fn verify_pkt_honors_mtu() {
|
||||
let now = now();
|
||||
|
||||
let res = client.process(None, now);
|
||||
let idle_timeout = ConnectionParameters::default().get_idle_timeout();
|
||||
assert_eq!(res, Output::Callback(idle_timeout));
|
||||
assert_eq!(res, Output::Callback(LOCAL_IDLE_TIMEOUT));
|
||||
|
||||
// Try to send a large stream and verify first packet is correctly sized
|
||||
let stream_id = client.stream_create(StreamType::UniDi).unwrap();
|
||||
@ -1001,30 +998,3 @@ fn ech_retry_fallback_rejected() {
|
||||
Some(&ConnectionError::Transport(Error::PeerError(298)))
|
||||
); // A bad_certificate alert.
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn bad_min_ack_delay() {
|
||||
const EXPECTED_ERROR: ConnectionError =
|
||||
ConnectionError::Transport(Error::TransportParameterError);
|
||||
let mut server = default_server();
|
||||
let max_ad = u64::try_from(DEFAULT_ACK_DELAY.as_micros()).unwrap();
|
||||
server
|
||||
.set_local_tparam(MIN_ACK_DELAY, TransportParameter::Integer(max_ad + 1))
|
||||
.unwrap();
|
||||
let mut client = default_client();
|
||||
|
||||
let dgram = client.process_output(now()).dgram();
|
||||
let dgram = server.process(dgram, now()).dgram();
|
||||
client.process_input(dgram.unwrap(), now());
|
||||
client.authenticated(AuthenticationStatus::Ok, now());
|
||||
assert_eq!(client.state().error(), Some(&EXPECTED_ERROR));
|
||||
let dgram = client.process_output(now()).dgram();
|
||||
|
||||
server.process_input(dgram.unwrap(), now());
|
||||
assert_eq!(
|
||||
server.state().error(),
|
||||
Some(&ConnectionError::Transport(Error::PeerError(
|
||||
Error::TransportParameterError.code()
|
||||
)))
|
||||
);
|
||||
}
|
||||
|
@ -4,11 +4,10 @@
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
use super::super::{Connection, ConnectionParameters, IdleTimeout, Output, State};
|
||||
use super::super::{IdleTimeout, Output, State, LOCAL_IDLE_TIMEOUT};
|
||||
use super::{
|
||||
connect, connect_force_idle, connect_with_rtt, default_client, default_server,
|
||||
maybe_authenticate, new_client, new_server, send_and_receive, send_something, AT_LEAST_PTO,
|
||||
DEFAULT_STREAM_DATA,
|
||||
maybe_authenticate, send_and_receive, send_something, AT_LEAST_PTO,
|
||||
};
|
||||
use crate::packet::PacketBuilder;
|
||||
use crate::stats::FrameStats;
|
||||
@ -16,64 +15,30 @@ use crate::tparams::{self, TransportParameter};
|
||||
use crate::tracking::PacketNumberSpace;
|
||||
use crate::StreamType;
|
||||
|
||||
use neqo_common::{qtrace, Encoder};
|
||||
use neqo_common::Encoder;
|
||||
use std::mem;
|
||||
use std::time::{Duration, Instant};
|
||||
use std::time::Duration;
|
||||
use test_fixture::{self, now, split_datagram};
|
||||
|
||||
fn default_timeout() -> Duration {
|
||||
ConnectionParameters::default().get_idle_timeout()
|
||||
}
|
||||
|
||||
fn test_idle_timeout(client: &mut Connection, server: &mut Connection, timeout: Duration) {
|
||||
assert!(timeout > Duration::from_secs(1));
|
||||
connect_force_idle(client, server);
|
||||
|
||||
let now = now();
|
||||
|
||||
let res = client.process(None, now);
|
||||
assert_eq!(res, Output::Callback(timeout));
|
||||
|
||||
// Still connected after timeout-1 seconds. Idle timer not reset
|
||||
mem::drop(client.process(None, now + timeout - Duration::from_secs(1)));
|
||||
assert!(matches!(client.state(), State::Confirmed));
|
||||
|
||||
mem::drop(client.process(None, now + timeout));
|
||||
|
||||
// Not connected after timeout.
|
||||
assert!(matches!(client.state(), State::Closed(_)));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn idle_timeout() {
|
||||
let mut client = default_client();
|
||||
let mut server = default_server();
|
||||
test_idle_timeout(&mut client, &mut server, default_timeout());
|
||||
}
|
||||
connect_force_idle(&mut client, &mut server);
|
||||
|
||||
#[test]
|
||||
fn idle_timeout_custom_client() {
|
||||
const IDLE_TIMEOUT: Duration = Duration::from_secs(5);
|
||||
let mut client = new_client(ConnectionParameters::default().idle_timeout(IDLE_TIMEOUT));
|
||||
let mut server = default_server();
|
||||
test_idle_timeout(&mut client, &mut server, IDLE_TIMEOUT);
|
||||
}
|
||||
let now = now();
|
||||
|
||||
#[test]
|
||||
fn idle_timeout_custom_server() {
|
||||
const IDLE_TIMEOUT: Duration = Duration::from_secs(5);
|
||||
let mut client = default_client();
|
||||
let mut server = new_server(ConnectionParameters::default().idle_timeout(IDLE_TIMEOUT));
|
||||
test_idle_timeout(&mut client, &mut server, IDLE_TIMEOUT);
|
||||
}
|
||||
let res = client.process(None, now);
|
||||
assert_eq!(res, Output::Callback(LOCAL_IDLE_TIMEOUT));
|
||||
|
||||
#[test]
|
||||
fn idle_timeout_custom_both() {
|
||||
const LOWER_TIMEOUT: Duration = Duration::from_secs(5);
|
||||
const HIGHER_TIMEOUT: Duration = Duration::from_secs(10);
|
||||
let mut client = new_client(ConnectionParameters::default().idle_timeout(HIGHER_TIMEOUT));
|
||||
let mut server = new_server(ConnectionParameters::default().idle_timeout(LOWER_TIMEOUT));
|
||||
test_idle_timeout(&mut client, &mut server, LOWER_TIMEOUT);
|
||||
// Still connected after 29 seconds. Idle timer not reset
|
||||
mem::drop(client.process(None, now + LOCAL_IDLE_TIMEOUT - Duration::from_secs(1)));
|
||||
assert!(matches!(client.state(), State::Confirmed));
|
||||
|
||||
mem::drop(client.process(None, now + LOCAL_IDLE_TIMEOUT));
|
||||
|
||||
// Not connected after LOCAL_IDLE_TIMEOUT seconds.
|
||||
assert!(matches!(client.state(), State::Closed(_)));
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -81,7 +46,7 @@ fn asymmetric_idle_timeout() {
|
||||
const LOWER_TIMEOUT_MS: u64 = 1000;
|
||||
const LOWER_TIMEOUT: Duration = Duration::from_millis(LOWER_TIMEOUT_MS);
|
||||
// Sanity check the constant.
|
||||
assert!(LOWER_TIMEOUT < default_timeout());
|
||||
assert!(LOWER_TIMEOUT < LOCAL_IDLE_TIMEOUT);
|
||||
|
||||
let mut client = default_client();
|
||||
let mut server = default_server();
|
||||
@ -172,7 +137,7 @@ fn idle_send_packet1() {
|
||||
connect_force_idle(&mut client, &mut server);
|
||||
|
||||
let timeout = client.process(None, now).callback();
|
||||
assert_eq!(timeout, default_timeout());
|
||||
assert_eq!(timeout, LOCAL_IDLE_TIMEOUT);
|
||||
|
||||
now += Duration::from_secs(10);
|
||||
let dgram = send_and_receive(&mut client, &mut server, now);
|
||||
@ -180,7 +145,7 @@ fn idle_send_packet1() {
|
||||
|
||||
// Still connected after 39 seconds because idle timer reset by the
|
||||
// outgoing packet.
|
||||
now += default_timeout() - DELTA;
|
||||
now += LOCAL_IDLE_TIMEOUT - DELTA;
|
||||
let dgram = client.process(None, now).dgram();
|
||||
assert!(dgram.is_some()); // PTO
|
||||
assert!(client.state().connected());
|
||||
@ -204,7 +169,7 @@ fn idle_send_packet2() {
|
||||
let mut now = now();
|
||||
|
||||
let timeout = client.process(None, now).callback();
|
||||
assert_eq!(timeout, default_timeout());
|
||||
assert_eq!(timeout, LOCAL_IDLE_TIMEOUT);
|
||||
|
||||
// First transmission at t=GAP.
|
||||
now += GAP;
|
||||
@ -212,10 +177,10 @@ fn idle_send_packet2() {
|
||||
|
||||
// Second transmission at t=2*GAP.
|
||||
mem::drop(send_something(&mut client, now + GAP));
|
||||
assert!((GAP * 2 + DELTA) < default_timeout());
|
||||
assert!((GAP * 2 + DELTA) < LOCAL_IDLE_TIMEOUT);
|
||||
|
||||
// Still connected just before GAP + default_timeout().
|
||||
now += default_timeout() - DELTA;
|
||||
// Still connected just before GAP + LOCAL_IDLE_TIMEOUT.
|
||||
now += LOCAL_IDLE_TIMEOUT - DELTA;
|
||||
let dgram = client.process(None, now).dgram();
|
||||
assert!(dgram.is_some()); // PTO
|
||||
assert!(matches!(client.state(), State::Confirmed));
|
||||
@ -237,7 +202,7 @@ fn idle_recv_packet() {
|
||||
let now = now();
|
||||
|
||||
let res = client.process(None, now);
|
||||
assert_eq!(res, Output::Callback(default_timeout()));
|
||||
assert_eq!(res, Output::Callback(LOCAL_IDLE_TIMEOUT));
|
||||
|
||||
assert_eq!(client.stream_create(StreamType::BiDi).unwrap(), 0);
|
||||
assert_eq!(client.stream_send(0, b"hello").unwrap(), 5);
|
||||
@ -254,11 +219,11 @@ fn idle_recv_packet() {
|
||||
|
||||
// Still connected after 49 seconds because idle timer reset by received
|
||||
// packet
|
||||
mem::drop(client.process(None, now + default_timeout() + Duration::from_secs(19)));
|
||||
mem::drop(client.process(None, now + LOCAL_IDLE_TIMEOUT + Duration::from_secs(19)));
|
||||
assert!(matches!(client.state(), State::Confirmed));
|
||||
|
||||
// Not connected after 50 seconds.
|
||||
mem::drop(client.process(None, now + default_timeout() + Duration::from_secs(20)));
|
||||
mem::drop(client.process(None, now + LOCAL_IDLE_TIMEOUT + Duration::from_secs(20)));
|
||||
|
||||
assert!(matches!(client.state(), State::Closed(_)));
|
||||
}
|
||||
@ -328,7 +293,7 @@ fn idle_caching() {
|
||||
assert_eq!(client.stats().frame_rx.ping, ping_before_c + 1);
|
||||
assert_eq!(client.stats().frame_rx.ack, ack_before + 1);
|
||||
|
||||
let end = start + default_timeout() + (AT_LEAST_PTO / 2);
|
||||
let end = start + LOCAL_IDLE_TIMEOUT + (AT_LEAST_PTO / 2);
|
||||
// Now let the server Initial through, with the CRYPTO frame.
|
||||
let dgram = server.process_output(end).dgram();
|
||||
let (initial, _) = split_datagram(&dgram.unwrap());
|
||||
@ -341,262 +306,3 @@ fn idle_caching() {
|
||||
assert_eq!(*client.state(), State::Confirmed);
|
||||
assert_eq!(*server.state(), State::Confirmed);
|
||||
}
|
||||
|
||||
/// This function opens a bidirectional stream and leaves both endpoints
|
||||
/// idle, with the stream left open.
|
||||
/// The stream ID of that stream is returned (along with the new time).
|
||||
fn create_stream_idle_rtt(
|
||||
initiator: &mut Connection,
|
||||
responder: &mut Connection,
|
||||
mut now: Instant,
|
||||
rtt: Duration,
|
||||
) -> (Instant, u64) {
|
||||
let check_idle = |endpoint: &mut Connection, now: Instant| {
|
||||
let delay = endpoint.process_output(now).callback();
|
||||
qtrace!([endpoint], "idle timeout {:?}", delay);
|
||||
if rtt < default_timeout() / 4 {
|
||||
assert_eq!(default_timeout(), delay);
|
||||
} else {
|
||||
assert!(delay > default_timeout());
|
||||
}
|
||||
};
|
||||
|
||||
// Exchange a message each way on a stream.
|
||||
let stream = initiator.stream_create(StreamType::BiDi).unwrap();
|
||||
let _ = initiator.stream_send(stream, DEFAULT_STREAM_DATA).unwrap();
|
||||
let req = initiator.process_output(now).dgram();
|
||||
now += rtt / 2;
|
||||
responder.process_input(req.unwrap(), now);
|
||||
|
||||
// Reordering two packets from the responder forces the initiator to be idle.
|
||||
let _ = responder.stream_send(stream, DEFAULT_STREAM_DATA).unwrap();
|
||||
let resp1 = responder.process_output(now).dgram();
|
||||
let _ = responder.stream_send(stream, DEFAULT_STREAM_DATA).unwrap();
|
||||
let resp2 = responder.process_output(now).dgram();
|
||||
|
||||
now += rtt / 2;
|
||||
initiator.process_input(resp2.unwrap(), now);
|
||||
initiator.process_input(resp1.unwrap(), now);
|
||||
let ack = initiator.process_output(now).dgram();
|
||||
assert!(ack.is_some());
|
||||
check_idle(initiator, now);
|
||||
|
||||
// Receiving the ACK should return the responder to idle too.
|
||||
now += rtt / 2;
|
||||
responder.process_input(ack.unwrap(), now);
|
||||
check_idle(responder, now);
|
||||
|
||||
(now, stream)
|
||||
}
|
||||
|
||||
fn create_stream_idle(initiator: &mut Connection, responder: &mut Connection) -> u64 {
|
||||
let (_, stream) = create_stream_idle_rtt(initiator, responder, now(), Duration::new(0, 0));
|
||||
stream
|
||||
}
|
||||
|
||||
fn assert_idle(endpoint: &mut Connection, expected: Duration) {
|
||||
assert_eq!(endpoint.process_output(now()).callback(), expected);
|
||||
}
|
||||
|
||||
/// The creator of a stream marks it as important enough to use a keep-alive.
|
||||
#[test]
|
||||
fn keep_alive_initiator() {
|
||||
let mut client = default_client();
|
||||
let mut server = default_server();
|
||||
connect(&mut client, &mut server);
|
||||
let stream = create_stream_idle(&mut server, &mut client);
|
||||
let mut now = now();
|
||||
|
||||
// Marking the stream for keep-alive changes the idle timeout.
|
||||
server.stream_keep_alive(stream, true).unwrap();
|
||||
assert_idle(&mut server, default_timeout() / 2);
|
||||
|
||||
// Wait that long and the server should send a PING frame.
|
||||
now += default_timeout() / 2;
|
||||
let pings_before = server.stats().frame_tx.ping;
|
||||
let ping = server.process_output(now).dgram();
|
||||
assert!(ping.is_some());
|
||||
assert_eq!(server.stats().frame_tx.ping, pings_before + 1);
|
||||
}
|
||||
|
||||
/// The other peer can also keep it alive.
|
||||
#[test]
|
||||
fn keep_alive_responder() {
|
||||
let mut client = default_client();
|
||||
let mut server = default_server();
|
||||
connect(&mut client, &mut server);
|
||||
let stream = create_stream_idle(&mut server, &mut client);
|
||||
let mut now = now();
|
||||
|
||||
// Marking the stream for keep-alive changes the idle timeout.
|
||||
client.stream_keep_alive(stream, true).unwrap();
|
||||
assert_idle(&mut client, default_timeout() / 2);
|
||||
|
||||
// Wait that long and the client should send a PING frame.
|
||||
now += default_timeout() / 2;
|
||||
let pings_before = client.stats().frame_tx.ping;
|
||||
let ping = client.process_output(now).dgram();
|
||||
assert!(ping.is_some());
|
||||
assert_eq!(client.stats().frame_tx.ping, pings_before + 1);
|
||||
}
|
||||
|
||||
/// Unmark a stream as being keep-alive.
|
||||
#[test]
|
||||
fn keep_alive_unmark() {
|
||||
let mut client = default_client();
|
||||
let mut server = default_server();
|
||||
connect(&mut client, &mut server);
|
||||
let stream = create_stream_idle(&mut client, &mut server);
|
||||
|
||||
client.stream_keep_alive(stream, true).unwrap();
|
||||
assert_idle(&mut client, default_timeout() / 2);
|
||||
|
||||
client.stream_keep_alive(stream, false).unwrap();
|
||||
assert_idle(&mut client, default_timeout());
|
||||
}
|
||||
|
||||
/// The sender has something to send. Make it send it
|
||||
/// and cause the receiver to become idle by sending something
|
||||
/// else, reordering the packets, and consuming the ACK.
|
||||
/// Note that the sender might not be idle if the thing that it
|
||||
/// sends results in something in addition to an ACK.
|
||||
fn transfer_force_idle(sender: &mut Connection, receiver: &mut Connection) {
|
||||
let dgram = sender.process_output(now()).dgram();
|
||||
let chaff = send_something(sender, now());
|
||||
receiver.process_input(chaff, now());
|
||||
receiver.process_input(dgram.unwrap(), now());
|
||||
let ack = receiver.process_output(now()).dgram();
|
||||
sender.process_input(ack.unwrap(), now());
|
||||
}
|
||||
|
||||
/// Receiving the end of the stream stops keep-alives for that stream.
|
||||
/// Even if that data hasn't been read.
|
||||
#[test]
|
||||
fn keep_alive_close() {
|
||||
let mut client = default_client();
|
||||
let mut server = default_server();
|
||||
connect(&mut client, &mut server);
|
||||
let stream = create_stream_idle(&mut client, &mut server);
|
||||
|
||||
client.stream_keep_alive(stream, true).unwrap();
|
||||
assert_idle(&mut client, default_timeout() / 2);
|
||||
|
||||
client.stream_close_send(stream).unwrap();
|
||||
transfer_force_idle(&mut client, &mut server);
|
||||
assert_idle(&mut client, default_timeout() / 2);
|
||||
|
||||
server.stream_close_send(stream).unwrap();
|
||||
transfer_force_idle(&mut server, &mut client);
|
||||
assert_idle(&mut client, default_timeout());
|
||||
}
|
||||
|
||||
/// Receiving `RESET_STREAM` stops keep-alives for that stream, but only once
|
||||
/// the sending side is also closed.
|
||||
#[test]
|
||||
fn keep_alive_reset() {
|
||||
let mut client = default_client();
|
||||
let mut server = default_server();
|
||||
connect(&mut client, &mut server);
|
||||
let stream = create_stream_idle(&mut client, &mut server);
|
||||
|
||||
client.stream_keep_alive(stream, true).unwrap();
|
||||
assert_idle(&mut client, default_timeout() / 2);
|
||||
|
||||
client.stream_close_send(stream).unwrap();
|
||||
transfer_force_idle(&mut client, &mut server);
|
||||
assert_idle(&mut client, default_timeout() / 2);
|
||||
|
||||
server.stream_reset_send(stream, 0).unwrap();
|
||||
transfer_force_idle(&mut server, &mut client);
|
||||
assert_idle(&mut client, default_timeout());
|
||||
|
||||
// The client will fade away from here.
|
||||
let t = now() + (default_timeout() / 2);
|
||||
assert_eq!(client.process_output(t).callback(), default_timeout() / 2);
|
||||
let t = now() + default_timeout();
|
||||
assert_eq!(client.process_output(t), Output::None);
|
||||
}
|
||||
|
||||
/// Stopping sending also cancels the keep-alive.
|
||||
#[test]
|
||||
fn keep_alive_stop_sending() {
|
||||
let mut client = default_client();
|
||||
let mut server = default_server();
|
||||
connect(&mut client, &mut server);
|
||||
let stream = create_stream_idle(&mut client, &mut server);
|
||||
|
||||
client.stream_keep_alive(stream, true).unwrap();
|
||||
assert_idle(&mut client, default_timeout() / 2);
|
||||
|
||||
client.stream_close_send(stream).unwrap();
|
||||
client.stream_stop_sending(stream, 0).unwrap();
|
||||
transfer_force_idle(&mut client, &mut server);
|
||||
// The server will have sent RESET_STREAM, which the client will
|
||||
// want to acknowledge, so force that out.
|
||||
let junk = send_something(&mut server, now());
|
||||
let ack = client.process(Some(junk), now()).dgram();
|
||||
assert!(ack.is_some());
|
||||
|
||||
// Now the client should be idle.
|
||||
assert_idle(&mut client, default_timeout());
|
||||
}
|
||||
|
||||
/// Multiple active streams are tracked properly.
|
||||
#[test]
|
||||
fn keep_alive_multiple_stop() {
|
||||
let mut client = default_client();
|
||||
let mut server = default_server();
|
||||
connect(&mut client, &mut server);
|
||||
let stream = create_stream_idle(&mut client, &mut server);
|
||||
|
||||
client.stream_keep_alive(stream, true).unwrap();
|
||||
assert_idle(&mut client, default_timeout() / 2);
|
||||
|
||||
let other = client.stream_create(StreamType::BiDi).unwrap();
|
||||
client.stream_keep_alive(other, true).unwrap();
|
||||
assert_idle(&mut client, default_timeout() / 2);
|
||||
|
||||
client.stream_keep_alive(stream, false).unwrap();
|
||||
assert_idle(&mut client, default_timeout() / 2);
|
||||
|
||||
client.stream_keep_alive(other, false).unwrap();
|
||||
assert_idle(&mut client, default_timeout());
|
||||
}
|
||||
|
||||
/// If the RTT is too long relative to the idle timeout, the keep-alive is large too.
|
||||
#[test]
|
||||
fn keep_alive_large_rtt() {
|
||||
let mut client = default_client();
|
||||
let mut server = default_server();
|
||||
// Use an RTT that is large enough to cause the PTO timer to exceed half
|
||||
// the idle timeout.
|
||||
let rtt = default_timeout() * 3 / 4;
|
||||
let now = connect_with_rtt(&mut client, &mut server, now(), rtt);
|
||||
let (now, stream) = create_stream_idle_rtt(&mut server, &mut client, now, rtt);
|
||||
|
||||
// Calculating PTO here is tricky as RTTvar has eroded after multiple round trips.
|
||||
// Just check that the delay is larger than the baseline and the RTT.
|
||||
for endpoint in &mut [client, server] {
|
||||
endpoint.stream_keep_alive(stream, true).unwrap();
|
||||
let delay = endpoint.process_output(now).callback();
|
||||
qtrace!([endpoint], "new delay {:?}", delay);
|
||||
assert!(delay > default_timeout() / 2);
|
||||
assert!(delay > rtt);
|
||||
}
|
||||
}
|
||||
|
||||
/// Only the recipient of a unidirectional stream can keep it alive.
|
||||
#[test]
|
||||
fn keep_alive_uni() {
|
||||
let mut client = default_client();
|
||||
let mut server = default_server();
|
||||
connect(&mut client, &mut server);
|
||||
|
||||
let stream = client.stream_create(StreamType::UniDi).unwrap();
|
||||
client.stream_keep_alive(stream, true).unwrap_err();
|
||||
let _ = client.stream_send(stream, DEFAULT_STREAM_DATA).unwrap();
|
||||
let dgram = client.process_output(now()).dgram();
|
||||
|
||||
server.process_input(dgram.unwrap(), now());
|
||||
server.stream_keep_alive(stream, true).unwrap();
|
||||
}
|
||||
|
@ -5,7 +5,7 @@
|
||||
// except according to those terms.
|
||||
|
||||
use super::super::super::{ConnectionError, ERROR_AEAD_LIMIT_REACHED};
|
||||
use super::super::{Connection, ConnectionParameters, Error, Output, State, StreamType};
|
||||
use super::super::{Connection, Error, Output, State, StreamType, LOCAL_IDLE_TIMEOUT};
|
||||
use super::{
|
||||
connect, connect_force_idle, default_client, default_server, maybe_authenticate,
|
||||
send_and_receive, send_something, AT_LEAST_PTO,
|
||||
@ -104,8 +104,10 @@ fn key_update_client() {
|
||||
assert_update_blocked(&mut client);
|
||||
|
||||
// Initiating an update should only increase the write epoch.
|
||||
let idle_timeout = ConnectionParameters::default().get_idle_timeout();
|
||||
assert_eq!(Output::Callback(idle_timeout), client.process(None, now));
|
||||
assert_eq!(
|
||||
Output::Callback(LOCAL_IDLE_TIMEOUT),
|
||||
client.process(None, now)
|
||||
);
|
||||
assert_eq!(client.get_epochs(), (Some(4), Some(3)));
|
||||
|
||||
// Send something to propagate the update.
|
||||
@ -115,7 +117,7 @@ fn key_update_client() {
|
||||
assert_eq!(server.get_epochs(), (Some(4), Some(3)));
|
||||
let res = server.process(None, now);
|
||||
if let Output::Callback(t) = res {
|
||||
assert!(t < idle_timeout);
|
||||
assert!(t < LOCAL_IDLE_TIMEOUT);
|
||||
} else {
|
||||
panic!("server should now be waiting to clear keys");
|
||||
}
|
||||
@ -147,7 +149,7 @@ fn key_update_client() {
|
||||
// This is the first packet that the client has received from the server
|
||||
// with new keys, so its read timer just started.
|
||||
if let Output::Callback(t) = res {
|
||||
assert!(t < ConnectionParameters::default().get_idle_timeout());
|
||||
assert!(t < LOCAL_IDLE_TIMEOUT);
|
||||
} else {
|
||||
panic!("client should now be waiting to clear keys");
|
||||
}
|
||||
|
@ -6,7 +6,7 @@
|
||||
|
||||
#![deny(clippy::pedantic)]
|
||||
|
||||
use super::{Connection, ConnectionError, ConnectionId, Output, State};
|
||||
use super::{Connection, ConnectionError, ConnectionId, Output, State, LOCAL_IDLE_TIMEOUT};
|
||||
use crate::addr_valid::{AddressValidation, ValidateAddress};
|
||||
use crate::cc::{CWND_INITIAL_PKTS, CWND_MIN};
|
||||
use crate::cid::ConnectionIdRef;
|
||||
@ -17,7 +17,6 @@ use crate::stats::MAX_PTO_COUNTS;
|
||||
use crate::{ConnectionIdDecoder, ConnectionIdGenerator, ConnectionParameters, Error, StreamType};
|
||||
|
||||
use std::cell::RefCell;
|
||||
use std::cmp::min;
|
||||
use std::convert::TryFrom;
|
||||
use std::mem;
|
||||
use std::rc::Rc;
|
||||
@ -255,13 +254,15 @@ fn force_idle(
|
||||
// Delivering s1 should not have the client change its mind about the ACK.
|
||||
let ack = client.process(Some(s1), now).dgram();
|
||||
assert!(ack.is_some());
|
||||
let idle_timeout = min(
|
||||
client.conn_params.get_idle_timeout(),
|
||||
server.conn_params.get_idle_timeout(),
|
||||
assert_eq!(
|
||||
client.process_output(now),
|
||||
Output::Callback(LOCAL_IDLE_TIMEOUT)
|
||||
);
|
||||
assert_eq!(client.process_output(now), Output::Callback(idle_timeout));
|
||||
now += rtt / 2;
|
||||
assert_eq!(server.process(ack, now), Output::Callback(idle_timeout));
|
||||
assert_eq!(
|
||||
server.process(ack, now),
|
||||
Output::Callback(LOCAL_IDLE_TIMEOUT)
|
||||
);
|
||||
now
|
||||
}
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
use super::super::{Connection, ConnectionParameters, Output, State};
|
||||
use super::super::{Connection, Output, State, LOCAL_IDLE_TIMEOUT};
|
||||
use super::{
|
||||
assert_full_cwnd, connect, connect_force_idle, connect_rtt_idle, connect_with_rtt,
|
||||
default_client, default_server, fill_cwnd, maybe_authenticate, send_and_receive,
|
||||
@ -33,8 +33,7 @@ fn pto_works_basic() {
|
||||
let mut now = now();
|
||||
|
||||
let res = client.process(None, now);
|
||||
let idle_timeout = ConnectionParameters::default().get_idle_timeout();
|
||||
assert_eq!(res, Output::Callback(idle_timeout));
|
||||
assert_eq!(res, Output::Callback(LOCAL_IDLE_TIMEOUT));
|
||||
|
||||
// Send data on two streams
|
||||
let stream1 = client.stream_create(StreamType::UniDi).unwrap();
|
||||
@ -96,10 +95,7 @@ fn pto_works_ping() {
|
||||
let mut now = now();
|
||||
|
||||
let res = client.process(None, now);
|
||||
assert_eq!(
|
||||
res,
|
||||
Output::Callback(ConnectionParameters::default().get_idle_timeout())
|
||||
);
|
||||
assert_eq!(res, Output::Callback(LOCAL_IDLE_TIMEOUT));
|
||||
|
||||
now += Duration::from_secs(10);
|
||||
|
||||
@ -317,8 +313,7 @@ fn pto_handshake_complete() {
|
||||
// We don't send another PING because the handshake space is done and there
|
||||
// is nothing to probe for.
|
||||
|
||||
let idle_timeout = ConnectionParameters::default().get_idle_timeout();
|
||||
assert_eq!(cb, idle_timeout - expected_ack_delay);
|
||||
assert_eq!(cb, LOCAL_IDLE_TIMEOUT - expected_ack_delay);
|
||||
}
|
||||
|
||||
/// Test that PTO in the Handshake space contains the right frames.
|
||||
|
@ -6,15 +6,15 @@
|
||||
|
||||
use super::super::State;
|
||||
use super::{
|
||||
assert_error, connect, connect_force_idle, default_client, default_server, maybe_authenticate,
|
||||
new_client, new_server, send_something, DEFAULT_STREAM_DATA,
|
||||
connect, connect_force_idle, default_client, default_server, maybe_authenticate, new_client,
|
||||
send_something, DEFAULT_STREAM_DATA,
|
||||
};
|
||||
use crate::events::ConnectionEvent;
|
||||
use crate::recv_stream::RECV_BUFFER_SIZE;
|
||||
use crate::send_stream::{SendStreamState, SEND_BUFFER_SIZE};
|
||||
use crate::tparams::{self, TransportParameter};
|
||||
use crate::tracking::DEFAULT_ACK_PACKET_TOLERANCE;
|
||||
use crate::{Connection, ConnectionError, ConnectionParameters};
|
||||
use crate::ConnectionParameters;
|
||||
use crate::{Error, StreamId, StreamType};
|
||||
|
||||
use neqo_common::{event::Provider, qdebug};
|
||||
@ -137,63 +137,6 @@ fn report_fin_when_stream_closed_wo_data() {
|
||||
assert!(client.events().any(stream_readable));
|
||||
}
|
||||
|
||||
fn exchange_data(client: &mut Connection, server: &mut Connection) {
|
||||
let mut input = None;
|
||||
loop {
|
||||
let out = client.process(input, now()).dgram();
|
||||
let c_done = out.is_none();
|
||||
let out = server.process(out, now()).dgram();
|
||||
if out.is_none() && c_done {
|
||||
break;
|
||||
}
|
||||
input = out;
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn sending_max_data() {
|
||||
const SMALL_MAX_DATA: usize = 2048;
|
||||
|
||||
let mut client = default_client();
|
||||
let mut server = new_server(
|
||||
ConnectionParameters::default().max_data(u64::try_from(SMALL_MAX_DATA).unwrap()),
|
||||
);
|
||||
|
||||
connect(&mut client, &mut server);
|
||||
|
||||
let stream_id = client.stream_create(StreamType::UniDi).unwrap();
|
||||
assert_eq!(client.events().count(), 2); // SendStreamWritable, StateChange(connected)
|
||||
assert_eq!(stream_id, 2);
|
||||
assert_eq!(
|
||||
client.stream_avail_send_space(stream_id).unwrap(),
|
||||
SMALL_MAX_DATA
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
client
|
||||
.stream_send(stream_id, &[b'a'; SMALL_MAX_DATA + 1])
|
||||
.unwrap(),
|
||||
SMALL_MAX_DATA
|
||||
);
|
||||
|
||||
exchange_data(&mut client, &mut server);
|
||||
|
||||
let mut buf = vec![0; 40000];
|
||||
let (received, fin) = server.stream_recv(stream_id, &mut buf).unwrap();
|
||||
assert_eq!(received, SMALL_MAX_DATA);
|
||||
assert!(!fin);
|
||||
|
||||
let out = server.process(None, now()).dgram();
|
||||
client.process_input(out.unwrap(), now());
|
||||
|
||||
assert_eq!(
|
||||
client
|
||||
.stream_send(stream_id, &[b'a'; SMALL_MAX_DATA + 1])
|
||||
.unwrap(),
|
||||
SMALL_MAX_DATA
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn max_data() {
|
||||
const SMALL_MAX_DATA: usize = 16383;
|
||||
@ -219,7 +162,7 @@ fn max_data() {
|
||||
);
|
||||
assert_eq!(
|
||||
client
|
||||
.stream_send(stream_id, &[b'a'; SMALL_MAX_DATA + 1])
|
||||
.stream_send(stream_id, &vec![b'a'; RECV_BUFFER_SIZE].into_boxed_slice())
|
||||
.unwrap(),
|
||||
SMALL_MAX_DATA
|
||||
);
|
||||
@ -269,49 +212,6 @@ fn max_data() {
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn exceed_max_data() {
|
||||
const SMALL_MAX_DATA: usize = 1024;
|
||||
|
||||
let mut client = default_client();
|
||||
let mut server = new_server(
|
||||
ConnectionParameters::default().max_data(u64::try_from(SMALL_MAX_DATA).unwrap()),
|
||||
);
|
||||
|
||||
connect(&mut client, &mut server);
|
||||
|
||||
let stream_id = client.stream_create(StreamType::UniDi).unwrap();
|
||||
assert_eq!(client.events().count(), 2); // SendStreamWritable, StateChange(connected)
|
||||
assert_eq!(stream_id, 2);
|
||||
assert_eq!(
|
||||
client.stream_avail_send_space(stream_id).unwrap(),
|
||||
SMALL_MAX_DATA
|
||||
);
|
||||
assert_eq!(
|
||||
client
|
||||
.stream_send(stream_id, &[b'a'; SMALL_MAX_DATA + 1])
|
||||
.unwrap(),
|
||||
SMALL_MAX_DATA
|
||||
);
|
||||
|
||||
assert_eq!(client.stream_send(stream_id, b"hello").unwrap(), 0);
|
||||
|
||||
// Artificially trick the client to think that it has more flow control credit.
|
||||
client.streams.handle_max_data(100_000_000);
|
||||
assert_eq!(client.stream_send(stream_id, b"h").unwrap(), 1);
|
||||
|
||||
exchange_data(&mut client, &mut server);
|
||||
|
||||
assert_error(
|
||||
&client,
|
||||
&ConnectionError::Transport(Error::PeerError(Error::FlowControlError.code())),
|
||||
);
|
||||
assert_error(
|
||||
&server,
|
||||
&ConnectionError::Transport(Error::FlowControlError),
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
// If we send a stop_sending to the peer, we should not accept more data from the peer.
|
||||
fn do_not_accept_data_after_stop_sending() {
|
||||
@ -718,206 +618,3 @@ fn increase_decrease_flow_control() {
|
||||
change_flow_control(StreamType::UniDi, RECV_BUFFER_NEW_SMALLER);
|
||||
change_flow_control(StreamType::BiDi, RECV_BUFFER_NEW_SMALLER);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn session_flow_control_stop_sending_state_recv() {
|
||||
const SMALL_MAX_DATA: usize = 1024;
|
||||
|
||||
let mut client = default_client();
|
||||
let mut server = new_server(
|
||||
ConnectionParameters::default().max_data(u64::try_from(SMALL_MAX_DATA).unwrap()),
|
||||
);
|
||||
|
||||
connect(&mut client, &mut server);
|
||||
|
||||
let stream_id = client.stream_create(StreamType::UniDi).unwrap();
|
||||
assert_eq!(
|
||||
client.stream_avail_send_space(stream_id).unwrap(),
|
||||
SMALL_MAX_DATA
|
||||
);
|
||||
|
||||
// send 1 byte so that the server learns about the stream.
|
||||
assert_eq!(client.stream_send(stream_id, b"a").unwrap(), 1);
|
||||
|
||||
exchange_data(&mut client, &mut server);
|
||||
|
||||
server
|
||||
.stream_stop_sending(stream_id, Error::NoError.code())
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(
|
||||
client
|
||||
.stream_send(stream_id, &[b'a'; SMALL_MAX_DATA])
|
||||
.unwrap(),
|
||||
SMALL_MAX_DATA - 1
|
||||
);
|
||||
|
||||
// In this case the final size is only known after RESET frame is received.
|
||||
// The server sends STOP_SENDING -> the client sends RESET -> the server
|
||||
// sends MAX_DATA.
|
||||
let out = server.process(None, now()).dgram();
|
||||
let out = client.process(out, now()).dgram();
|
||||
// the client is still limited.
|
||||
let stream_id2 = client.stream_create(StreamType::UniDi).unwrap();
|
||||
assert_eq!(client.stream_avail_send_space(stream_id2).unwrap(), 0);
|
||||
let out = server.process(out, now()).dgram();
|
||||
client.process_input(out.unwrap(), now());
|
||||
assert_eq!(
|
||||
client.stream_avail_send_space(stream_id2).unwrap(),
|
||||
SMALL_MAX_DATA
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn session_flow_control_stop_sending_state_size_known() {
|
||||
const SMALL_MAX_DATA: usize = 1024;
|
||||
|
||||
let mut client = default_client();
|
||||
let mut server = new_server(
|
||||
ConnectionParameters::default().max_data(u64::try_from(SMALL_MAX_DATA).unwrap()),
|
||||
);
|
||||
|
||||
connect(&mut client, &mut server);
|
||||
|
||||
let stream_id = client.stream_create(StreamType::UniDi).unwrap();
|
||||
assert_eq!(
|
||||
client.stream_avail_send_space(stream_id).unwrap(),
|
||||
SMALL_MAX_DATA
|
||||
);
|
||||
|
||||
// send 1 byte so that the server learns about the stream.
|
||||
assert_eq!(
|
||||
client
|
||||
.stream_send(stream_id, &[b'a'; SMALL_MAX_DATA + 1])
|
||||
.unwrap(),
|
||||
SMALL_MAX_DATA
|
||||
);
|
||||
|
||||
let out1 = client.process(None, now()).dgram();
|
||||
// Delay this packet and let the server receive fin first (it will enter SizeKnown state).
|
||||
client.stream_close_send(stream_id).unwrap();
|
||||
let out2 = client.process(None, now()).dgram();
|
||||
|
||||
server.process_input(out2.unwrap(), now());
|
||||
|
||||
server
|
||||
.stream_stop_sending(stream_id, Error::NoError.code())
|
||||
.unwrap();
|
||||
|
||||
// In this case the final size is known when stream_stop_sending is called
|
||||
// and the server releases flow control immediately and sends STOP_SENDING and
|
||||
// MAX_DATA in the same packet.
|
||||
let out = server.process(out1, now()).dgram();
|
||||
client.process_input(out.unwrap(), now());
|
||||
|
||||
// The flow control should have been updated and the client can again send
|
||||
// SMALL_MAX_DATA.
|
||||
let stream_id2 = client.stream_create(StreamType::UniDi).unwrap();
|
||||
assert_eq!(
|
||||
client.stream_avail_send_space(stream_id2).unwrap(),
|
||||
SMALL_MAX_DATA
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn session_flow_control_stop_sending_state_data_recvd() {
|
||||
const SMALL_MAX_DATA: usize = 1024;
|
||||
|
||||
let mut client = default_client();
|
||||
let mut server = new_server(
|
||||
ConnectionParameters::default().max_data(u64::try_from(SMALL_MAX_DATA).unwrap()),
|
||||
);
|
||||
|
||||
connect(&mut client, &mut server);
|
||||
|
||||
let stream_id = client.stream_create(StreamType::UniDi).unwrap();
|
||||
assert_eq!(
|
||||
client.stream_avail_send_space(stream_id).unwrap(),
|
||||
SMALL_MAX_DATA
|
||||
);
|
||||
|
||||
// send 1 byte so that the server learns about the stream.
|
||||
assert_eq!(
|
||||
client
|
||||
.stream_send(stream_id, &[b'a'; SMALL_MAX_DATA + 1])
|
||||
.unwrap(),
|
||||
SMALL_MAX_DATA
|
||||
);
|
||||
|
||||
client.stream_close_send(stream_id).unwrap();
|
||||
|
||||
exchange_data(&mut client, &mut server);
|
||||
|
||||
// The stream is DataRecvd state
|
||||
server
|
||||
.stream_stop_sending(stream_id, Error::NoError.code())
|
||||
.unwrap();
|
||||
|
||||
exchange_data(&mut client, &mut server);
|
||||
|
||||
// The flow control should have been updated and the client can again send
|
||||
// SMALL_MAX_DATA.
|
||||
let stream_id2 = client.stream_create(StreamType::UniDi).unwrap();
|
||||
assert_eq!(
|
||||
client.stream_avail_send_space(stream_id2).unwrap(),
|
||||
SMALL_MAX_DATA
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn session_flow_control_affects_all_streams() {
|
||||
const SMALL_MAX_DATA: usize = 1024;
|
||||
|
||||
let mut client = default_client();
|
||||
let mut server = new_server(
|
||||
ConnectionParameters::default().max_data(u64::try_from(SMALL_MAX_DATA).unwrap()),
|
||||
);
|
||||
|
||||
connect(&mut client, &mut server);
|
||||
|
||||
let stream_id = client.stream_create(StreamType::UniDi).unwrap();
|
||||
assert_eq!(
|
||||
client.stream_avail_send_space(stream_id).unwrap(),
|
||||
SMALL_MAX_DATA
|
||||
);
|
||||
|
||||
let stream_id2 = client.stream_create(StreamType::UniDi).unwrap();
|
||||
assert_eq!(
|
||||
client.stream_avail_send_space(stream_id2).unwrap(),
|
||||
SMALL_MAX_DATA
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
client
|
||||
.stream_send(stream_id, &[b'a'; SMALL_MAX_DATA / 2 + 1])
|
||||
.unwrap(),
|
||||
SMALL_MAX_DATA / 2 + 1
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
client.stream_avail_send_space(stream_id).unwrap(),
|
||||
SMALL_MAX_DATA / 2 - 1
|
||||
);
|
||||
assert_eq!(
|
||||
client.stream_avail_send_space(stream_id2).unwrap(),
|
||||
SMALL_MAX_DATA / 2 - 1
|
||||
);
|
||||
|
||||
exchange_data(&mut client, &mut server);
|
||||
|
||||
let mut buf = [0x0; SMALL_MAX_DATA];
|
||||
let (read, _) = server.stream_recv(stream_id, &mut buf).unwrap();
|
||||
assert_eq!(read, SMALL_MAX_DATA / 2 + 1);
|
||||
|
||||
exchange_data(&mut client, &mut server);
|
||||
|
||||
assert_eq!(
|
||||
client.stream_avail_send_space(stream_id).unwrap(),
|
||||
SMALL_MAX_DATA
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
client.stream_avail_send_space(stream_id2).unwrap(),
|
||||
SMALL_MAX_DATA
|
||||
);
|
||||
}
|
||||
|
116
third_party/rust/neqo-transport/src/fc.rs
vendored
116
third_party/rust/neqo-transport/src/fc.rs
vendored
@ -17,7 +17,7 @@ use crate::recovery::RecoveryToken;
|
||||
use crate::stats::FrameStats;
|
||||
use crate::stream_id::{StreamId, StreamType};
|
||||
use crate::{Error, Res};
|
||||
use neqo_common::{qtrace, Role};
|
||||
use neqo_common::Role;
|
||||
|
||||
use std::convert::TryFrom;
|
||||
use std::fmt::Debug;
|
||||
@ -203,11 +203,6 @@ where
|
||||
max_active: u64,
|
||||
/// Last max allowed sent.
|
||||
max_allowed: u64,
|
||||
/// Item received, but not retired yet.
|
||||
/// This will be used for byte flow control: each stream will remember is largest byte
|
||||
/// offset received and session flow control will remember the sum of all bytes consumed
|
||||
/// by all streams.
|
||||
consumed: u64,
|
||||
/// Retired items.
|
||||
retired: u64,
|
||||
frame_pending: bool,
|
||||
@ -223,15 +218,19 @@ where
|
||||
subject,
|
||||
max_active: max,
|
||||
max_allowed: max,
|
||||
consumed: 0,
|
||||
retired: 0,
|
||||
frame_pending: false,
|
||||
}
|
||||
}
|
||||
|
||||
/// Check if received item exceeds the allowed flow control limit.
|
||||
pub fn check_allowed(&self, new_end: u64) -> bool {
|
||||
new_end < self.max_allowed
|
||||
}
|
||||
|
||||
/// Retired some items and maybe send flow control
|
||||
/// update.
|
||||
pub fn retire(&mut self, retired: u64) {
|
||||
pub fn retired(&mut self, retired: u64) {
|
||||
if retired <= self.retired {
|
||||
return;
|
||||
}
|
||||
@ -278,14 +277,6 @@ where
|
||||
self.frame_pending |= self.max_active < max;
|
||||
self.max_active = max;
|
||||
}
|
||||
|
||||
pub fn retired(&self) -> u64 {
|
||||
self.retired
|
||||
}
|
||||
|
||||
pub fn consumed(&self) -> u64 {
|
||||
self.consumed
|
||||
}
|
||||
}
|
||||
|
||||
impl ReceiverFlowControl<()> {
|
||||
@ -303,34 +294,6 @@ impl ReceiverFlowControl<()> {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn add_retired(&mut self, count: u64) {
|
||||
debug_assert!(self.retired + count <= self.consumed);
|
||||
self.retired += count;
|
||||
if self.retired + self.max_active / 2 > self.max_allowed {
|
||||
self.frame_pending = true;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn consume(&mut self, count: u64) -> Res<()> {
|
||||
if self.consumed + count > self.max_allowed {
|
||||
qtrace!(
|
||||
"Session RX window exceeded: consumed:{} new:{} limit:{}",
|
||||
self.consumed,
|
||||
count,
|
||||
self.max_allowed
|
||||
);
|
||||
return Err(Error::FlowControlError);
|
||||
}
|
||||
self.consumed += count;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for ReceiverFlowControl<()> {
|
||||
fn default() -> Self {
|
||||
Self::new((), 0)
|
||||
}
|
||||
}
|
||||
|
||||
impl ReceiverFlowControl<StreamId> {
|
||||
@ -355,34 +318,6 @@ impl ReceiverFlowControl<StreamId> {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn add_retired(&mut self, count: u64) {
|
||||
debug_assert!(self.retired + count <= self.consumed);
|
||||
self.retired += count;
|
||||
if self.retired + self.max_active / 2 > self.max_allowed {
|
||||
self.frame_pending = true;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_consumed(&mut self, consumed: u64) -> Res<u64> {
|
||||
if consumed <= self.consumed {
|
||||
return Ok(0);
|
||||
}
|
||||
|
||||
if consumed > self.max_allowed {
|
||||
qtrace!("Stream RX window exceeded: {}", consumed);
|
||||
return Err(Error::FlowControlError);
|
||||
}
|
||||
let new_consumed = consumed - self.consumed;
|
||||
self.consumed = consumed;
|
||||
Ok(new_consumed)
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for ReceiverFlowControl<StreamId> {
|
||||
fn default() -> Self {
|
||||
Self::new(StreamId::new(0), 0)
|
||||
}
|
||||
}
|
||||
|
||||
impl ReceiverFlowControl<StreamType> {
|
||||
@ -409,11 +344,6 @@ impl ReceiverFlowControl<StreamType> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Check if received item exceeds the allowed flow control limit.
|
||||
pub fn check_allowed(&self, new_end: u64) -> bool {
|
||||
new_end < self.max_allowed
|
||||
}
|
||||
|
||||
/// Retire given amount of additional data.
|
||||
/// This function will send flow updates immediately.
|
||||
pub fn add_retired(&mut self, count: u64) {
|
||||
@ -646,16 +576,16 @@ mod test {
|
||||
#[test]
|
||||
fn max_allowed_after_items_retired() {
|
||||
let mut fc = ReceiverFlowControl::new((), 100);
|
||||
fc.retire(49);
|
||||
fc.retired(49);
|
||||
assert_eq!(fc.frame_needed(), None);
|
||||
fc.retire(51);
|
||||
fc.retired(51);
|
||||
assert_eq!(fc.frame_needed(), Some(151));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn need_max_allowed_frame_after_loss() {
|
||||
let mut fc = ReceiverFlowControl::new((), 100);
|
||||
fc.retire(100);
|
||||
fc.retired(100);
|
||||
assert_eq!(fc.frame_needed(), Some(200));
|
||||
fc.frame_sent(200);
|
||||
assert_eq!(fc.frame_needed(), None);
|
||||
@ -666,11 +596,11 @@ mod test {
|
||||
#[test]
|
||||
fn no_max_allowed_frame_after_old_loss() {
|
||||
let mut fc = ReceiverFlowControl::new((), 100);
|
||||
fc.retire(51);
|
||||
fc.retired(51);
|
||||
assert_eq!(fc.frame_needed(), Some(151));
|
||||
fc.frame_sent(151);
|
||||
assert_eq!(fc.frame_needed(), None);
|
||||
fc.retire(102);
|
||||
fc.retired(102);
|
||||
assert_eq!(fc.frame_needed(), Some(202));
|
||||
fc.frame_sent(202);
|
||||
assert_eq!(fc.frame_needed(), None);
|
||||
@ -681,24 +611,24 @@ mod test {
|
||||
#[test]
|
||||
fn force_send_max_allowed() {
|
||||
let mut fc = ReceiverFlowControl::new((), 100);
|
||||
fc.retire(10);
|
||||
fc.retired(10);
|
||||
assert_eq!(fc.frame_needed(), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn multiple_retries_after_frame_pending_is_set() {
|
||||
let mut fc = ReceiverFlowControl::new((), 100);
|
||||
fc.retire(51);
|
||||
fc.retired(51);
|
||||
assert_eq!(fc.frame_needed(), Some(151));
|
||||
fc.retire(61);
|
||||
fc.retired(61);
|
||||
assert_eq!(fc.frame_needed(), Some(161));
|
||||
fc.retire(88);
|
||||
fc.retired(88);
|
||||
assert_eq!(fc.frame_needed(), Some(188));
|
||||
fc.retire(90);
|
||||
fc.retired(90);
|
||||
assert_eq!(fc.frame_needed(), Some(190));
|
||||
fc.frame_sent(190);
|
||||
assert_eq!(fc.frame_needed(), None);
|
||||
fc.retire(141);
|
||||
fc.retired(141);
|
||||
assert_eq!(fc.frame_needed(), Some(241));
|
||||
fc.frame_sent(241);
|
||||
assert_eq!(fc.frame_needed(), None);
|
||||
@ -707,11 +637,11 @@ mod test {
|
||||
#[test]
|
||||
fn new_retired_before_loss() {
|
||||
let mut fc = ReceiverFlowControl::new((), 100);
|
||||
fc.retire(51);
|
||||
fc.retired(51);
|
||||
assert_eq!(fc.frame_needed(), Some(151));
|
||||
fc.frame_sent(151);
|
||||
assert_eq!(fc.frame_needed(), None);
|
||||
fc.retire(62);
|
||||
fc.retired(62);
|
||||
assert_eq!(fc.frame_needed(), None);
|
||||
fc.frame_lost(151);
|
||||
assert_eq!(fc.frame_needed(), Some(162));
|
||||
@ -724,10 +654,10 @@ mod test {
|
||||
// There is no MAX_STREAM_DATA frame needed.
|
||||
assert_eq!(fc.frame_needed(), None);
|
||||
// We can still retire more than 50.
|
||||
fc.retire(60);
|
||||
fc.retired(60);
|
||||
// There is no MAX_STREAM_DATA fame needed yet.
|
||||
assert_eq!(fc.frame_needed(), None);
|
||||
fc.retire(76);
|
||||
fc.retired(76);
|
||||
assert_eq!(fc.frame_needed(), Some(126));
|
||||
|
||||
// Increase max_active.
|
||||
@ -735,7 +665,7 @@ mod test {
|
||||
assert_eq!(fc.frame_needed(), Some(136));
|
||||
|
||||
// We can retire more than 60.
|
||||
fc.retire(136);
|
||||
fc.retired(136);
|
||||
assert_eq!(fc.frame_needed(), Some(196));
|
||||
}
|
||||
|
||||
|
132
third_party/rust/neqo-transport/src/flow_mgr.rs
vendored
Normal file
132
third_party/rust/neqo-transport/src/flow_mgr.rs
vendored
Normal file
@ -0,0 +1,132 @@
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// Tracks possibly-redundant flow control signals from other code and converts
|
||||
// into flow control frames needing to be sent to the remote.
|
||||
|
||||
use std::collections::HashMap;
|
||||
use std::mem;
|
||||
|
||||
use neqo_common::qwarn;
|
||||
use smallvec::{smallvec, SmallVec};
|
||||
|
||||
use crate::frame::{write_varint_frame, Frame};
|
||||
use crate::packet::PacketBuilder;
|
||||
use crate::recovery::RecoveryToken;
|
||||
use crate::stats::FrameStats;
|
||||
use crate::stream_id::{StreamIndex, StreamIndexes, StreamType};
|
||||
use crate::Res;
|
||||
|
||||
type FlowFrame = Frame<'static>;
|
||||
pub type FlowControlRecoveryToken = FlowFrame;
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
pub struct FlowMgr {
|
||||
// (stream_type, discriminant) as key ensures only 1 of every frame type
|
||||
// per stream type will be queued.
|
||||
from_stream_types: HashMap<(StreamType, mem::Discriminant<FlowFrame>), FlowFrame>,
|
||||
}
|
||||
|
||||
impl FlowMgr {
|
||||
// -- frames scoped on stream type --
|
||||
|
||||
pub fn max_streams(&mut self, stream_limit: StreamIndex, stream_type: StreamType) {
|
||||
let frame = Frame::MaxStreams {
|
||||
stream_type,
|
||||
maximum_streams: stream_limit,
|
||||
};
|
||||
self.from_stream_types
|
||||
.insert((stream_type, mem::discriminant(&frame)), frame);
|
||||
}
|
||||
|
||||
pub fn streams_blocked(&mut self, stream_limit: StreamIndex, stream_type: StreamType) {
|
||||
let frame = Frame::StreamsBlocked {
|
||||
stream_type,
|
||||
stream_limit,
|
||||
};
|
||||
self.from_stream_types
|
||||
.insert((stream_type, mem::discriminant(&frame)), frame);
|
||||
}
|
||||
|
||||
pub fn peek(&self) -> Option<&Frame> {
|
||||
if let Some(key) = self.from_stream_types.keys().next() {
|
||||
return self.from_stream_types.get(key);
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
pub(crate) fn lost(&mut self, token: &FlowControlRecoveryToken, indexes: &mut StreamIndexes) {
|
||||
match *token {
|
||||
// Resend MaxStreams if lost (with updated value)
|
||||
Frame::MaxStreams { stream_type, .. } => {
|
||||
let local_max = match stream_type {
|
||||
StreamType::BiDi => &mut indexes.local_max_stream_bidi,
|
||||
StreamType::UniDi => &mut indexes.local_max_stream_uni,
|
||||
};
|
||||
|
||||
self.max_streams(*local_max, stream_type)
|
||||
}
|
||||
// Only resend "*Blocked" frames if still blocked
|
||||
Frame::StreamsBlocked { stream_type, .. } => match stream_type {
|
||||
StreamType::UniDi => {
|
||||
if indexes.remote_next_stream_uni >= indexes.remote_max_stream_uni {
|
||||
self.streams_blocked(indexes.remote_max_stream_uni, StreamType::UniDi);
|
||||
}
|
||||
}
|
||||
StreamType::BiDi => {
|
||||
if indexes.remote_next_stream_bidi >= indexes.remote_max_stream_bidi {
|
||||
self.streams_blocked(indexes.remote_max_stream_bidi, StreamType::BiDi);
|
||||
}
|
||||
}
|
||||
},
|
||||
_ => qwarn!("Unexpected Flow frame {:?} lost, not re-sent", token),
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn write_frames(
|
||||
&mut self,
|
||||
builder: &mut PacketBuilder,
|
||||
tokens: &mut Vec<RecoveryToken>,
|
||||
stats: &mut FrameStats,
|
||||
) -> Res<()> {
|
||||
while let Some(frame) = self.peek() {
|
||||
// All these frames are bags of varints, so we can just extract the
|
||||
// varints and use common code for writing.
|
||||
let (mut values, stat): (SmallVec<[_; 3]>, _) = match frame {
|
||||
Frame::MaxStreams {
|
||||
maximum_streams, ..
|
||||
} => (smallvec![maximum_streams.as_u64()], &mut stats.max_streams),
|
||||
Frame::StreamsBlocked { stream_limit, .. } => {
|
||||
(smallvec![stream_limit.as_u64()], &mut stats.streams_blocked)
|
||||
}
|
||||
_ => unreachable!("{:?}", frame),
|
||||
};
|
||||
values.insert(0, frame.get_type());
|
||||
debug_assert!(!values.spilled());
|
||||
|
||||
if write_varint_frame(builder, &values)? {
|
||||
tokens.push(RecoveryToken::Flow(self.next().unwrap()));
|
||||
*stat += 1;
|
||||
} else {
|
||||
return Ok(());
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl Iterator for FlowMgr {
|
||||
type Item = FlowFrame;
|
||||
|
||||
/// Used by generator to get a flow control frame.
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
let first_key = self.from_stream_types.keys().next();
|
||||
if let Some(&first_key) = first_key {
|
||||
return self.from_stream_types.remove(&first_key);
|
||||
}
|
||||
None
|
||||
}
|
||||
}
|
@ -20,6 +20,7 @@ use neqo_common::{qdebug, qlog::NeqoQlog, qtrace, qwarn};
|
||||
|
||||
use crate::ackrate::AckRate;
|
||||
use crate::cid::ConnectionIdEntry;
|
||||
use crate::connection::LOCAL_IDLE_TIMEOUT;
|
||||
use crate::crypto::CryptoRecoveryToken;
|
||||
use crate::packet::PacketNumber;
|
||||
use crate::path::{Path, PathRef};
|
||||
@ -51,7 +52,6 @@ pub enum RecoveryToken {
|
||||
Stream(StreamRecoveryToken),
|
||||
Crypto(CryptoRecoveryToken),
|
||||
HandshakeDone,
|
||||
KeepAlive, // Special PING.
|
||||
NewToken(usize),
|
||||
NewConnectionId(ConnectionIdEntry<[u8; 16]>),
|
||||
RetireConnectionId(u64),
|
||||
@ -831,7 +831,7 @@ impl LossRecovery {
|
||||
) -> Duration {
|
||||
rtt.pto(pn_space)
|
||||
.checked_mul(1 << pto_state.map_or(0, |p| p.count))
|
||||
.unwrap_or_else(|| Duration::from_secs(3600))
|
||||
.unwrap_or(LOCAL_IDLE_TIMEOUT * 2)
|
||||
}
|
||||
|
||||
/// Get the current PTO period for the given packet number space.
|
||||
|
980
third_party/rust/neqo-transport/src/recv_stream.rs
vendored
980
third_party/rust/neqo-transport/src/recv_stream.rs
vendored
File diff suppressed because it is too large
Load Diff
23
third_party/rust/neqo-transport/src/streams.rs
vendored
23
third_party/rust/neqo-transport/src/streams.rs
vendored
@ -86,11 +86,11 @@ impl Streams {
|
||||
Frame::ResetStream {
|
||||
stream_id,
|
||||
application_error_code,
|
||||
final_size,
|
||||
..
|
||||
} => {
|
||||
stats.reset_stream += 1;
|
||||
if let (_, Some(rs)) = self.obtain_stream(stream_id)? {
|
||||
rs.reset(application_error_code, final_size)?;
|
||||
rs.reset(application_error_code);
|
||||
}
|
||||
}
|
||||
Frame::StopSending {
|
||||
@ -279,8 +279,7 @@ impl Streams {
|
||||
| RecoveryToken::StreamDataBlocked { .. }
|
||||
| RecoveryToken::MaxStreamData { .. }
|
||||
| RecoveryToken::StreamsBlocked { .. }
|
||||
| RecoveryToken::MaxStreams { .. }
|
||||
| RecoveryToken::MaxData(_) => (),
|
||||
| RecoveryToken::MaxStreams { .. } => (),
|
||||
_ => unreachable!("This is not a stream RecoveryToken"),
|
||||
}
|
||||
}
|
||||
@ -330,7 +329,6 @@ impl Streams {
|
||||
RecvStream::new(
|
||||
next_stream_id,
|
||||
recv_initial_max_stream_data,
|
||||
Rc::clone(&self.receiver_fc),
|
||||
self.events.clone(),
|
||||
),
|
||||
);
|
||||
@ -404,12 +402,7 @@ impl Streams {
|
||||
|
||||
self.recv.insert(
|
||||
new_id,
|
||||
RecvStream::new(
|
||||
new_id,
|
||||
recv_initial_max_stream_data,
|
||||
Rc::clone(&self.receiver_fc),
|
||||
self.events.clone(),
|
||||
),
|
||||
RecvStream::new(new_id, recv_initial_max_stream_data, self.events.clone()),
|
||||
);
|
||||
}
|
||||
Ok(new_id.as_u64())
|
||||
@ -482,12 +475,4 @@ impl Streams {
|
||||
pub fn get_recv_stream_mut(&mut self, stream_id: StreamId) -> Res<&mut RecvStream> {
|
||||
self.recv.get_mut(stream_id)
|
||||
}
|
||||
|
||||
pub fn keep_alive(&mut self, stream_id: StreamId, keep: bool) -> Res<()> {
|
||||
self.recv.keep_alive(stream_id, keep)
|
||||
}
|
||||
|
||||
pub fn need_keep_alive(&mut self) -> bool {
|
||||
self.recv.need_keep_alive()
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user