deploy: 008d821f6e6e6a875a90ec3db3f54973d6c84eff

This commit is contained in:
rklaehn
2026-02-26 10:38:36 +00:00
parent 2508742e05
commit 02133dce48
18 changed files with 437 additions and 436 deletions
+1 -1
View File
@@ -1 +1 @@
<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta name="generator" content="rustdoc"><meta name="description" content="Documentation for Rustdoc"><title>Help</title><script>if(window.location.protocol!=="file:")document.head.insertAdjacentHTML("beforeend","SourceSerif4-Regular-6b053e98.ttf.woff2,FiraSans-Italic-81dc35de.woff2,FiraSans-Regular-0fe48ade.woff2,FiraSans-MediumItalic-ccf7e434.woff2,FiraSans-Medium-e1aa3f0a.woff2,SourceCodePro-Regular-8badfe75.ttf.woff2,SourceCodePro-Semibold-aa29a496.ttf.woff2".split(",").map(f=>`<link rel="preload" as="font" type="font/woff2"href="./static.files/${f}">`).join(""))</script><link rel="stylesheet" href="./static.files/normalize-9960930a.css"><link rel="stylesheet" href="./static.files/rustdoc-ca0dd0c4.css"><meta name="rustdoc-vars" data-root-path="./" data-static-root-path="./static.files/" data-current-crate="data_transfer" data-themes="" data-resource-suffix="" data-rustdoc-version="1.92.0-nightly (b6f0945e4 2025-10-08)" data-channel="nightly" data-search-js="search-8d3311b9.js" data-stringdex-js="stringdex-828709d0.js" data-settings-js="settings-c38705f0.js" ><script src="./static.files/storage-e2aeef58.js"></script><script defer src="./static.files/main-ce535bd0.js"></script><noscript><link rel="stylesheet" href="./static.files/noscript-263c88ec.css"></noscript><link rel="alternate icon" type="image/png" href="./static.files/favicon-32x32-eab170b8.png"><link rel="icon" type="image/svg+xml" href="./static.files/favicon-044be391.svg"></head><body class="rustdoc mod sys"><!--[if lte IE 11]><div class="warning">This old browser is unsupported and will most likely display funky things.</div><![endif]--><rustdoc-topbar><h2><a href="#">All</a></h2></rustdoc-topbar><nav class="sidebar"><div class="sidebar-crate"><a class="logo-container" href="./index.html"><img class="rust-logo" src="./static.files/rust-logo-9a9549ea.svg" alt="logo"></a><h2><a href="./index.html">Rustdoc</a><span class="version">1.92.0-nightly</span></h2></div><div class="version">(b6f0945e4 2025-10-08)</div><h2 class="location">Help</h2><div class="sidebar-elems"></div></nav><div class="sidebar-resizer" title="Drag to resize sidebar"></div><main><div class="width-limiter"><section id="main-content" class="content"><div class="main-heading"><h1>Rustdoc help</h1><span class="out-of-band"><a id="back" href="javascript:void(0)" onclick="history.back();">Back</a></span></div><noscript><section><p>You need to enable JavaScript to use keyboard commands or search.</p><p>For more information, browse the <a href="https://doc.rust-lang.org/nightly/rustdoc/">rustdoc handbook</a>.</p></section></noscript></section></div></main></body></html>
<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta name="generator" content="rustdoc"><meta name="description" content="Documentation for Rustdoc"><title>Help</title><script>if(window.location.protocol!=="file:")document.head.insertAdjacentHTML("beforeend","SourceSerif4-Regular-6b053e98.ttf.woff2,FiraSans-Italic-81dc35de.woff2,FiraSans-Regular-0fe48ade.woff2,FiraSans-MediumItalic-ccf7e434.woff2,FiraSans-Medium-e1aa3f0a.woff2,SourceCodePro-Regular-8badfe75.ttf.woff2,SourceCodePro-Semibold-aa29a496.ttf.woff2".split(",").map(f=>`<link rel="preload" as="font" type="font/woff2"href="./static.files/${f}">`).join(""))</script><link rel="stylesheet" href="./static.files/normalize-9960930a.css"><link rel="stylesheet" href="./static.files/rustdoc-ca0dd0c4.css"><meta name="rustdoc-vars" data-root-path="./" data-static-root-path="./static.files/" data-current-crate="quinn_perf" data-themes="" data-resource-suffix="" data-rustdoc-version="1.92.0-nightly (b6f0945e4 2025-10-08)" data-channel="nightly" data-search-js="search-8d3311b9.js" data-stringdex-js="stringdex-828709d0.js" data-settings-js="settings-c38705f0.js" ><script src="./static.files/storage-e2aeef58.js"></script><script defer src="./static.files/main-ce535bd0.js"></script><noscript><link rel="stylesheet" href="./static.files/noscript-263c88ec.css"></noscript><link rel="alternate icon" type="image/png" href="./static.files/favicon-32x32-eab170b8.png"><link rel="icon" type="image/svg+xml" href="./static.files/favicon-044be391.svg"></head><body class="rustdoc mod sys"><!--[if lte IE 11]><div class="warning">This old browser is unsupported and will most likely display funky things.</div><![endif]--><rustdoc-topbar><h2><a href="#">All</a></h2></rustdoc-topbar><nav class="sidebar"><div class="sidebar-crate"><a class="logo-container" href="./index.html"><img class="rust-logo" src="./static.files/rust-logo-9a9549ea.svg" alt="logo"></a><h2><a href="./index.html">Rustdoc</a><span class="version">1.92.0-nightly</span></h2></div><div class="version">(b6f0945e4 2025-10-08)</div><h2 class="location">Help</h2><div class="sidebar-elems"></div></nav><div class="sidebar-resizer" title="Drag to resize sidebar"></div><main><div class="width-limiter"><section id="main-content" class="content"><div class="main-heading"><h1>Rustdoc help</h1><span class="out-of-band"><a id="back" href="javascript:void(0)" onclick="history.back();">Back</a></span></div><noscript><section><p>You need to enable JavaScript to use keyboard commands or search.</p><p>For more information, browse the <a href="https://doc.rust-lang.org/nightly/rustdoc/">rustdoc handbook</a>.</p></section></noscript></section></div></main></body></html>
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1,10 +1,10 @@
<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta name="generator" content="rustdoc"><meta name="description" content="Error type for attempting to accept an `Incoming`"><title>AcceptError in iroh_quinn_proto - Rust</title><script>if(window.location.protocol!=="file:")document.head.insertAdjacentHTML("beforeend","SourceSerif4-Regular-6b053e98.ttf.woff2,FiraSans-Italic-81dc35de.woff2,FiraSans-Regular-0fe48ade.woff2,FiraSans-MediumItalic-ccf7e434.woff2,FiraSans-Medium-e1aa3f0a.woff2,SourceCodePro-Regular-8badfe75.ttf.woff2,SourceCodePro-Semibold-aa29a496.ttf.woff2".split(",").map(f=>`<link rel="preload" as="font" type="font/woff2"href="../static.files/${f}">`).join(""))</script><link rel="stylesheet" href="../static.files/normalize-9960930a.css"><link rel="stylesheet" href="../static.files/rustdoc-ca0dd0c4.css"><meta name="rustdoc-vars" data-root-path="../" data-static-root-path="../static.files/" data-current-crate="iroh_quinn_proto" data-themes="" data-resource-suffix="" data-rustdoc-version="1.92.0-nightly (b6f0945e4 2025-10-08)" data-channel="nightly" data-search-js="search-8d3311b9.js" data-stringdex-js="stringdex-828709d0.js" data-settings-js="settings-c38705f0.js" ><script src="../static.files/storage-e2aeef58.js"></script><script defer src="sidebar-items.js"></script><script defer src="../static.files/main-ce535bd0.js"></script><noscript><link rel="stylesheet" href="../static.files/noscript-263c88ec.css"></noscript><link rel="alternate icon" type="image/png" href="../static.files/favicon-32x32-eab170b8.png"><link rel="icon" type="image/svg+xml" href="../static.files/favicon-044be391.svg"></head><body class="rustdoc struct"><!--[if lte IE 11]><div class="warning">This old browser is unsupported and will most likely display funky things.</div><![endif]--><rustdoc-topbar><h2><a href="#">AcceptError</a></h2></rustdoc-topbar><nav class="sidebar"><div class="sidebar-crate"><h2><a href="../iroh_quinn_proto/index.html">iroh_<wbr>quinn_<wbr>proto</a><span class="version">0.15.1</span></h2></div><div class="sidebar-elems"><section id="rustdoc-toc"><h2 class="location"><a href="#">Accept<wbr>Error</a></h2><h3><a href="#fields">Fields</a></h3><ul class="block structfield"><li><a href="#structfield.cause" title="cause">cause</a></li><li><a href="#structfield.response" title="response">response</a></li></ul><h3><a href="#trait-implementations">Trait Implementations</a></h3><ul class="block trait-implementation"><li><a href="#impl-Debug-for-AcceptError" title="Debug">Debug</a></li></ul><h3><a href="#synthetic-implementations">Auto Trait Implementations</a></h3><ul class="block synthetic-implementation"><li><a href="#impl-Freeze-for-AcceptError" title="!Freeze">!Freeze</a></li><li><a href="#impl-RefUnwindSafe-for-AcceptError" title="!RefUnwindSafe">!RefUnwindSafe</a></li><li><a href="#impl-UnwindSafe-for-AcceptError" title="!UnwindSafe">!UnwindSafe</a></li><li><a href="#impl-Send-for-AcceptError" title="Send">Send</a></li><li><a href="#impl-Sync-for-AcceptError" title="Sync">Sync</a></li><li><a href="#impl-Unpin-for-AcceptError" title="Unpin">Unpin</a></li></ul><h3><a href="#blanket-implementations">Blanket Implementations</a></h3><ul class="block blanket-implementation"><li><a href="#impl-Any-for-T" title="Any">Any</a></li><li><a href="#impl-Borrow%3CT%3E-for-T" title="Borrow&#60;T&#62;">Borrow&#60;T&#62;</a></li><li><a href="#impl-BorrowMut%3CT%3E-for-T" title="BorrowMut&#60;T&#62;">BorrowMut&#60;T&#62;</a></li><li><a href="#impl-From%3CT%3E-for-T" title="From&#60;T&#62;">From&#60;T&#62;</a></li><li><a href="#impl-Instrument-for-T" title="Instrument">Instrument</a></li><li><a href="#impl-Into%3CU%3E-for-T" title="Into&#60;U&#62;">Into&#60;U&#62;</a></li><li><a href="#impl-IntoEither-for-T" title="IntoEither">IntoEither</a></li><li><a href="#impl-TryFrom%3CU%3E-for-T" title="TryFrom&#60;U&#62;">TryFrom&#60;U&#62;</a></li><li><a href="#impl-TryInto%3CU%3E-for-T" title="TryInto&#60;U&#62;">TryInto&#60;U&#62;</a></li><li><a href="#impl-VZip%3CV%3E-for-T" title="VZip&#60;V&#62;">VZip&#60;V&#62;</a></li><li><a href="#impl-WithSubscriber-for-T" title="WithSubscriber">WithSubscriber</a></li></ul></section><div id="rustdoc-modnav"><h2 class="in-crate"><a href="index.html">In crate iroh_<wbr>quinn_<wbr>proto</a></h2></div></div></nav><div class="sidebar-resizer" title="Drag to resize sidebar"></div><main><div class="width-limiter"><section id="main-content" class="content"><div class="main-heading"><div class="rustdoc-breadcrumbs"><a href="index.html">iroh_quinn_proto</a></div><h1>Struct <span class="struct">Accept<wbr>Error</span>&nbsp;<button id="copy-path" title="Copy item path to clipboard">Copy item path</button></h1><rustdoc-toolbar></rustdoc-toolbar><span class="sub-heading"><a class="src" href="../src/iroh_quinn_proto/endpoint.rs.html#1511-1516">Source</a> </span></div><pre class="rust item-decl"><code>pub struct AcceptError {
<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta name="generator" content="rustdoc"><meta name="description" content="Error type for attempting to accept an `Incoming`"><title>AcceptError in iroh_quinn_proto - Rust</title><script>if(window.location.protocol!=="file:")document.head.insertAdjacentHTML("beforeend","SourceSerif4-Regular-6b053e98.ttf.woff2,FiraSans-Italic-81dc35de.woff2,FiraSans-Regular-0fe48ade.woff2,FiraSans-MediumItalic-ccf7e434.woff2,FiraSans-Medium-e1aa3f0a.woff2,SourceCodePro-Regular-8badfe75.ttf.woff2,SourceCodePro-Semibold-aa29a496.ttf.woff2".split(",").map(f=>`<link rel="preload" as="font" type="font/woff2"href="../static.files/${f}">`).join(""))</script><link rel="stylesheet" href="../static.files/normalize-9960930a.css"><link rel="stylesheet" href="../static.files/rustdoc-ca0dd0c4.css"><meta name="rustdoc-vars" data-root-path="../" data-static-root-path="../static.files/" data-current-crate="iroh_quinn_proto" data-themes="" data-resource-suffix="" data-rustdoc-version="1.92.0-nightly (b6f0945e4 2025-10-08)" data-channel="nightly" data-search-js="search-8d3311b9.js" data-stringdex-js="stringdex-828709d0.js" data-settings-js="settings-c38705f0.js" ><script src="../static.files/storage-e2aeef58.js"></script><script defer src="sidebar-items.js"></script><script defer src="../static.files/main-ce535bd0.js"></script><noscript><link rel="stylesheet" href="../static.files/noscript-263c88ec.css"></noscript><link rel="alternate icon" type="image/png" href="../static.files/favicon-32x32-eab170b8.png"><link rel="icon" type="image/svg+xml" href="../static.files/favicon-044be391.svg"></head><body class="rustdoc struct"><!--[if lte IE 11]><div class="warning">This old browser is unsupported and will most likely display funky things.</div><![endif]--><rustdoc-topbar><h2><a href="#">AcceptError</a></h2></rustdoc-topbar><nav class="sidebar"><div class="sidebar-crate"><h2><a href="../iroh_quinn_proto/index.html">iroh_<wbr>quinn_<wbr>proto</a><span class="version">0.15.1</span></h2></div><div class="sidebar-elems"><section id="rustdoc-toc"><h2 class="location"><a href="#">Accept<wbr>Error</a></h2><h3><a href="#fields">Fields</a></h3><ul class="block structfield"><li><a href="#structfield.cause" title="cause">cause</a></li><li><a href="#structfield.response" title="response">response</a></li></ul><h3><a href="#trait-implementations">Trait Implementations</a></h3><ul class="block trait-implementation"><li><a href="#impl-Debug-for-AcceptError" title="Debug">Debug</a></li></ul><h3><a href="#synthetic-implementations">Auto Trait Implementations</a></h3><ul class="block synthetic-implementation"><li><a href="#impl-Freeze-for-AcceptError" title="!Freeze">!Freeze</a></li><li><a href="#impl-RefUnwindSafe-for-AcceptError" title="!RefUnwindSafe">!RefUnwindSafe</a></li><li><a href="#impl-UnwindSafe-for-AcceptError" title="!UnwindSafe">!UnwindSafe</a></li><li><a href="#impl-Send-for-AcceptError" title="Send">Send</a></li><li><a href="#impl-Sync-for-AcceptError" title="Sync">Sync</a></li><li><a href="#impl-Unpin-for-AcceptError" title="Unpin">Unpin</a></li></ul><h3><a href="#blanket-implementations">Blanket Implementations</a></h3><ul class="block blanket-implementation"><li><a href="#impl-Any-for-T" title="Any">Any</a></li><li><a href="#impl-Borrow%3CT%3E-for-T" title="Borrow&#60;T&#62;">Borrow&#60;T&#62;</a></li><li><a href="#impl-BorrowMut%3CT%3E-for-T" title="BorrowMut&#60;T&#62;">BorrowMut&#60;T&#62;</a></li><li><a href="#impl-From%3CT%3E-for-T" title="From&#60;T&#62;">From&#60;T&#62;</a></li><li><a href="#impl-Instrument-for-T" title="Instrument">Instrument</a></li><li><a href="#impl-Into%3CU%3E-for-T" title="Into&#60;U&#62;">Into&#60;U&#62;</a></li><li><a href="#impl-IntoEither-for-T" title="IntoEither">IntoEither</a></li><li><a href="#impl-TryFrom%3CU%3E-for-T" title="TryFrom&#60;U&#62;">TryFrom&#60;U&#62;</a></li><li><a href="#impl-TryInto%3CU%3E-for-T" title="TryInto&#60;U&#62;">TryInto&#60;U&#62;</a></li><li><a href="#impl-VZip%3CV%3E-for-T" title="VZip&#60;V&#62;">VZip&#60;V&#62;</a></li><li><a href="#impl-WithSubscriber-for-T" title="WithSubscriber">WithSubscriber</a></li></ul></section><div id="rustdoc-modnav"><h2 class="in-crate"><a href="index.html">In crate iroh_<wbr>quinn_<wbr>proto</a></h2></div></div></nav><div class="sidebar-resizer" title="Drag to resize sidebar"></div><main><div class="width-limiter"><section id="main-content" class="content"><div class="main-heading"><div class="rustdoc-breadcrumbs"><a href="index.html">iroh_quinn_proto</a></div><h1>Struct <span class="struct">Accept<wbr>Error</span>&nbsp;<button id="copy-path" title="Copy item path to clipboard">Copy item path</button></h1><rustdoc-toolbar></rustdoc-toolbar><span class="sub-heading"><a class="src" href="../src/iroh_quinn_proto/endpoint.rs.html#1509-1514">Source</a> </span></div><pre class="rust item-decl"><code>pub struct AcceptError {
pub cause: <a class="enum" href="enum.ConnectionError.html" title="enum iroh_quinn_proto::ConnectionError">ConnectionError</a>,
pub response: <a class="enum" href="https://doc.rust-lang.org/nightly/core/option/enum.Option.html" title="enum core::option::Option">Option</a>&lt;<a class="struct" href="struct.Transmit.html" title="struct iroh_quinn_proto::Transmit">Transmit</a>&gt;,
}</code></pre><details class="toggle top-doc" open><summary class="hideme"><span>Expand description</span></summary><div class="docblock"><p>Error type for attempting to accept an <a href="struct.Incoming.html" title="struct iroh_quinn_proto::Incoming"><code>Incoming</code></a></p>
</div></details><h2 id="fields" class="fields section-header">Fields<a href="#fields" class="anchor">§</a></h2><span id="structfield.cause" class="structfield section-header"><a href="#structfield.cause" class="anchor field">§</a><code>cause: <a class="enum" href="enum.ConnectionError.html" title="enum iroh_quinn_proto::ConnectionError">ConnectionError</a></code></span><div class="docblock"><p>Underlying error describing reason for failure</p>
</div><span id="structfield.response" class="structfield section-header"><a href="#structfield.response" class="anchor field">§</a><code>response: <a class="enum" href="https://doc.rust-lang.org/nightly/core/option/enum.Option.html" title="enum core::option::Option">Option</a>&lt;<a class="struct" href="struct.Transmit.html" title="struct iroh_quinn_proto::Transmit">Transmit</a>&gt;</code></span><div class="docblock"><p>Optional response to transmit back</p>
</div><h2 id="trait-implementations" class="section-header">Trait Implementations<a href="#trait-implementations" class="anchor">§</a></h2><div id="trait-implementations-list"><details class="toggle implementors-toggle" open><summary><section id="impl-Debug-for-AcceptError" class="impl"><a class="src rightside" href="../src/iroh_quinn_proto/endpoint.rs.html#1510">Source</a><a href="#impl-Debug-for-AcceptError" class="anchor">§</a><h3 class="code-header">impl <a class="trait" href="https://doc.rust-lang.org/nightly/core/fmt/trait.Debug.html" title="trait core::fmt::Debug">Debug</a> for <a class="struct" href="struct.AcceptError.html" title="struct iroh_quinn_proto::AcceptError">AcceptError</a></h3></section></summary><div class="impl-items"><details class="toggle method-toggle" open><summary><section id="method.fmt" class="method trait-impl"><a class="src rightside" href="../src/iroh_quinn_proto/endpoint.rs.html#1510">Source</a><a href="#method.fmt" class="anchor">§</a><h4 class="code-header">fn <a href="https://doc.rust-lang.org/nightly/core/fmt/trait.Debug.html#tymethod.fmt" class="fn">fmt</a>(&amp;self, f: &amp;mut <a class="struct" href="https://doc.rust-lang.org/nightly/core/fmt/struct.Formatter.html" title="struct core::fmt::Formatter">Formatter</a>&lt;'_&gt;) -&gt; <a class="type" href="https://doc.rust-lang.org/nightly/core/fmt/type.Result.html" title="type core::fmt::Result">Result</a></h4></section></summary><div class='docblock'>Formats the value using the given formatter. <a href="https://doc.rust-lang.org/nightly/core/fmt/trait.Debug.html#tymethod.fmt">Read more</a></div></details></div></details></div><h2 id="synthetic-implementations" class="section-header">Auto Trait Implementations<a href="#synthetic-implementations" class="anchor">§</a></h2><div id="synthetic-implementations-list"><section id="impl-Freeze-for-AcceptError" class="impl"><a href="#impl-Freeze-for-AcceptError" class="anchor">§</a><h3 class="code-header">impl !<a class="trait" href="https://doc.rust-lang.org/nightly/core/marker/trait.Freeze.html" title="trait core::marker::Freeze">Freeze</a> for <a class="struct" href="struct.AcceptError.html" title="struct iroh_quinn_proto::AcceptError">AcceptError</a></h3></section><section id="impl-RefUnwindSafe-for-AcceptError" class="impl"><a href="#impl-RefUnwindSafe-for-AcceptError" class="anchor">§</a><h3 class="code-header">impl !<a class="trait" href="https://doc.rust-lang.org/nightly/core/panic/unwind_safe/trait.RefUnwindSafe.html" title="trait core::panic::unwind_safe::RefUnwindSafe">RefUnwindSafe</a> for <a class="struct" href="struct.AcceptError.html" title="struct iroh_quinn_proto::AcceptError">AcceptError</a></h3></section><section id="impl-Send-for-AcceptError" class="impl"><a href="#impl-Send-for-AcceptError" class="anchor">§</a><h3 class="code-header">impl <a class="trait" href="https://doc.rust-lang.org/nightly/core/marker/trait.Send.html" title="trait core::marker::Send">Send</a> for <a class="struct" href="struct.AcceptError.html" title="struct iroh_quinn_proto::AcceptError">AcceptError</a></h3></section><section id="impl-Sync-for-AcceptError" class="impl"><a href="#impl-Sync-for-AcceptError" class="anchor">§</a><h3 class="code-header">impl <a class="trait" href="https://doc.rust-lang.org/nightly/core/marker/trait.Sync.html" title="trait core::marker::Sync">Sync</a> for <a class="struct" href="struct.AcceptError.html" title="struct iroh_quinn_proto::AcceptError">AcceptError</a></h3></section><section id="impl-Unpin-for-AcceptError" class="impl"><a href="#impl-Unpin-for-AcceptError" class="anchor">§</a><h3 class="code-header">impl <a class="trait" href="https://doc.rust-lang.org/nightly/core/marker/trait.Unpin.html" title="trait core::marker::Unpin">Unpin</a> for <a class="struct" href="struct.AcceptError.html" title="struct iroh_quinn_proto::AcceptError">AcceptError</a></h3></section><section id="impl-UnwindSafe-for-AcceptError" class="impl"><a href="#impl-UnwindSafe-for-AcceptError" class="anchor">§</a><h3 class="code-header">impl !<a class="trait" href="https://doc.rust-lang.org/nightly/core/panic/unwind_safe/trait.UnwindSafe.html" title="trait core::panic::unwind_safe::UnwindSafe">UnwindSafe</a> for <a class="struct" href="struct.AcceptError.html" title="struct iroh_quinn_proto::AcceptError">AcceptError</a></h3></section></div><h2 id="blanket-implementations" class="section-header">Blanket Implementations<a href="#blanket-implementations" class="anchor">§</a></h2><div id="blanket-implementations-list"><details class="toggle implementors-toggle"><summary><section id="impl-Any-for-T" class="impl"><a class="src rightside" href="https://doc.rust-lang.org/nightly/src/core/any.rs.html#138">Source</a><a href="#impl-Any-for-T" class="anchor">§</a><h3 class="code-header">impl&lt;T&gt; <a class="trait" href="https://doc.rust-lang.org/nightly/core/any/trait.Any.html" title="trait core::any::Any">Any</a> for T<div class="where">where
</div><h2 id="trait-implementations" class="section-header">Trait Implementations<a href="#trait-implementations" class="anchor">§</a></h2><div id="trait-implementations-list"><details class="toggle implementors-toggle" open><summary><section id="impl-Debug-for-AcceptError" class="impl"><a class="src rightside" href="../src/iroh_quinn_proto/endpoint.rs.html#1508">Source</a><a href="#impl-Debug-for-AcceptError" class="anchor">§</a><h3 class="code-header">impl <a class="trait" href="https://doc.rust-lang.org/nightly/core/fmt/trait.Debug.html" title="trait core::fmt::Debug">Debug</a> for <a class="struct" href="struct.AcceptError.html" title="struct iroh_quinn_proto::AcceptError">AcceptError</a></h3></section></summary><div class="impl-items"><details class="toggle method-toggle" open><summary><section id="method.fmt" class="method trait-impl"><a class="src rightside" href="../src/iroh_quinn_proto/endpoint.rs.html#1508">Source</a><a href="#method.fmt" class="anchor">§</a><h4 class="code-header">fn <a href="https://doc.rust-lang.org/nightly/core/fmt/trait.Debug.html#tymethod.fmt" class="fn">fmt</a>(&amp;self, f: &amp;mut <a class="struct" href="https://doc.rust-lang.org/nightly/core/fmt/struct.Formatter.html" title="struct core::fmt::Formatter">Formatter</a>&lt;'_&gt;) -&gt; <a class="type" href="https://doc.rust-lang.org/nightly/core/fmt/type.Result.html" title="type core::fmt::Result">Result</a></h4></section></summary><div class='docblock'>Formats the value using the given formatter. <a href="https://doc.rust-lang.org/nightly/core/fmt/trait.Debug.html#tymethod.fmt">Read more</a></div></details></div></details></div><h2 id="synthetic-implementations" class="section-header">Auto Trait Implementations<a href="#synthetic-implementations" class="anchor">§</a></h2><div id="synthetic-implementations-list"><section id="impl-Freeze-for-AcceptError" class="impl"><a href="#impl-Freeze-for-AcceptError" class="anchor">§</a><h3 class="code-header">impl !<a class="trait" href="https://doc.rust-lang.org/nightly/core/marker/trait.Freeze.html" title="trait core::marker::Freeze">Freeze</a> for <a class="struct" href="struct.AcceptError.html" title="struct iroh_quinn_proto::AcceptError">AcceptError</a></h3></section><section id="impl-RefUnwindSafe-for-AcceptError" class="impl"><a href="#impl-RefUnwindSafe-for-AcceptError" class="anchor">§</a><h3 class="code-header">impl !<a class="trait" href="https://doc.rust-lang.org/nightly/core/panic/unwind_safe/trait.RefUnwindSafe.html" title="trait core::panic::unwind_safe::RefUnwindSafe">RefUnwindSafe</a> for <a class="struct" href="struct.AcceptError.html" title="struct iroh_quinn_proto::AcceptError">AcceptError</a></h3></section><section id="impl-Send-for-AcceptError" class="impl"><a href="#impl-Send-for-AcceptError" class="anchor">§</a><h3 class="code-header">impl <a class="trait" href="https://doc.rust-lang.org/nightly/core/marker/trait.Send.html" title="trait core::marker::Send">Send</a> for <a class="struct" href="struct.AcceptError.html" title="struct iroh_quinn_proto::AcceptError">AcceptError</a></h3></section><section id="impl-Sync-for-AcceptError" class="impl"><a href="#impl-Sync-for-AcceptError" class="anchor">§</a><h3 class="code-header">impl <a class="trait" href="https://doc.rust-lang.org/nightly/core/marker/trait.Sync.html" title="trait core::marker::Sync">Sync</a> for <a class="struct" href="struct.AcceptError.html" title="struct iroh_quinn_proto::AcceptError">AcceptError</a></h3></section><section id="impl-Unpin-for-AcceptError" class="impl"><a href="#impl-Unpin-for-AcceptError" class="anchor">§</a><h3 class="code-header">impl <a class="trait" href="https://doc.rust-lang.org/nightly/core/marker/trait.Unpin.html" title="trait core::marker::Unpin">Unpin</a> for <a class="struct" href="struct.AcceptError.html" title="struct iroh_quinn_proto::AcceptError">AcceptError</a></h3></section><section id="impl-UnwindSafe-for-AcceptError" class="impl"><a href="#impl-UnwindSafe-for-AcceptError" class="anchor">§</a><h3 class="code-header">impl !<a class="trait" href="https://doc.rust-lang.org/nightly/core/panic/unwind_safe/trait.UnwindSafe.html" title="trait core::panic::unwind_safe::UnwindSafe">UnwindSafe</a> for <a class="struct" href="struct.AcceptError.html" title="struct iroh_quinn_proto::AcceptError">AcceptError</a></h3></section></div><h2 id="blanket-implementations" class="section-header">Blanket Implementations<a href="#blanket-implementations" class="anchor">§</a></h2><div id="blanket-implementations-list"><details class="toggle implementors-toggle"><summary><section id="impl-Any-for-T" class="impl"><a class="src rightside" href="https://doc.rust-lang.org/nightly/src/core/any.rs.html#138">Source</a><a href="#impl-Any-for-T" class="anchor">§</a><h3 class="code-header">impl&lt;T&gt; <a class="trait" href="https://doc.rust-lang.org/nightly/core/any/trait.Any.html" title="trait core::any::Any">Any</a> for T<div class="where">where
T: 'static + ?<a class="trait" href="https://doc.rust-lang.org/nightly/core/marker/trait.Sized.html" title="trait core::marker::Sized">Sized</a>,</div></h3></section></summary><div class="impl-items"><details class="toggle method-toggle" open><summary><section id="method.type_id" class="method trait-impl"><a class="src rightside" href="https://doc.rust-lang.org/nightly/src/core/any.rs.html#139">Source</a><a href="#method.type_id" class="anchor">§</a><h4 class="code-header">fn <a href="https://doc.rust-lang.org/nightly/core/any/trait.Any.html#tymethod.type_id" class="fn">type_id</a>(&amp;self) -&gt; <a class="struct" href="https://doc.rust-lang.org/nightly/core/any/struct.TypeId.html" title="struct core::any::TypeId">TypeId</a></h4></section></summary><div class='docblock'>Gets the <code>TypeId</code> of <code>self</code>. <a href="https://doc.rust-lang.org/nightly/core/any/trait.Any.html#tymethod.type_id">Read more</a></div></details></div></details><details class="toggle implementors-toggle"><summary><section id="impl-Borrow%3CT%3E-for-T" class="impl"><a class="src rightside" href="https://doc.rust-lang.org/nightly/src/core/borrow.rs.html#212">Source</a><a href="#impl-Borrow%3CT%3E-for-T" class="anchor">§</a><h3 class="code-header">impl&lt;T&gt; <a class="trait" href="https://doc.rust-lang.org/nightly/core/borrow/trait.Borrow.html" title="trait core::borrow::Borrow">Borrow</a>&lt;T&gt; for T<div class="where">where
T: ?<a class="trait" href="https://doc.rust-lang.org/nightly/core/marker/trait.Sized.html" title="trait core::marker::Sized">Sized</a>,</div></h3></section></summary><div class="impl-items"><details class="toggle method-toggle" open><summary><section id="method.borrow" class="method trait-impl"><a class="src rightside" href="https://doc.rust-lang.org/nightly/src/core/borrow.rs.html#214">Source</a><a href="#method.borrow" class="anchor">§</a><h4 class="code-header">fn <a href="https://doc.rust-lang.org/nightly/core/borrow/trait.Borrow.html#tymethod.borrow" class="fn">borrow</a>(&amp;self) -&gt; <a class="primitive" href="https://doc.rust-lang.org/nightly/std/primitive.reference.html">&amp;T</a></h4></section></summary><div class='docblock'>Immutably borrows from an owned value. <a href="https://doc.rust-lang.org/nightly/core/borrow/trait.Borrow.html#tymethod.borrow">Read more</a></div></details></div></details><details class="toggle implementors-toggle"><summary><section id="impl-BorrowMut%3CT%3E-for-T" class="impl"><a class="src rightside" href="https://doc.rust-lang.org/nightly/src/core/borrow.rs.html#221">Source</a><a href="#impl-BorrowMut%3CT%3E-for-T" class="anchor">§</a><h3 class="code-header">impl&lt;T&gt; <a class="trait" href="https://doc.rust-lang.org/nightly/core/borrow/trait.BorrowMut.html" title="trait core::borrow::BorrowMut">BorrowMut</a>&lt;T&gt; for T<div class="where">where
T: ?<a class="trait" href="https://doc.rust-lang.org/nightly/core/marker/trait.Sized.html" title="trait core::marker::Sized">Sized</a>,</div></h3></section></summary><div class="impl-items"><details class="toggle method-toggle" open><summary><section id="method.borrow_mut" class="method trait-impl"><a class="src rightside" href="https://doc.rust-lang.org/nightly/src/core/borrow.rs.html#222">Source</a><a href="#method.borrow_mut" class="anchor">§</a><h4 class="code-header">fn <a href="https://doc.rust-lang.org/nightly/core/borrow/trait.BorrowMut.html#tymethod.borrow_mut" class="fn">borrow_mut</a>(&amp;mut self) -&gt; <a class="primitive" href="https://doc.rust-lang.org/nightly/std/primitive.reference.html">&amp;mut T</a></h4></section></summary><div class='docblock'>Mutably borrows from an owned value. <a href="https://doc.rust-lang.org/nightly/core/borrow/trait.BorrowMut.html#tymethod.borrow_mut">Read more</a></div></details></div></details><details class="toggle implementors-toggle"><summary><section id="impl-From%3CT%3E-for-T" class="impl"><a class="src rightside" href="https://doc.rust-lang.org/nightly/src/core/convert/mod.rs.html#785">Source</a><a href="#impl-From%3CT%3E-for-T" class="anchor">§</a><h3 class="code-header">impl&lt;T&gt; <a class="trait" href="https://doc.rust-lang.org/nightly/core/convert/trait.From.html" title="trait core::convert::From">From</a>&lt;T&gt; for T</h3></section></summary><div class="impl-items"><details class="toggle method-toggle" open><summary><section id="method.from" class="method trait-impl"><a class="src rightside" href="https://doc.rust-lang.org/nightly/src/core/convert/mod.rs.html#788">Source</a><a href="#method.from" class="anchor">§</a><h4 class="code-header">fn <a href="https://doc.rust-lang.org/nightly/core/convert/trait.From.html#tymethod.from" class="fn">from</a>(t: T) -&gt; T</h4></section></summary><div class="docblock"><p>Returns the argument unchanged.</p>
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+1 -1
View File
@@ -1 +1 @@
<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta name="generator" content="rustdoc"><meta name="description" content="Settings of Rustdoc"><title>Settings</title><script>if(window.location.protocol!=="file:")document.head.insertAdjacentHTML("beforeend","SourceSerif4-Regular-6b053e98.ttf.woff2,FiraSans-Italic-81dc35de.woff2,FiraSans-Regular-0fe48ade.woff2,FiraSans-MediumItalic-ccf7e434.woff2,FiraSans-Medium-e1aa3f0a.woff2,SourceCodePro-Regular-8badfe75.ttf.woff2,SourceCodePro-Semibold-aa29a496.ttf.woff2".split(",").map(f=>`<link rel="preload" as="font" type="font/woff2"href="./static.files/${f}">`).join(""))</script><link rel="stylesheet" href="./static.files/normalize-9960930a.css"><link rel="stylesheet" href="./static.files/rustdoc-ca0dd0c4.css"><meta name="rustdoc-vars" data-root-path="./" data-static-root-path="./static.files/" data-current-crate="data_transfer" data-themes="" data-resource-suffix="" data-rustdoc-version="1.92.0-nightly (b6f0945e4 2025-10-08)" data-channel="nightly" data-search-js="search-8d3311b9.js" data-stringdex-js="stringdex-828709d0.js" data-settings-js="settings-c38705f0.js" ><script src="./static.files/storage-e2aeef58.js"></script><script defer src="./static.files/main-ce535bd0.js"></script><noscript><link rel="stylesheet" href="./static.files/noscript-263c88ec.css"></noscript><link rel="alternate icon" type="image/png" href="./static.files/favicon-32x32-eab170b8.png"><link rel="icon" type="image/svg+xml" href="./static.files/favicon-044be391.svg"></head><body class="rustdoc mod sys"><!--[if lte IE 11]><div class="warning">This old browser is unsupported and will most likely display funky things.</div><![endif]--><rustdoc-topbar><h2><a href="#">All</a></h2></rustdoc-topbar><nav class="sidebar"><div class="sidebar-crate"><a class="logo-container" href="./index.html"><img class="rust-logo" src="./static.files/rust-logo-9a9549ea.svg" alt="logo"></a><h2><a href="./index.html">Rustdoc</a><span class="version">1.92.0-nightly</span></h2></div><div class="version">(b6f0945e4 2025-10-08)</div><h2 class="location">Settings</h2><div class="sidebar-elems"></div></nav><div class="sidebar-resizer" title="Drag to resize sidebar"></div><main><div class="width-limiter"><section id="main-content" class="content"><div class="main-heading"><h1>Rustdoc settings</h1><span class="out-of-band"><a id="back" href="javascript:void(0)" onclick="history.back();">Back</a></span></div><noscript><section>You need to enable JavaScript be able to update your settings.</section></noscript><script defer src="./static.files/settings-c38705f0.js"></script></section></div></main></body></html>
<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta name="generator" content="rustdoc"><meta name="description" content="Settings of Rustdoc"><title>Settings</title><script>if(window.location.protocol!=="file:")document.head.insertAdjacentHTML("beforeend","SourceSerif4-Regular-6b053e98.ttf.woff2,FiraSans-Italic-81dc35de.woff2,FiraSans-Regular-0fe48ade.woff2,FiraSans-MediumItalic-ccf7e434.woff2,FiraSans-Medium-e1aa3f0a.woff2,SourceCodePro-Regular-8badfe75.ttf.woff2,SourceCodePro-Semibold-aa29a496.ttf.woff2".split(",").map(f=>`<link rel="preload" as="font" type="font/woff2"href="./static.files/${f}">`).join(""))</script><link rel="stylesheet" href="./static.files/normalize-9960930a.css"><link rel="stylesheet" href="./static.files/rustdoc-ca0dd0c4.css"><meta name="rustdoc-vars" data-root-path="./" data-static-root-path="./static.files/" data-current-crate="quinn_perf" data-themes="" data-resource-suffix="" data-rustdoc-version="1.92.0-nightly (b6f0945e4 2025-10-08)" data-channel="nightly" data-search-js="search-8d3311b9.js" data-stringdex-js="stringdex-828709d0.js" data-settings-js="settings-c38705f0.js" ><script src="./static.files/storage-e2aeef58.js"></script><script defer src="./static.files/main-ce535bd0.js"></script><noscript><link rel="stylesheet" href="./static.files/noscript-263c88ec.css"></noscript><link rel="alternate icon" type="image/png" href="./static.files/favicon-32x32-eab170b8.png"><link rel="icon" type="image/svg+xml" href="./static.files/favicon-044be391.svg"></head><body class="rustdoc mod sys"><!--[if lte IE 11]><div class="warning">This old browser is unsupported and will most likely display funky things.</div><![endif]--><rustdoc-topbar><h2><a href="#">All</a></h2></rustdoc-topbar><nav class="sidebar"><div class="sidebar-crate"><a class="logo-container" href="./index.html"><img class="rust-logo" src="./static.files/rust-logo-9a9549ea.svg" alt="logo"></a><h2><a href="./index.html">Rustdoc</a><span class="version">1.92.0-nightly</span></h2></div><div class="version">(b6f0945e4 2025-10-08)</div><h2 class="location">Settings</h2><div class="sidebar-elems"></div></nav><div class="sidebar-resizer" title="Drag to resize sidebar"></div><main><div class="width-limiter"><section id="main-content" class="content"><div class="main-heading"><h1>Rustdoc settings</h1><span class="out-of-band"><a id="back" href="javascript:void(0)" onclick="history.back();">Back</a></span></div><noscript><section>You need to enable JavaScript be able to update your settings.</section></noscript><script defer src="./static.files/settings-c38705f0.js"></script></section></div></main></body></html>
+57 -56
View File
@@ -109,59 +109,60 @@
<a href=#109 id=109 data-nosnippet>109</a> /// and parsing the TLS ClientHello. The result is not cached.
<a href=#110 id=110 data-nosnippet>110</a> ///
<a href=#111 id=111 data-nosnippet>111</a> /// Returns an iterator over the proposed ALPN protocol names. On the common
<a href=#112 id=112 data-nosnippet>112</a> /// fast path (single CRYPTO frame), this is zero-allocation.
<a href=#113 id=113 data-nosnippet>113</a> </span><span class="kw">pub fn </span>alpns(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; <span class="prelude-ty">Option</span>&lt;proto::IncomingAlpns&gt; {
<a href=#114 id=114 data-nosnippet>114</a> <span class="self">self</span>.<span class="number">0</span>.as_ref()<span class="question-mark">?</span>.inner.alpns()
<a href=#115 id=115 data-nosnippet>115</a> }
<a href=#116 id=116 data-nosnippet>116</a>}
<a href=#117 id=117 data-nosnippet>117</a>
<a href=#118 id=118 data-nosnippet>118</a><span class="kw">impl </span>Drop <span class="kw">for </span>Incoming {
<a href=#119 id=119 data-nosnippet>119</a> <span class="kw">fn </span>drop(<span class="kw-2">&amp;mut </span><span class="self">self</span>) {
<a href=#120 id=120 data-nosnippet>120</a> <span class="comment">// Implicit reject, similar to Connection's implicit close
<a href=#121 id=121 data-nosnippet>121</a> </span><span class="kw">if let </span><span class="prelude-val">Some</span>(state) = <span class="self">self</span>.<span class="number">0</span>.take() {
<a href=#122 id=122 data-nosnippet>122</a> state.endpoint.refuse(state.inner);
<a href=#123 id=123 data-nosnippet>123</a> }
<a href=#124 id=124 data-nosnippet>124</a> }
<a href=#125 id=125 data-nosnippet>125</a>}
<a href=#126 id=126 data-nosnippet>126</a>
<a href=#127 id=127 data-nosnippet>127</a><span class="attr">#[derive(Debug)]
<a href=#128 id=128 data-nosnippet>128</a></span><span class="kw">struct </span>State {
<a href=#129 id=129 data-nosnippet>129</a> inner: proto::Incoming,
<a href=#130 id=130 data-nosnippet>130</a> endpoint: EndpointRef,
<a href=#131 id=131 data-nosnippet>131</a>}
<a href=#132 id=132 data-nosnippet>132</a>
<a href=#133 id=133 data-nosnippet>133</a><span class="doccomment">/// Error for attempting to retry an [`Incoming`] which already bears a token from a previous retry
<a href=#134 id=134 data-nosnippet>134</a></span><span class="attr">#[derive(Debug, Error)]
<a href=#135 id=135 data-nosnippet>135</a>#[error(<span class="string">"retry() with validated Incoming"</span>)]
<a href=#136 id=136 data-nosnippet>136</a></span><span class="kw">pub struct </span>RetryError(Box&lt;Incoming&gt;);
<a href=#137 id=137 data-nosnippet>137</a>
<a href=#138 id=138 data-nosnippet>138</a><span class="kw">impl </span>RetryError {
<a href=#139 id=139 data-nosnippet>139</a> <span class="doccomment">/// Get the [`Incoming`]
<a href=#140 id=140 data-nosnippet>140</a> </span><span class="kw">pub fn </span>into_incoming(<span class="self">self</span>) -&gt; Incoming {
<a href=#141 id=141 data-nosnippet>141</a> <span class="kw-2">*</span><span class="self">self</span>.<span class="number">0
<a href=#142 id=142 data-nosnippet>142</a> </span>}
<a href=#143 id=143 data-nosnippet>143</a>}
<a href=#144 id=144 data-nosnippet>144</a>
<a href=#145 id=145 data-nosnippet>145</a><span class="doccomment">/// Basic adapter to let [`Incoming`] be `await`-ed like a [`Connecting`]
<a href=#146 id=146 data-nosnippet>146</a></span><span class="attr">#[derive(Debug)]
<a href=#147 id=147 data-nosnippet>147</a></span><span class="kw">pub struct </span>IncomingFuture(<span class="prelude-ty">Result</span>&lt;Connecting, ConnectionError&gt;);
<a href=#148 id=148 data-nosnippet>148</a>
<a href=#149 id=149 data-nosnippet>149</a><span class="kw">impl </span>Future <span class="kw">for </span>IncomingFuture {
<a href=#150 id=150 data-nosnippet>150</a> <span class="kw">type </span>Output = <span class="prelude-ty">Result</span>&lt;Connection, ConnectionError&gt;;
<a href=#151 id=151 data-nosnippet>151</a>
<a href=#152 id=152 data-nosnippet>152</a> <span class="kw">fn </span>poll(<span class="kw-2">mut </span><span class="self">self</span>: Pin&lt;<span class="kw-2">&amp;mut </span><span class="self">Self</span>&gt;, cx: <span class="kw-2">&amp;mut </span>Context&lt;<span class="lifetime">'_</span>&gt;) -&gt; Poll&lt;<span class="self">Self</span>::Output&gt; {
<a href=#153 id=153 data-nosnippet>153</a> <span class="kw">match </span><span class="kw-2">&amp;mut </span><span class="self">self</span>.<span class="number">0 </span>{
<a href=#154 id=154 data-nosnippet>154</a> <span class="prelude-val">Ok</span>(connecting) =&gt; Pin::new(connecting).poll(cx),
<a href=#155 id=155 data-nosnippet>155</a> <span class="prelude-val">Err</span>(e) =&gt; Poll::Ready(<span class="prelude-val">Err</span>(e.clone())),
<a href=#156 id=156 data-nosnippet>156</a> }
<a href=#157 id=157 data-nosnippet>157</a> }
<a href=#158 id=158 data-nosnippet>158</a>}
<a href=#159 id=159 data-nosnippet>159</a>
<a href=#160 id=160 data-nosnippet>160</a><span class="kw">impl </span>IntoFuture <span class="kw">for </span>Incoming {
<a href=#161 id=161 data-nosnippet>161</a> <span class="kw">type </span>Output = <span class="prelude-ty">Result</span>&lt;Connection, ConnectionError&gt;;
<a href=#162 id=162 data-nosnippet>162</a> <span class="kw">type </span>IntoFuture = IncomingFuture;
<a href=#163 id=163 data-nosnippet>163</a>
<a href=#164 id=164 data-nosnippet>164</a> <span class="kw">fn </span>into_future(<span class="self">self</span>) -&gt; <span class="self">Self</span>::IntoFuture {
<a href=#165 id=165 data-nosnippet>165</a> IncomingFuture(<span class="self">self</span>.accept())
<a href=#166 id=166 data-nosnippet>166</a> }
<a href=#167 id=167 data-nosnippet>167</a>}</code></pre></div></section></main></body></html>
<a href=#112 id=112 data-nosnippet>112</a> /// fast path (single CRYPTO frame), the only allocation is the payload clone
<a href=#113 id=113 data-nosnippet>113</a> /// for decryption.
<a href=#114 id=114 data-nosnippet>114</a> </span><span class="kw">pub fn </span>alpns(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; <span class="prelude-ty">Option</span>&lt;proto::IncomingAlpns&gt; {
<a href=#115 id=115 data-nosnippet>115</a> <span class="self">self</span>.<span class="number">0</span>.as_ref()<span class="question-mark">?</span>.inner.alpns()
<a href=#116 id=116 data-nosnippet>116</a> }
<a href=#117 id=117 data-nosnippet>117</a>}
<a href=#118 id=118 data-nosnippet>118</a>
<a href=#119 id=119 data-nosnippet>119</a><span class="kw">impl </span>Drop <span class="kw">for </span>Incoming {
<a href=#120 id=120 data-nosnippet>120</a> <span class="kw">fn </span>drop(<span class="kw-2">&amp;mut </span><span class="self">self</span>) {
<a href=#121 id=121 data-nosnippet>121</a> <span class="comment">// Implicit reject, similar to Connection's implicit close
<a href=#122 id=122 data-nosnippet>122</a> </span><span class="kw">if let </span><span class="prelude-val">Some</span>(state) = <span class="self">self</span>.<span class="number">0</span>.take() {
<a href=#123 id=123 data-nosnippet>123</a> state.endpoint.refuse(state.inner);
<a href=#124 id=124 data-nosnippet>124</a> }
<a href=#125 id=125 data-nosnippet>125</a> }
<a href=#126 id=126 data-nosnippet>126</a>}
<a href=#127 id=127 data-nosnippet>127</a>
<a href=#128 id=128 data-nosnippet>128</a><span class="attr">#[derive(Debug)]
<a href=#129 id=129 data-nosnippet>129</a></span><span class="kw">struct </span>State {
<a href=#130 id=130 data-nosnippet>130</a> inner: proto::Incoming,
<a href=#131 id=131 data-nosnippet>131</a> endpoint: EndpointRef,
<a href=#132 id=132 data-nosnippet>132</a>}
<a href=#133 id=133 data-nosnippet>133</a>
<a href=#134 id=134 data-nosnippet>134</a><span class="doccomment">/// Error for attempting to retry an [`Incoming`] which already bears a token from a previous retry
<a href=#135 id=135 data-nosnippet>135</a></span><span class="attr">#[derive(Debug, Error)]
<a href=#136 id=136 data-nosnippet>136</a>#[error(<span class="string">"retry() with validated Incoming"</span>)]
<a href=#137 id=137 data-nosnippet>137</a></span><span class="kw">pub struct </span>RetryError(Box&lt;Incoming&gt;);
<a href=#138 id=138 data-nosnippet>138</a>
<a href=#139 id=139 data-nosnippet>139</a><span class="kw">impl </span>RetryError {
<a href=#140 id=140 data-nosnippet>140</a> <span class="doccomment">/// Get the [`Incoming`]
<a href=#141 id=141 data-nosnippet>141</a> </span><span class="kw">pub fn </span>into_incoming(<span class="self">self</span>) -&gt; Incoming {
<a href=#142 id=142 data-nosnippet>142</a> <span class="kw-2">*</span><span class="self">self</span>.<span class="number">0
<a href=#143 id=143 data-nosnippet>143</a> </span>}
<a href=#144 id=144 data-nosnippet>144</a>}
<a href=#145 id=145 data-nosnippet>145</a>
<a href=#146 id=146 data-nosnippet>146</a><span class="doccomment">/// Basic adapter to let [`Incoming`] be `await`-ed like a [`Connecting`]
<a href=#147 id=147 data-nosnippet>147</a></span><span class="attr">#[derive(Debug)]
<a href=#148 id=148 data-nosnippet>148</a></span><span class="kw">pub struct </span>IncomingFuture(<span class="prelude-ty">Result</span>&lt;Connecting, ConnectionError&gt;);
<a href=#149 id=149 data-nosnippet>149</a>
<a href=#150 id=150 data-nosnippet>150</a><span class="kw">impl </span>Future <span class="kw">for </span>IncomingFuture {
<a href=#151 id=151 data-nosnippet>151</a> <span class="kw">type </span>Output = <span class="prelude-ty">Result</span>&lt;Connection, ConnectionError&gt;;
<a href=#152 id=152 data-nosnippet>152</a>
<a href=#153 id=153 data-nosnippet>153</a> <span class="kw">fn </span>poll(<span class="kw-2">mut </span><span class="self">self</span>: Pin&lt;<span class="kw-2">&amp;mut </span><span class="self">Self</span>&gt;, cx: <span class="kw-2">&amp;mut </span>Context&lt;<span class="lifetime">'_</span>&gt;) -&gt; Poll&lt;<span class="self">Self</span>::Output&gt; {
<a href=#154 id=154 data-nosnippet>154</a> <span class="kw">match </span><span class="kw-2">&amp;mut </span><span class="self">self</span>.<span class="number">0 </span>{
<a href=#155 id=155 data-nosnippet>155</a> <span class="prelude-val">Ok</span>(connecting) =&gt; Pin::new(connecting).poll(cx),
<a href=#156 id=156 data-nosnippet>156</a> <span class="prelude-val">Err</span>(e) =&gt; Poll::Ready(<span class="prelude-val">Err</span>(e.clone())),
<a href=#157 id=157 data-nosnippet>157</a> }
<a href=#158 id=158 data-nosnippet>158</a> }
<a href=#159 id=159 data-nosnippet>159</a>}
<a href=#160 id=160 data-nosnippet>160</a>
<a href=#161 id=161 data-nosnippet>161</a><span class="kw">impl </span>IntoFuture <span class="kw">for </span>Incoming {
<a href=#162 id=162 data-nosnippet>162</a> <span class="kw">type </span>Output = <span class="prelude-ty">Result</span>&lt;Connection, ConnectionError&gt;;
<a href=#163 id=163 data-nosnippet>163</a> <span class="kw">type </span>IntoFuture = IncomingFuture;
<a href=#164 id=164 data-nosnippet>164</a>
<a href=#165 id=165 data-nosnippet>165</a> <span class="kw">fn </span>into_future(<span class="self">self</span>) -&gt; <span class="self">Self</span>::IntoFuture {
<a href=#166 id=166 data-nosnippet>166</a> IncomingFuture(<span class="self">self</span>.accept())
<a href=#167 id=167 data-nosnippet>167</a> }
<a href=#168 id=168 data-nosnippet>168</a>}</code></pre></div></section></main></body></html>
+345 -347
View File
@@ -1275,351 +1275,349 @@
<a href=#1275 id=1275 data-nosnippet>1275</a> /// and parsing the TLS ClientHello. The result is not cached.
<a href=#1276 id=1276 data-nosnippet>1276</a> ///
<a href=#1277 id=1277 data-nosnippet>1277</a> /// Returns an iterator over the proposed ALPN protocol names. On the common
<a href=#1278 id=1278 data-nosnippet>1278</a> /// fast path (single CRYPTO frame), this is zero-allocation.
<a href=#1279 id=1279 data-nosnippet>1279</a> </span><span class="kw">pub fn </span>alpns(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; <span class="prelude-ty">Option</span>&lt;IncomingAlpns&gt; {
<a href=#1280 id=1280 data-nosnippet>1280</a> <span class="kw">let </span>packet_number = <span class="self">self</span>.packet.header.number.expand(<span class="number">0</span>);
<a href=#1281 id=1281 data-nosnippet>1281</a> <span class="kw">let </span><span class="kw-2">mut </span>payload = <span class="self">self</span>.packet.payload.clone();
<a href=#1282 id=1282 data-nosnippet>1282</a> <span class="self">self</span>.crypto
<a href=#1283 id=1283 data-nosnippet>1283</a> .packet
<a href=#1284 id=1284 data-nosnippet>1284</a> .remote
<a href=#1285 id=1285 data-nosnippet>1285</a> .decrypt(
<a href=#1286 id=1286 data-nosnippet>1286</a> PathId::ZERO,
<a href=#1287 id=1287 data-nosnippet>1287</a> packet_number,
<a href=#1288 id=1288 data-nosnippet>1288</a> <span class="kw-2">&amp;</span><span class="self">self</span>.packet.header_data,
<a href=#1289 id=1289 data-nosnippet>1289</a> <span class="kw-2">&amp;mut </span>payload,
<a href=#1290 id=1290 data-nosnippet>1290</a> )
<a href=#1291 id=1291 data-nosnippet>1291</a> .ok()<span class="question-mark">?</span>;
<a href=#1292 id=1292 data-nosnippet>1292</a>
<a href=#1293 id=1293 data-nosnippet>1293</a> <span class="comment">// Collect CRYPTO frames, fast path avoids allocation
<a href=#1294 id=1294 data-nosnippet>1294</a> </span><span class="kw">let </span>frames = frame::Iter::new(payload.freeze()).ok()<span class="question-mark">?</span>;
<a href=#1295 id=1295 data-nosnippet>1295</a> <span class="kw">let </span><span class="kw-2">mut </span>first = <span class="prelude-val">None</span>;
<a href=#1296 id=1296 data-nosnippet>1296</a> <span class="kw">let </span><span class="kw-2">mut </span>rest = Vec::new();
<a href=#1297 id=1297 data-nosnippet>1297</a> <span class="kw">for </span>frame <span class="kw">in </span>frames {
<a href=#1298 id=1298 data-nosnippet>1298</a> <span class="kw">match </span>frame {
<a href=#1299 id=1299 data-nosnippet>1299</a> <span class="prelude-val">Ok</span>(frame::Frame::Crypto(crypto)) =&gt; <span class="kw">match </span>first {
<a href=#1300 id=1300 data-nosnippet>1300</a> <span class="prelude-val">None </span>=&gt; first = <span class="prelude-val">Some</span>(crypto),
<a href=#1301 id=1301 data-nosnippet>1301</a> <span class="prelude-val">Some</span>(<span class="kw">_</span>) =&gt; rest.push(crypto),
<a href=#1302 id=1302 data-nosnippet>1302</a> },
<a href=#1303 id=1303 data-nosnippet>1303</a> <span class="prelude-val">Err</span>(<span class="kw">_</span>) =&gt; <span class="kw">return </span><span class="prelude-val">None</span>,
<a href=#1304 id=1304 data-nosnippet>1304</a> <span class="kw">_ </span>=&gt; {}
<a href=#1305 id=1305 data-nosnippet>1305</a> }
<a href=#1306 id=1306 data-nosnippet>1306</a> }
<a href=#1307 id=1307 data-nosnippet>1307</a> <span class="kw">let </span>first = first<span class="question-mark">?</span>;
<a href=#1308 id=1308 data-nosnippet>1308</a>
<a href=#1309 id=1309 data-nosnippet>1309</a> <span class="comment">// Fast path: single CRYPTO frame at offset 0 (no Vec allocated)
<a href=#1310 id=1310 data-nosnippet>1310</a> </span><span class="kw">if </span>rest.is_empty() &amp;&amp; first.offset == <span class="number">0 </span>{
<a href=#1311 id=1311 data-nosnippet>1311</a> <span class="kw">let </span>data = find_alpn_data(<span class="kw-2">&amp;</span>first.data).ok()<span class="question-mark">?</span>;
<a href=#1312 id=1312 data-nosnippet>1312</a> <span class="kw">return </span><span class="prelude-val">Some</span>(IncomingAlpns { data, pos: <span class="number">0 </span>});
<a href=#1313 id=1313 data-nosnippet>1313</a> }
<a href=#1314 id=1314 data-nosnippet>1314</a>
<a href=#1315 id=1315 data-nosnippet>1315</a> <span class="comment">// Slow path: reassemble multiple CRYPTO frames
<a href=#1316 id=1316 data-nosnippet>1316</a> </span>rest.push(first);
<a href=#1317 id=1317 data-nosnippet>1317</a> <span class="kw">let </span>source = assemble_crypto_frames(<span class="kw-2">&amp;mut </span>rest)<span class="question-mark">?</span>;
<a href=#1318 id=1318 data-nosnippet>1318</a> <span class="kw">let </span>data = find_alpn_data(<span class="kw-2">&amp;</span>source).ok()<span class="question-mark">?</span>;
<a href=#1319 id=1319 data-nosnippet>1319</a> <span class="prelude-val">Some</span>(IncomingAlpns { data, pos: <span class="number">0 </span>})
<a href=#1320 id=1320 data-nosnippet>1320</a> }
<a href=#1321 id=1321 data-nosnippet>1321</a>}
<a href=#1322 id=1322 data-nosnippet>1322</a>
<a href=#1323 id=1323 data-nosnippet>1323</a><span class="doccomment">/// TLS handshake type for ClientHello messages
<a href=#1324 id=1324 data-nosnippet>1324</a>/// &lt;https://www.rfc-editor.org/rfc/rfc8446#section-4.1.2&gt;
<a href=#1325 id=1325 data-nosnippet>1325</a></span><span class="kw">const </span>TLS_HANDSHAKE_TYPE_CLIENT_HELLO: u8 = <span class="number">0x01</span>;
<a href=#1326 id=1326 data-nosnippet>1326</a><span class="doccomment">/// TLS extension type for Application-Layer Protocol Negotiation
<a href=#1327 id=1327 data-nosnippet>1327</a>/// &lt;https://www.rfc-editor.org/rfc/rfc7301#section-3.1&gt;
<a href=#1328 id=1328 data-nosnippet>1328</a></span><span class="kw">const </span>TLS_EXTENSION_TYPE_ALPN: u16 = <span class="number">0x0010</span>;
<a href=#1329 id=1329 data-nosnippet>1329</a><span class="doccomment">/// Size of the fixed-length fields in a ClientHello (client_version + random)
<a href=#1330 id=1330 data-nosnippet>1330</a>/// &lt;https://www.rfc-editor.org/rfc/rfc8446#section-4.1.2&gt;
<a href=#1331 id=1331 data-nosnippet>1331</a></span><span class="kw">const </span>TLS_CLIENT_HELLO_FIXED_LEN: usize = <span class="number">2 </span>+ <span class="number">32</span>;
<a href=#1332 id=1332 data-nosnippet>1332</a>
<a href=#1333 id=1333 data-nosnippet>1333</a><span class="doccomment">/// Iterator over ALPN protocol names from a TLS ClientHello
<a href=#1334 id=1334 data-nosnippet>1334</a>///
<a href=#1335 id=1335 data-nosnippet>1335</a>/// Yields protocol names as [`Bytes`] slices. On the common fast path (single
<a href=#1336 id=1336 data-nosnippet>1336</a>/// CRYPTO frame), this involves no allocation beyond the initial decryption.
<a href=#1337 id=1337 data-nosnippet>1337</a></span><span class="kw">pub struct </span>IncomingAlpns {
<a href=#1338 id=1338 data-nosnippet>1338</a> data: Bytes,
<a href=#1339 id=1339 data-nosnippet>1339</a> pos: usize,
<a href=#1340 id=1340 data-nosnippet>1340</a>}
<a href=#1341 id=1341 data-nosnippet>1341</a>
<a href=#1342 id=1342 data-nosnippet>1342</a><span class="kw">impl </span>Iterator <span class="kw">for </span>IncomingAlpns {
<a href=#1343 id=1343 data-nosnippet>1343</a> <span class="kw">type </span>Item = <span class="prelude-ty">Result</span>&lt;Bytes, UnexpectedEnd&gt;;
<a href=#1344 id=1344 data-nosnippet>1344</a>
<a href=#1345 id=1345 data-nosnippet>1345</a> <span class="kw">fn </span>next(<span class="kw-2">&amp;mut </span><span class="self">self</span>) -&gt; <span class="prelude-ty">Option</span>&lt;<span class="self">Self</span>::Item&gt; {
<a href=#1346 id=1346 data-nosnippet>1346</a> <span class="kw">if </span><span class="self">self</span>.pos &gt;= <span class="self">self</span>.data.len() {
<a href=#1347 id=1347 data-nosnippet>1347</a> <span class="kw">return </span><span class="prelude-val">None</span>;
<a href=#1348 id=1348 data-nosnippet>1348</a> }
<a href=#1349 id=1349 data-nosnippet>1349</a> <span class="kw">let </span>len = <span class="self">self</span>.data[<span class="self">self</span>.pos] <span class="kw">as </span>usize;
<a href=#1350 id=1350 data-nosnippet>1350</a> <span class="self">self</span>.pos += <span class="number">1</span>;
<a href=#1351 id=1351 data-nosnippet>1351</a> <span class="kw">if </span><span class="self">self</span>.pos + len &gt; <span class="self">self</span>.data.len() {
<a href=#1352 id=1352 data-nosnippet>1352</a> <span class="kw">return </span><span class="prelude-val">Some</span>(<span class="prelude-val">Err</span>(UnexpectedEnd));
<a href=#1353 id=1353 data-nosnippet>1353</a> }
<a href=#1354 id=1354 data-nosnippet>1354</a> <span class="kw">let </span>proto = <span class="self">self</span>.data.slice(<span class="self">self</span>.pos..<span class="self">self</span>.pos + len);
<a href=#1355 id=1355 data-nosnippet>1355</a> <span class="self">self</span>.pos += len;
<a href=#1356 id=1356 data-nosnippet>1356</a> <span class="prelude-val">Some</span>(<span class="prelude-val">Ok</span>(proto))
<a href=#1357 id=1357 data-nosnippet>1357</a> }
<a href=#1358 id=1358 data-nosnippet>1358</a>}
<a href=#1359 id=1359 data-nosnippet>1359</a>
<a href=#1360 id=1360 data-nosnippet>1360</a><span class="doccomment">/// Sort CRYPTO frames by offset and concatenate into a contiguous `Bytes`
<a href=#1361 id=1361 data-nosnippet>1361</a>///
<a href=#1362 id=1362 data-nosnippet>1362</a>/// Returns `None` if there are gaps in the stream.
<a href=#1363 id=1363 data-nosnippet>1363</a></span><span class="kw">fn </span>assemble_crypto_frames(frames: <span class="kw-2">&amp;mut </span>[frame::Crypto]) -&gt; <span class="prelude-ty">Option</span>&lt;Bytes&gt; {
<a href=#1364 id=1364 data-nosnippet>1364</a> frames.sort_by_key(|f| f.offset);
<a href=#1365 id=1365 data-nosnippet>1365</a> <span class="kw">let </span>capacity = frames.iter().map(|f| f.data.len()).sum();
<a href=#1366 id=1366 data-nosnippet>1366</a> <span class="kw">let </span><span class="kw-2">mut </span>buf = Vec::with_capacity(capacity);
<a href=#1367 id=1367 data-nosnippet>1367</a> <span class="kw">for </span>f <span class="kw">in </span>frames.iter() {
<a href=#1368 id=1368 data-nosnippet>1368</a> <span class="kw">let </span>start = f.offset <span class="kw">as </span>usize;
<a href=#1369 id=1369 data-nosnippet>1369</a> <span class="kw">if </span>start &gt; buf.len() {
<a href=#1370 id=1370 data-nosnippet>1370</a> <span class="kw">return </span><span class="prelude-val">None</span>;
<a href=#1371 id=1371 data-nosnippet>1371</a> }
<a href=#1372 id=1372 data-nosnippet>1372</a> <span class="kw">let </span>end = start + f.data.len();
<a href=#1373 id=1373 data-nosnippet>1373</a> <span class="kw">if </span>end &gt; buf.len() {
<a href=#1374 id=1374 data-nosnippet>1374</a> buf.extend_from_slice(<span class="kw-2">&amp;</span>f.data[buf.len() - start..]);
<a href=#1375 id=1375 data-nosnippet>1375</a> }
<a href=#1376 id=1376 data-nosnippet>1376</a> }
<a href=#1377 id=1377 data-nosnippet>1377</a> <span class="prelude-val">Some</span>(Bytes::from(buf))
<a href=#1378 id=1378 data-nosnippet>1378</a>}
<a href=#1379 id=1379 data-nosnippet>1379</a>
<a href=#1380 id=1380 data-nosnippet>1380</a><span class="doccomment">/// Locate the raw ALPN protocol list data within a TLS ClientHello message
<a href=#1381 id=1381 data-nosnippet>1381</a>///
<a href=#1382 id=1382 data-nosnippet>1382</a>/// Parses the ClientHello in `source` and returns a [`Bytes`] containing the
<a href=#1383 id=1383 data-nosnippet>1383</a>/// u8-length-prefixed protocol names (after the outer ProtocolNameList u16
<a href=#1384 id=1384 data-nosnippet>1384</a>/// length prefix). The returned `Bytes` is a zero-copy slice of `source`.
<a href=#1385 id=1385 data-nosnippet>1385</a></span><span class="kw">fn </span>find_alpn_data(source: <span class="kw-2">&amp;</span>Bytes) -&gt; <span class="prelude-ty">Result</span>&lt;Bytes, UnexpectedEnd&gt; {
<a href=#1386 id=1386 data-nosnippet>1386</a> <span class="kw">let </span><span class="kw-2">mut </span>r = <span class="kw-2">&amp;**</span>source;
<a href=#1387 id=1387 data-nosnippet>1387</a>
<a href=#1388 id=1388 data-nosnippet>1388</a> <span class="kw">if </span>u8::decode(<span class="kw-2">&amp;mut </span>r)<span class="question-mark">? </span>!= TLS_HANDSHAKE_TYPE_CLIENT_HELLO {
<a href=#1389 id=1389 data-nosnippet>1389</a> <span class="kw">return </span><span class="prelude-val">Err</span>(UnexpectedEnd);
<a href=#1390 id=1390 data-nosnippet>1390</a> }
<a href=#1391 id=1391 data-nosnippet>1391</a>
<a href=#1392 id=1392 data-nosnippet>1392</a> <span class="comment">// Handshake message length (u24), scopes the remainder
<a href=#1393 id=1393 data-nosnippet>1393</a> </span><span class="kw">let </span>len = decode_u24(<span class="kw-2">&amp;mut </span>r)<span class="question-mark">?</span>;
<a href=#1394 id=1394 data-nosnippet>1394</a> <span class="kw">let </span><span class="kw-2">mut </span>body = take(<span class="kw-2">&amp;mut </span>r, len)<span class="question-mark">?</span>;
<a href=#1395 id=1395 data-nosnippet>1395</a>
<a href=#1396 id=1396 data-nosnippet>1396</a> <span class="comment">// Client version + random
<a href=#1397 id=1397 data-nosnippet>1397</a> </span>skip(<span class="kw-2">&amp;mut </span>body, TLS_CLIENT_HELLO_FIXED_LEN)<span class="question-mark">?</span>;
<a href=#1398 id=1398 data-nosnippet>1398</a>
<a href=#1399 id=1399 data-nosnippet>1399</a> <span class="comment">// Session ID, cipher suites, compression methods
<a href=#1400 id=1400 data-nosnippet>1400</a> </span>skip_u8_prefixed(<span class="kw-2">&amp;mut </span>body)<span class="question-mark">?</span>;
<a href=#1401 id=1401 data-nosnippet>1401</a> skip_u16_prefixed(<span class="kw-2">&amp;mut </span>body)<span class="question-mark">?</span>;
<a href=#1402 id=1402 data-nosnippet>1402</a> skip_u8_prefixed(<span class="kw-2">&amp;mut </span>body)<span class="question-mark">?</span>;
<a href=#1403 id=1403 data-nosnippet>1403</a>
<a href=#1404 id=1404 data-nosnippet>1404</a> <span class="comment">// Extensions
<a href=#1405 id=1405 data-nosnippet>1405</a> </span><span class="kw">let </span><span class="kw-2">mut </span>exts = take_u16_prefixed(<span class="kw-2">&amp;mut </span>body)<span class="question-mark">?</span>;
<a href=#1406 id=1406 data-nosnippet>1406</a> <span class="kw">while </span>exts.has_remaining() {
<a href=#1407 id=1407 data-nosnippet>1407</a> <span class="kw">let </span>ext_type = u16::decode(<span class="kw-2">&amp;mut </span>exts)<span class="question-mark">?</span>;
<a href=#1408 id=1408 data-nosnippet>1408</a> <span class="kw">let </span>ext_data = take_u16_prefixed(<span class="kw-2">&amp;mut </span>exts)<span class="question-mark">?</span>;
<a href=#1409 id=1409 data-nosnippet>1409</a> <span class="kw">if </span>ext_type == TLS_EXTENSION_TYPE_ALPN {
<a href=#1410 id=1410 data-nosnippet>1410</a> <span class="kw">let </span>list = take_u16_prefixed(<span class="kw-2">&amp;mut &amp;*</span>ext_data)<span class="question-mark">?</span>;
<a href=#1411 id=1411 data-nosnippet>1411</a> <span class="kw">return </span><span class="prelude-val">Ok</span>(source.slice_ref(list));
<a href=#1412 id=1412 data-nosnippet>1412</a> }
<a href=#1413 id=1413 data-nosnippet>1413</a> }
<a href=#1414 id=1414 data-nosnippet>1414</a> <span class="prelude-val">Err</span>(UnexpectedEnd)
<a href=#1415 id=1415 data-nosnippet>1415</a>}
<a href=#1416 id=1416 data-nosnippet>1416</a>
<a href=#1417 id=1417 data-nosnippet>1417</a><span class="doccomment">/// Decode a big-endian u24 as usize
<a href=#1418 id=1418 data-nosnippet>1418</a></span><span class="kw">fn </span>decode_u24(r: <span class="kw-2">&amp;mut &amp;</span>[u8]) -&gt; <span class="prelude-ty">Result</span>&lt;usize, UnexpectedEnd&gt; {
<a href=#1419 id=1419 data-nosnippet>1419</a> <span class="kw">let </span>a = u8::decode(r)<span class="question-mark">?</span>;
<a href=#1420 id=1420 data-nosnippet>1420</a> <span class="kw">let </span>b = u8::decode(r)<span class="question-mark">?</span>;
<a href=#1421 id=1421 data-nosnippet>1421</a> <span class="kw">let </span>c = u8::decode(r)<span class="question-mark">?</span>;
<a href=#1422 id=1422 data-nosnippet>1422</a> <span class="prelude-val">Ok</span>(u32::from_be_bytes([<span class="number">0</span>, a, b, c]) <span class="kw">as </span>usize)
<a href=#1423 id=1423 data-nosnippet>1423</a>}
<a href=#1424 id=1424 data-nosnippet>1424</a>
<a href=#1425 id=1425 data-nosnippet>1425</a><span class="doccomment">/// Take `len` bytes from the front and return them as a sub-slice
<a href=#1426 id=1426 data-nosnippet>1426</a></span><span class="kw">fn </span>take&lt;<span class="lifetime">'a</span>&gt;(r: <span class="kw-2">&amp;mut &amp;</span><span class="lifetime">'a </span>[u8], len: usize) -&gt; <span class="prelude-ty">Result</span>&lt;<span class="kw-2">&amp;</span><span class="lifetime">'a </span>[u8], UnexpectedEnd&gt; {
<a href=#1427 id=1427 data-nosnippet>1427</a> <span class="kw">if </span>r.remaining() &lt; len {
<a href=#1428 id=1428 data-nosnippet>1428</a> <span class="kw">return </span><span class="prelude-val">Err</span>(UnexpectedEnd);
<a href=#1429 id=1429 data-nosnippet>1429</a> }
<a href=#1430 id=1430 data-nosnippet>1430</a> <span class="kw">let </span>data = <span class="kw-2">&amp;</span>r[..len];
<a href=#1431 id=1431 data-nosnippet>1431</a> r.advance(len);
<a href=#1432 id=1432 data-nosnippet>1432</a> <span class="prelude-val">Ok</span>(data)
<a href=#1433 id=1433 data-nosnippet>1433</a>}
<a href=#1434 id=1434 data-nosnippet>1434</a>
<a href=#1435 id=1435 data-nosnippet>1435</a><span class="doccomment">/// Read a u16 length prefix and return the sub-slice it covers
<a href=#1436 id=1436 data-nosnippet>1436</a></span><span class="kw">fn </span>take_u16_prefixed&lt;<span class="lifetime">'a</span>&gt;(r: <span class="kw-2">&amp;mut &amp;</span><span class="lifetime">'a </span>[u8]) -&gt; <span class="prelude-ty">Result</span>&lt;<span class="kw-2">&amp;</span><span class="lifetime">'a </span>[u8], UnexpectedEnd&gt; {
<a href=#1437 id=1437 data-nosnippet>1437</a> <span class="kw">let </span>len = u16::decode(r)<span class="question-mark">? </span><span class="kw">as </span>usize;
<a href=#1438 id=1438 data-nosnippet>1438</a> take(r, len)
<a href=#1439 id=1439 data-nosnippet>1439</a>}
<a href=#1440 id=1440 data-nosnippet>1440</a>
<a href=#1441 id=1441 data-nosnippet>1441</a><span class="doccomment">/// Advance past `n` bytes
<a href=#1442 id=1442 data-nosnippet>1442</a></span><span class="kw">fn </span>skip(r: <span class="kw-2">&amp;mut &amp;</span>[u8], len: usize) -&gt; <span class="prelude-ty">Result</span>&lt;(), UnexpectedEnd&gt; {
<a href=#1443 id=1443 data-nosnippet>1443</a> take(r, len)<span class="question-mark">?</span>;
<a href=#1444 id=1444 data-nosnippet>1444</a> <span class="prelude-val">Ok</span>(())
<a href=#1445 id=1445 data-nosnippet>1445</a>}
<a href=#1446 id=1446 data-nosnippet>1446</a>
<a href=#1447 id=1447 data-nosnippet>1447</a><span class="doccomment">/// Skip a u8-length-prefixed field
<a href=#1448 id=1448 data-nosnippet>1448</a></span><span class="kw">fn </span>skip_u8_prefixed(r: <span class="kw-2">&amp;mut &amp;</span>[u8]) -&gt; <span class="prelude-ty">Result</span>&lt;(), UnexpectedEnd&gt; {
<a href=#1449 id=1449 data-nosnippet>1449</a> <span class="kw">let </span>len = u8::decode(r)<span class="question-mark">? </span><span class="kw">as </span>usize;
<a href=#1450 id=1450 data-nosnippet>1450</a> skip(r, len)
<a href=#1451 id=1451 data-nosnippet>1451</a>}
<a href=#1452 id=1452 data-nosnippet>1452</a>
<a href=#1453 id=1453 data-nosnippet>1453</a><span class="doccomment">/// Skip a u16-length-prefixed field
<a href=#1454 id=1454 data-nosnippet>1454</a></span><span class="kw">fn </span>skip_u16_prefixed(r: <span class="kw-2">&amp;mut &amp;</span>[u8]) -&gt; <span class="prelude-ty">Result</span>&lt;(), UnexpectedEnd&gt; {
<a href=#1455 id=1455 data-nosnippet>1455</a> <span class="kw">let </span>len = u16::decode(r)<span class="question-mark">? </span><span class="kw">as </span>usize;
<a href=#1456 id=1456 data-nosnippet>1456</a> skip(r, len)
<a href=#1457 id=1457 data-nosnippet>1457</a>}
<a href=#1278 id=1278 data-nosnippet>1278</a> /// fast path (single CRYPTO frame), the only allocation is the payload clone
<a href=#1279 id=1279 data-nosnippet>1279</a> /// for decryption.
<a href=#1280 id=1280 data-nosnippet>1280</a> </span><span class="kw">pub fn </span>alpns(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; <span class="prelude-ty">Option</span>&lt;IncomingAlpns&gt; {
<a href=#1281 id=1281 data-nosnippet>1281</a> <span class="kw">let </span>packet_number = <span class="self">self</span>.packet.header.number.expand(<span class="number">0</span>);
<a href=#1282 id=1282 data-nosnippet>1282</a> <span class="kw">let </span><span class="kw-2">mut </span>payload = <span class="self">self</span>.packet.payload.clone();
<a href=#1283 id=1283 data-nosnippet>1283</a> <span class="self">self</span>.crypto
<a href=#1284 id=1284 data-nosnippet>1284</a> .packet
<a href=#1285 id=1285 data-nosnippet>1285</a> .remote
<a href=#1286 id=1286 data-nosnippet>1286</a> .decrypt(
<a href=#1287 id=1287 data-nosnippet>1287</a> PathId::ZERO,
<a href=#1288 id=1288 data-nosnippet>1288</a> packet_number,
<a href=#1289 id=1289 data-nosnippet>1289</a> <span class="kw-2">&amp;</span><span class="self">self</span>.packet.header_data,
<a href=#1290 id=1290 data-nosnippet>1290</a> <span class="kw-2">&amp;mut </span>payload,
<a href=#1291 id=1291 data-nosnippet>1291</a> )
<a href=#1292 id=1292 data-nosnippet>1292</a> .ok()<span class="question-mark">?</span>;
<a href=#1293 id=1293 data-nosnippet>1293</a>
<a href=#1294 id=1294 data-nosnippet>1294</a> <span class="comment">// Collect CRYPTO frames, fast path avoids allocation
<a href=#1295 id=1295 data-nosnippet>1295</a> </span><span class="kw">let </span>frames = frame::Iter::new(payload.freeze()).ok()<span class="question-mark">?</span>;
<a href=#1296 id=1296 data-nosnippet>1296</a> <span class="kw">let </span><span class="kw-2">mut </span>first = <span class="prelude-val">None</span>;
<a href=#1297 id=1297 data-nosnippet>1297</a> <span class="kw">let </span><span class="kw-2">mut </span>rest = Vec::new();
<a href=#1298 id=1298 data-nosnippet>1298</a> <span class="kw">for </span>frame <span class="kw">in </span>frames {
<a href=#1299 id=1299 data-nosnippet>1299</a> <span class="kw">match </span>(frame.ok()<span class="question-mark">?</span>, <span class="kw-2">&amp;</span>first) {
<a href=#1300 id=1300 data-nosnippet>1300</a> (frame::Frame::Crypto(crypto), <span class="prelude-val">None</span>) =&gt; first = <span class="prelude-val">Some</span>(crypto),
<a href=#1301 id=1301 data-nosnippet>1301</a> (frame::Frame::Crypto(crypto), <span class="prelude-val">Some</span>(<span class="kw">_</span>)) =&gt; rest.push(crypto),
<a href=#1302 id=1302 data-nosnippet>1302</a> <span class="kw">_ </span>=&gt; {}
<a href=#1303 id=1303 data-nosnippet>1303</a> }
<a href=#1304 id=1304 data-nosnippet>1304</a> }
<a href=#1305 id=1305 data-nosnippet>1305</a> <span class="kw">let </span>first = first<span class="question-mark">?</span>;
<a href=#1306 id=1306 data-nosnippet>1306</a>
<a href=#1307 id=1307 data-nosnippet>1307</a> <span class="comment">// Fast path: single CRYPTO frame at offset 0 (no Vec allocated)
<a href=#1308 id=1308 data-nosnippet>1308</a> </span><span class="kw">if </span>rest.is_empty() &amp;&amp; first.offset == <span class="number">0 </span>{
<a href=#1309 id=1309 data-nosnippet>1309</a> <span class="kw">let </span>data = find_alpn_data(<span class="kw-2">&amp;</span>first.data).ok()<span class="question-mark">?</span>;
<a href=#1310 id=1310 data-nosnippet>1310</a> <span class="kw">return </span><span class="prelude-val">Some</span>(IncomingAlpns { data, pos: <span class="number">0 </span>});
<a href=#1311 id=1311 data-nosnippet>1311</a> }
<a href=#1312 id=1312 data-nosnippet>1312</a>
<a href=#1313 id=1313 data-nosnippet>1313</a> <span class="comment">// Slow path: reassemble multiple CRYPTO frames
<a href=#1314 id=1314 data-nosnippet>1314</a> </span>rest.push(first);
<a href=#1315 id=1315 data-nosnippet>1315</a> <span class="kw">let </span>source = assemble_crypto_frames(<span class="kw-2">&amp;mut </span>rest)<span class="question-mark">?</span>;
<a href=#1316 id=1316 data-nosnippet>1316</a> <span class="kw">let </span>data = find_alpn_data(<span class="kw-2">&amp;</span>source).ok()<span class="question-mark">?</span>;
<a href=#1317 id=1317 data-nosnippet>1317</a> <span class="prelude-val">Some</span>(IncomingAlpns { data, pos: <span class="number">0 </span>})
<a href=#1318 id=1318 data-nosnippet>1318</a> }
<a href=#1319 id=1319 data-nosnippet>1319</a>}
<a href=#1320 id=1320 data-nosnippet>1320</a>
<a href=#1321 id=1321 data-nosnippet>1321</a><span class="doccomment">/// TLS handshake type for ClientHello messages
<a href=#1322 id=1322 data-nosnippet>1322</a>/// &lt;https://www.rfc-editor.org/rfc/rfc8446#section-4.1.2&gt;
<a href=#1323 id=1323 data-nosnippet>1323</a></span><span class="kw">const </span>TLS_HANDSHAKE_TYPE_CLIENT_HELLO: u8 = <span class="number">0x01</span>;
<a href=#1324 id=1324 data-nosnippet>1324</a><span class="doccomment">/// TLS extension type for Application-Layer Protocol Negotiation
<a href=#1325 id=1325 data-nosnippet>1325</a>/// &lt;https://www.rfc-editor.org/rfc/rfc7301#section-3.1&gt;
<a href=#1326 id=1326 data-nosnippet>1326</a></span><span class="kw">const </span>TLS_EXTENSION_TYPE_ALPN: u16 = <span class="number">0x0010</span>;
<a href=#1327 id=1327 data-nosnippet>1327</a><span class="doccomment">/// Size of the fixed-length fields in a ClientHello (client_version + random)
<a href=#1328 id=1328 data-nosnippet>1328</a>/// &lt;https://www.rfc-editor.org/rfc/rfc8446#section-4.1.2&gt;
<a href=#1329 id=1329 data-nosnippet>1329</a></span><span class="kw">const </span>TLS_CLIENT_HELLO_FIXED_LEN: usize = <span class="number">2 </span>+ <span class="number">32</span>;
<a href=#1330 id=1330 data-nosnippet>1330</a>
<a href=#1331 id=1331 data-nosnippet>1331</a><span class="doccomment">/// Iterator over ALPN protocol names from a TLS ClientHello
<a href=#1332 id=1332 data-nosnippet>1332</a>///
<a href=#1333 id=1333 data-nosnippet>1333</a>/// Yields protocol names as [`Bytes`] slices. On the common fast path (single
<a href=#1334 id=1334 data-nosnippet>1334</a>/// CRYPTO frame), the only allocation is the payload clone for decryption.
<a href=#1335 id=1335 data-nosnippet>1335</a></span><span class="kw">pub struct </span>IncomingAlpns {
<a href=#1336 id=1336 data-nosnippet>1336</a> data: Bytes,
<a href=#1337 id=1337 data-nosnippet>1337</a> pos: usize,
<a href=#1338 id=1338 data-nosnippet>1338</a>}
<a href=#1339 id=1339 data-nosnippet>1339</a>
<a href=#1340 id=1340 data-nosnippet>1340</a><span class="kw">impl </span>Iterator <span class="kw">for </span>IncomingAlpns {
<a href=#1341 id=1341 data-nosnippet>1341</a> <span class="kw">type </span>Item = <span class="prelude-ty">Result</span>&lt;Bytes, UnexpectedEnd&gt;;
<a href=#1342 id=1342 data-nosnippet>1342</a>
<a href=#1343 id=1343 data-nosnippet>1343</a> <span class="kw">fn </span>next(<span class="kw-2">&amp;mut </span><span class="self">self</span>) -&gt; <span class="prelude-ty">Option</span>&lt;<span class="self">Self</span>::Item&gt; {
<a href=#1344 id=1344 data-nosnippet>1344</a> <span class="kw">if </span><span class="self">self</span>.pos &gt;= <span class="self">self</span>.data.len() {
<a href=#1345 id=1345 data-nosnippet>1345</a> <span class="kw">return </span><span class="prelude-val">None</span>;
<a href=#1346 id=1346 data-nosnippet>1346</a> }
<a href=#1347 id=1347 data-nosnippet>1347</a> <span class="kw">let </span>len = <span class="self">self</span>.data[<span class="self">self</span>.pos] <span class="kw">as </span>usize;
<a href=#1348 id=1348 data-nosnippet>1348</a> <span class="self">self</span>.pos += <span class="number">1</span>;
<a href=#1349 id=1349 data-nosnippet>1349</a> <span class="kw">if </span><span class="self">self</span>.pos + len &gt; <span class="self">self</span>.data.len() {
<a href=#1350 id=1350 data-nosnippet>1350</a> <span class="kw">return </span><span class="prelude-val">Some</span>(<span class="prelude-val">Err</span>(UnexpectedEnd));
<a href=#1351 id=1351 data-nosnippet>1351</a> }
<a href=#1352 id=1352 data-nosnippet>1352</a> <span class="kw">let </span>proto = <span class="self">self</span>.data.slice(<span class="self">self</span>.pos..<span class="self">self</span>.pos + len);
<a href=#1353 id=1353 data-nosnippet>1353</a> <span class="self">self</span>.pos += len;
<a href=#1354 id=1354 data-nosnippet>1354</a> <span class="prelude-val">Some</span>(<span class="prelude-val">Ok</span>(proto))
<a href=#1355 id=1355 data-nosnippet>1355</a> }
<a href=#1356 id=1356 data-nosnippet>1356</a>}
<a href=#1357 id=1357 data-nosnippet>1357</a>
<a href=#1358 id=1358 data-nosnippet>1358</a><span class="doccomment">/// Sort CRYPTO frames by offset and concatenate into a contiguous `Bytes`
<a href=#1359 id=1359 data-nosnippet>1359</a>///
<a href=#1360 id=1360 data-nosnippet>1360</a>/// Returns `None` if there are gaps in the stream.
<a href=#1361 id=1361 data-nosnippet>1361</a></span><span class="kw">fn </span>assemble_crypto_frames(frames: <span class="kw-2">&amp;mut </span>[frame::Crypto]) -&gt; <span class="prelude-ty">Option</span>&lt;Bytes&gt; {
<a href=#1362 id=1362 data-nosnippet>1362</a> frames.sort_by_key(|f| f.offset);
<a href=#1363 id=1363 data-nosnippet>1363</a> <span class="kw">let </span>capacity = frames.iter().map(|f| f.data.len()).sum();
<a href=#1364 id=1364 data-nosnippet>1364</a> <span class="kw">let </span><span class="kw-2">mut </span>buf = Vec::with_capacity(capacity);
<a href=#1365 id=1365 data-nosnippet>1365</a> <span class="kw">for </span>f <span class="kw">in </span>frames.iter() {
<a href=#1366 id=1366 data-nosnippet>1366</a> <span class="kw">let </span>start = f.offset <span class="kw">as </span>usize;
<a href=#1367 id=1367 data-nosnippet>1367</a> <span class="kw">if </span>start &gt; buf.len() {
<a href=#1368 id=1368 data-nosnippet>1368</a> <span class="kw">return </span><span class="prelude-val">None</span>;
<a href=#1369 id=1369 data-nosnippet>1369</a> }
<a href=#1370 id=1370 data-nosnippet>1370</a> <span class="kw">let </span>end = start + f.data.len();
<a href=#1371 id=1371 data-nosnippet>1371</a> <span class="kw">if </span>end &gt; buf.len() {
<a href=#1372 id=1372 data-nosnippet>1372</a> buf.extend_from_slice(<span class="kw-2">&amp;</span>f.data[buf.len() - start..]);
<a href=#1373 id=1373 data-nosnippet>1373</a> }
<a href=#1374 id=1374 data-nosnippet>1374</a> }
<a href=#1375 id=1375 data-nosnippet>1375</a> <span class="prelude-val">Some</span>(Bytes::from(buf))
<a href=#1376 id=1376 data-nosnippet>1376</a>}
<a href=#1377 id=1377 data-nosnippet>1377</a>
<a href=#1378 id=1378 data-nosnippet>1378</a><span class="doccomment">/// Locate the raw ALPN protocol list data within a TLS ClientHello message
<a href=#1379 id=1379 data-nosnippet>1379</a>///
<a href=#1380 id=1380 data-nosnippet>1380</a>/// Parses the ClientHello in `source` and returns a [`Bytes`] containing the
<a href=#1381 id=1381 data-nosnippet>1381</a>/// u8-length-prefixed protocol names (after the outer ProtocolNameList u16
<a href=#1382 id=1382 data-nosnippet>1382</a>/// length prefix). The returned `Bytes` is a zero-copy slice of `source`.
<a href=#1383 id=1383 data-nosnippet>1383</a></span><span class="kw">fn </span>find_alpn_data(source: <span class="kw-2">&amp;</span>Bytes) -&gt; <span class="prelude-ty">Result</span>&lt;Bytes, UnexpectedEnd&gt; {
<a href=#1384 id=1384 data-nosnippet>1384</a> <span class="kw">let </span><span class="kw-2">mut </span>r = <span class="kw-2">&amp;**</span>source;
<a href=#1385 id=1385 data-nosnippet>1385</a>
<a href=#1386 id=1386 data-nosnippet>1386</a> <span class="kw">if </span>u8::decode(<span class="kw-2">&amp;mut </span>r)<span class="question-mark">? </span>!= TLS_HANDSHAKE_TYPE_CLIENT_HELLO {
<a href=#1387 id=1387 data-nosnippet>1387</a> <span class="kw">return </span><span class="prelude-val">Err</span>(UnexpectedEnd);
<a href=#1388 id=1388 data-nosnippet>1388</a> }
<a href=#1389 id=1389 data-nosnippet>1389</a>
<a href=#1390 id=1390 data-nosnippet>1390</a> <span class="comment">// Handshake message length (u24), scopes the remainder
<a href=#1391 id=1391 data-nosnippet>1391</a> </span><span class="kw">let </span>len = decode_u24(<span class="kw-2">&amp;mut </span>r)<span class="question-mark">?</span>;
<a href=#1392 id=1392 data-nosnippet>1392</a> <span class="kw">let </span><span class="kw-2">mut </span>body = take(<span class="kw-2">&amp;mut </span>r, len)<span class="question-mark">?</span>;
<a href=#1393 id=1393 data-nosnippet>1393</a>
<a href=#1394 id=1394 data-nosnippet>1394</a> <span class="comment">// Client version + random
<a href=#1395 id=1395 data-nosnippet>1395</a> </span>skip(<span class="kw-2">&amp;mut </span>body, TLS_CLIENT_HELLO_FIXED_LEN)<span class="question-mark">?</span>;
<a href=#1396 id=1396 data-nosnippet>1396</a>
<a href=#1397 id=1397 data-nosnippet>1397</a> <span class="comment">// Session ID, cipher suites, compression methods
<a href=#1398 id=1398 data-nosnippet>1398</a> </span>skip_u8_prefixed(<span class="kw-2">&amp;mut </span>body)<span class="question-mark">?</span>;
<a href=#1399 id=1399 data-nosnippet>1399</a> skip_u16_prefixed(<span class="kw-2">&amp;mut </span>body)<span class="question-mark">?</span>;
<a href=#1400 id=1400 data-nosnippet>1400</a> skip_u8_prefixed(<span class="kw-2">&amp;mut </span>body)<span class="question-mark">?</span>;
<a href=#1401 id=1401 data-nosnippet>1401</a>
<a href=#1402 id=1402 data-nosnippet>1402</a> <span class="comment">// Extensions
<a href=#1403 id=1403 data-nosnippet>1403</a> </span><span class="kw">let </span><span class="kw-2">mut </span>exts = take_u16_prefixed(<span class="kw-2">&amp;mut </span>body)<span class="question-mark">?</span>;
<a href=#1404 id=1404 data-nosnippet>1404</a> <span class="kw">while </span>exts.has_remaining() {
<a href=#1405 id=1405 data-nosnippet>1405</a> <span class="kw">let </span>ext_type = u16::decode(<span class="kw-2">&amp;mut </span>exts)<span class="question-mark">?</span>;
<a href=#1406 id=1406 data-nosnippet>1406</a> <span class="kw">let </span>ext_data = take_u16_prefixed(<span class="kw-2">&amp;mut </span>exts)<span class="question-mark">?</span>;
<a href=#1407 id=1407 data-nosnippet>1407</a> <span class="kw">if </span>ext_type == TLS_EXTENSION_TYPE_ALPN {
<a href=#1408 id=1408 data-nosnippet>1408</a> <span class="kw">let </span>list = take_u16_prefixed(<span class="kw-2">&amp;mut &amp;*</span>ext_data)<span class="question-mark">?</span>;
<a href=#1409 id=1409 data-nosnippet>1409</a> <span class="kw">return </span><span class="prelude-val">Ok</span>(source.slice_ref(list));
<a href=#1410 id=1410 data-nosnippet>1410</a> }
<a href=#1411 id=1411 data-nosnippet>1411</a> }
<a href=#1412 id=1412 data-nosnippet>1412</a> <span class="prelude-val">Err</span>(UnexpectedEnd)
<a href=#1413 id=1413 data-nosnippet>1413</a>}
<a href=#1414 id=1414 data-nosnippet>1414</a>
<a href=#1415 id=1415 data-nosnippet>1415</a><span class="doccomment">/// Decode a big-endian u24 as usize
<a href=#1416 id=1416 data-nosnippet>1416</a></span><span class="kw">fn </span>decode_u24(r: <span class="kw-2">&amp;mut &amp;</span>[u8]) -&gt; <span class="prelude-ty">Result</span>&lt;usize, UnexpectedEnd&gt; {
<a href=#1417 id=1417 data-nosnippet>1417</a> <span class="kw">let </span>a = u8::decode(r)<span class="question-mark">?</span>;
<a href=#1418 id=1418 data-nosnippet>1418</a> <span class="kw">let </span>b = u8::decode(r)<span class="question-mark">?</span>;
<a href=#1419 id=1419 data-nosnippet>1419</a> <span class="kw">let </span>c = u8::decode(r)<span class="question-mark">?</span>;
<a href=#1420 id=1420 data-nosnippet>1420</a> <span class="prelude-val">Ok</span>(u32::from_be_bytes([<span class="number">0</span>, a, b, c]) <span class="kw">as </span>usize)
<a href=#1421 id=1421 data-nosnippet>1421</a>}
<a href=#1422 id=1422 data-nosnippet>1422</a>
<a href=#1423 id=1423 data-nosnippet>1423</a><span class="doccomment">/// Take `len` bytes from the front and return them as a sub-slice
<a href=#1424 id=1424 data-nosnippet>1424</a></span><span class="kw">fn </span>take&lt;<span class="lifetime">'a</span>&gt;(r: <span class="kw-2">&amp;mut &amp;</span><span class="lifetime">'a </span>[u8], len: usize) -&gt; <span class="prelude-ty">Result</span>&lt;<span class="kw-2">&amp;</span><span class="lifetime">'a </span>[u8], UnexpectedEnd&gt; {
<a href=#1425 id=1425 data-nosnippet>1425</a> <span class="kw">if </span>r.remaining() &lt; len {
<a href=#1426 id=1426 data-nosnippet>1426</a> <span class="kw">return </span><span class="prelude-val">Err</span>(UnexpectedEnd);
<a href=#1427 id=1427 data-nosnippet>1427</a> }
<a href=#1428 id=1428 data-nosnippet>1428</a> <span class="kw">let </span>data = <span class="kw-2">&amp;</span>r[..len];
<a href=#1429 id=1429 data-nosnippet>1429</a> r.advance(len);
<a href=#1430 id=1430 data-nosnippet>1430</a> <span class="prelude-val">Ok</span>(data)
<a href=#1431 id=1431 data-nosnippet>1431</a>}
<a href=#1432 id=1432 data-nosnippet>1432</a>
<a href=#1433 id=1433 data-nosnippet>1433</a><span class="doccomment">/// Read a u16 length prefix and return the sub-slice it covers
<a href=#1434 id=1434 data-nosnippet>1434</a></span><span class="kw">fn </span>take_u16_prefixed&lt;<span class="lifetime">'a</span>&gt;(r: <span class="kw-2">&amp;mut &amp;</span><span class="lifetime">'a </span>[u8]) -&gt; <span class="prelude-ty">Result</span>&lt;<span class="kw-2">&amp;</span><span class="lifetime">'a </span>[u8], UnexpectedEnd&gt; {
<a href=#1435 id=1435 data-nosnippet>1435</a> <span class="kw">let </span>len = u16::decode(r)<span class="question-mark">? </span><span class="kw">as </span>usize;
<a href=#1436 id=1436 data-nosnippet>1436</a> take(r, len)
<a href=#1437 id=1437 data-nosnippet>1437</a>}
<a href=#1438 id=1438 data-nosnippet>1438</a>
<a href=#1439 id=1439 data-nosnippet>1439</a><span class="doccomment">/// Advance past `n` bytes
<a href=#1440 id=1440 data-nosnippet>1440</a></span><span class="kw">fn </span>skip(r: <span class="kw-2">&amp;mut &amp;</span>[u8], len: usize) -&gt; <span class="prelude-ty">Result</span>&lt;(), UnexpectedEnd&gt; {
<a href=#1441 id=1441 data-nosnippet>1441</a> take(r, len)<span class="question-mark">?</span>;
<a href=#1442 id=1442 data-nosnippet>1442</a> <span class="prelude-val">Ok</span>(())
<a href=#1443 id=1443 data-nosnippet>1443</a>}
<a href=#1444 id=1444 data-nosnippet>1444</a>
<a href=#1445 id=1445 data-nosnippet>1445</a><span class="doccomment">/// Skip a u8-length-prefixed field
<a href=#1446 id=1446 data-nosnippet>1446</a></span><span class="kw">fn </span>skip_u8_prefixed(r: <span class="kw-2">&amp;mut &amp;</span>[u8]) -&gt; <span class="prelude-ty">Result</span>&lt;(), UnexpectedEnd&gt; {
<a href=#1447 id=1447 data-nosnippet>1447</a> <span class="kw">let </span>len = u8::decode(r)<span class="question-mark">? </span><span class="kw">as </span>usize;
<a href=#1448 id=1448 data-nosnippet>1448</a> skip(r, len)
<a href=#1449 id=1449 data-nosnippet>1449</a>}
<a href=#1450 id=1450 data-nosnippet>1450</a>
<a href=#1451 id=1451 data-nosnippet>1451</a><span class="doccomment">/// Skip a u16-length-prefixed field
<a href=#1452 id=1452 data-nosnippet>1452</a></span><span class="kw">fn </span>skip_u16_prefixed(r: <span class="kw-2">&amp;mut &amp;</span>[u8]) -&gt; <span class="prelude-ty">Result</span>&lt;(), UnexpectedEnd&gt; {
<a href=#1453 id=1453 data-nosnippet>1453</a> <span class="kw">let </span>len = u16::decode(r)<span class="question-mark">? </span><span class="kw">as </span>usize;
<a href=#1454 id=1454 data-nosnippet>1454</a> skip(r, len)
<a href=#1455 id=1455 data-nosnippet>1455</a>}
<a href=#1456 id=1456 data-nosnippet>1456</a>
<a href=#1457 id=1457 data-nosnippet>1457</a><span class="kw">struct </span>IncomingImproperDropWarner;
<a href=#1458 id=1458 data-nosnippet>1458</a>
<a href=#1459 id=1459 data-nosnippet>1459</a><span class="kw">struct </span>IncomingImproperDropWarner;
<a href=#1460 id=1460 data-nosnippet>1460</a>
<a href=#1461 id=1461 data-nosnippet>1461</a><span class="kw">impl </span>IncomingImproperDropWarner {
<a href=#1462 id=1462 data-nosnippet>1462</a> <span class="kw">fn </span>dismiss(<span class="self">self</span>) {
<a href=#1463 id=1463 data-nosnippet>1463</a> mem::forget(<span class="self">self</span>);
<a href=#1464 id=1464 data-nosnippet>1464</a> }
<a href=#1465 id=1465 data-nosnippet>1465</a>}
<a href=#1466 id=1466 data-nosnippet>1466</a>
<a href=#1467 id=1467 data-nosnippet>1467</a><span class="kw">impl </span>Drop <span class="kw">for </span>IncomingImproperDropWarner {
<a href=#1468 id=1468 data-nosnippet>1468</a> <span class="kw">fn </span>drop(<span class="kw-2">&amp;mut </span><span class="self">self</span>) {
<a href=#1469 id=1469 data-nosnippet>1469</a> <span class="macro">warn!</span>(
<a href=#1470 id=1470 data-nosnippet>1470</a> <span class="string">"quinn_proto::Incoming dropped without passing to Endpoint::accept/refuse/retry/ignore \
<a href=#1471 id=1471 data-nosnippet>1471</a> (may cause memory leak and eventual inability to accept new connections)"
<a href=#1472 id=1472 data-nosnippet>1472</a> </span>);
<a href=#1473 id=1473 data-nosnippet>1473</a> }
<a href=#1474 id=1474 data-nosnippet>1474</a>}
<a href=#1475 id=1475 data-nosnippet>1475</a>
<a href=#1476 id=1476 data-nosnippet>1476</a><span class="doccomment">/// Errors in the parameters being used to create a new connection
<a href=#1477 id=1477 data-nosnippet>1477</a>///
<a href=#1478 id=1478 data-nosnippet>1478</a>/// These arise before any I/O has been performed.
<a href=#1479 id=1479 data-nosnippet>1479</a></span><span class="attr">#[derive(Debug, Error, Clone, PartialEq, Eq)]
<a href=#1480 id=1480 data-nosnippet>1480</a></span><span class="kw">pub enum </span>ConnectError {
<a href=#1481 id=1481 data-nosnippet>1481</a> <span class="doccomment">/// The endpoint can no longer create new connections
<a href=#1482 id=1482 data-nosnippet>1482</a> ///
<a href=#1483 id=1483 data-nosnippet>1483</a> /// Indicates that a necessary component of the endpoint has been dropped or otherwise disabled.
<a href=#1484 id=1484 data-nosnippet>1484</a> </span><span class="attr">#[error(<span class="string">"endpoint stopping"</span>)]
<a href=#1485 id=1485 data-nosnippet>1485</a> </span>EndpointStopping,
<a href=#1486 id=1486 data-nosnippet>1486</a> <span class="doccomment">/// The connection could not be created because not enough of the CID space is available
<a href=#1487 id=1487 data-nosnippet>1487</a> ///
<a href=#1488 id=1488 data-nosnippet>1488</a> /// Try using longer connection IDs
<a href=#1489 id=1489 data-nosnippet>1489</a> </span><span class="attr">#[error(<span class="string">"CIDs exhausted"</span>)]
<a href=#1490 id=1490 data-nosnippet>1490</a> </span>CidsExhausted,
<a href=#1491 id=1491 data-nosnippet>1491</a> <span class="doccomment">/// The given server name was malformed
<a href=#1492 id=1492 data-nosnippet>1492</a> </span><span class="attr">#[error(<span class="string">"invalid server name: {0}"</span>)]
<a href=#1493 id=1493 data-nosnippet>1493</a> </span>InvalidServerName(String),
<a href=#1494 id=1494 data-nosnippet>1494</a> <span class="doccomment">/// The remote [`SocketAddr`] supplied was malformed
<a href=#1495 id=1495 data-nosnippet>1495</a> ///
<a href=#1496 id=1496 data-nosnippet>1496</a> /// Examples include attempting to connect to port 0, or using an inappropriate address family.
<a href=#1497 id=1497 data-nosnippet>1497</a> </span><span class="attr">#[error(<span class="string">"invalid remote address: {0}"</span>)]
<a href=#1498 id=1498 data-nosnippet>1498</a> </span>InvalidRemoteAddress(SocketAddr),
<a href=#1499 id=1499 data-nosnippet>1499</a> <span class="doccomment">/// No default client configuration was set up
<a href=#1500 id=1500 data-nosnippet>1500</a> ///
<a href=#1501 id=1501 data-nosnippet>1501</a> /// Use `Endpoint::connect_with` to specify a client configuration.
<a href=#1502 id=1502 data-nosnippet>1502</a> </span><span class="attr">#[error(<span class="string">"no default client config"</span>)]
<a href=#1503 id=1503 data-nosnippet>1503</a> </span>NoDefaultClientConfig,
<a href=#1504 id=1504 data-nosnippet>1504</a> <span class="doccomment">/// The local endpoint does not support the QUIC version specified in the client configuration
<a href=#1505 id=1505 data-nosnippet>1505</a> </span><span class="attr">#[error(<span class="string">"unsupported QUIC version"</span>)]
<a href=#1506 id=1506 data-nosnippet>1506</a> </span>UnsupportedVersion,
<a href=#1507 id=1507 data-nosnippet>1507</a>}
<a href=#1508 id=1508 data-nosnippet>1508</a>
<a href=#1509 id=1509 data-nosnippet>1509</a><span class="doccomment">/// Error type for attempting to accept an [`Incoming`]
<a href=#1510 id=1510 data-nosnippet>1510</a></span><span class="attr">#[derive(Debug)]
<a href=#1511 id=1511 data-nosnippet>1511</a></span><span class="kw">pub struct </span>AcceptError {
<a href=#1512 id=1512 data-nosnippet>1512</a> <span class="doccomment">/// Underlying error describing reason for failure
<a href=#1513 id=1513 data-nosnippet>1513</a> </span><span class="kw">pub </span>cause: ConnectionError,
<a href=#1514 id=1514 data-nosnippet>1514</a> <span class="doccomment">/// Optional response to transmit back
<a href=#1515 id=1515 data-nosnippet>1515</a> </span><span class="kw">pub </span>response: <span class="prelude-ty">Option</span>&lt;Transmit&gt;,
<a href=#1516 id=1516 data-nosnippet>1516</a>}
<a href=#1517 id=1517 data-nosnippet>1517</a>
<a href=#1518 id=1518 data-nosnippet>1518</a><span class="doccomment">/// Error for attempting to retry an [`Incoming`] which already bears a token from a previous retry
<a href=#1519 id=1519 data-nosnippet>1519</a></span><span class="attr">#[derive(Debug, Error)]
<a href=#1520 id=1520 data-nosnippet>1520</a>#[error(<span class="string">"retry() with validated Incoming"</span>)]
<a href=#1521 id=1521 data-nosnippet>1521</a></span><span class="kw">pub struct </span>RetryError(Box&lt;Incoming&gt;);
<a href=#1522 id=1522 data-nosnippet>1522</a>
<a href=#1523 id=1523 data-nosnippet>1523</a><span class="kw">impl </span>RetryError {
<a href=#1524 id=1524 data-nosnippet>1524</a> <span class="doccomment">/// Get the [`Incoming`]
<a href=#1525 id=1525 data-nosnippet>1525</a> </span><span class="kw">pub fn </span>into_incoming(<span class="self">self</span>) -&gt; Incoming {
<a href=#1526 id=1526 data-nosnippet>1526</a> <span class="kw-2">*</span><span class="self">self</span>.<span class="number">0
<a href=#1527 id=1527 data-nosnippet>1527</a> </span>}
<a href=#1528 id=1528 data-nosnippet>1528</a>}
<a href=#1529 id=1529 data-nosnippet>1529</a>
<a href=#1530 id=1530 data-nosnippet>1530</a><span class="doccomment">/// Reset Tokens which are associated with peer socket addresses
<a href=#1531 id=1531 data-nosnippet>1531</a>///
<a href=#1532 id=1532 data-nosnippet>1532</a>/// The standard `HashMap` is used since both `SocketAddr` and `ResetToken` are
<a href=#1533 id=1533 data-nosnippet>1533</a>/// peer generated and might be usable for hash collision attacks.
<a href=#1534 id=1534 data-nosnippet>1534</a></span><span class="attr">#[derive(Default, Debug)]
<a href=#1535 id=1535 data-nosnippet>1535</a></span><span class="kw">struct </span>ResetTokenTable(HashMap&lt;SocketAddr, HashMap&lt;ResetToken, ConnectionHandle&gt;&gt;);
<a href=#1536 id=1536 data-nosnippet>1536</a>
<a href=#1537 id=1537 data-nosnippet>1537</a><span class="kw">impl </span>ResetTokenTable {
<a href=#1538 id=1538 data-nosnippet>1538</a> <span class="kw">fn </span>insert(<span class="kw-2">&amp;mut </span><span class="self">self</span>, remote: SocketAddr, token: ResetToken, ch: ConnectionHandle) -&gt; bool {
<a href=#1539 id=1539 data-nosnippet>1539</a> <span class="self">self</span>.<span class="number">0
<a href=#1540 id=1540 data-nosnippet>1540</a> </span>.entry(remote)
<a href=#1541 id=1541 data-nosnippet>1541</a> .or_default()
<a href=#1542 id=1542 data-nosnippet>1542</a> .insert(token, ch)
<a href=#1543 id=1543 data-nosnippet>1543</a> .is_some()
<a href=#1544 id=1544 data-nosnippet>1544</a> }
<a href=#1545 id=1545 data-nosnippet>1545</a>
<a href=#1546 id=1546 data-nosnippet>1546</a> <span class="kw">fn </span>remove(<span class="kw-2">&amp;mut </span><span class="self">self</span>, remote: SocketAddr, token: ResetToken) {
<a href=#1547 id=1547 data-nosnippet>1547</a> <span class="kw">use </span>std::collections::hash_map::Entry;
<a href=#1548 id=1548 data-nosnippet>1548</a> <span class="kw">match </span><span class="self">self</span>.<span class="number">0</span>.entry(remote) {
<a href=#1549 id=1549 data-nosnippet>1549</a> Entry::Vacant(<span class="kw">_</span>) =&gt; {}
<a href=#1550 id=1550 data-nosnippet>1550</a> Entry::Occupied(<span class="kw-2">mut </span>e) =&gt; {
<a href=#1551 id=1551 data-nosnippet>1551</a> e.get_mut().remove(<span class="kw-2">&amp;</span>token);
<a href=#1552 id=1552 data-nosnippet>1552</a> <span class="kw">if </span>e.get().is_empty() {
<a href=#1553 id=1553 data-nosnippet>1553</a> e.remove_entry();
<a href=#1554 id=1554 data-nosnippet>1554</a> }
<a href=#1555 id=1555 data-nosnippet>1555</a> }
<a href=#1556 id=1556 data-nosnippet>1556</a> }
<a href=#1557 id=1557 data-nosnippet>1557</a> }
<a href=#1558 id=1558 data-nosnippet>1558</a>
<a href=#1559 id=1559 data-nosnippet>1559</a> <span class="kw">fn </span>get(<span class="kw-2">&amp;</span><span class="self">self</span>, remote: SocketAddr, token: <span class="kw-2">&amp;</span>[u8]) -&gt; <span class="prelude-ty">Option</span>&lt;<span class="kw-2">&amp;</span>ConnectionHandle&gt; {
<a href=#1560 id=1560 data-nosnippet>1560</a> <span class="kw">let </span>token = ResetToken::from(&lt;[u8; RESET_TOKEN_SIZE]&gt;::try_from(token).ok()<span class="question-mark">?</span>);
<a href=#1561 id=1561 data-nosnippet>1561</a> <span class="self">self</span>.<span class="number">0</span>.get(<span class="kw-2">&amp;</span>remote)<span class="question-mark">?</span>.get(<span class="kw-2">&amp;</span>token)
<a href=#1562 id=1562 data-nosnippet>1562</a> }
<a href=#1563 id=1563 data-nosnippet>1563</a>}
<a href=#1564 id=1564 data-nosnippet>1564</a>
<a href=#1565 id=1565 data-nosnippet>1565</a><span class="attr">#[cfg(test)]
<a href=#1566 id=1566 data-nosnippet>1566</a></span><span class="kw">mod </span>tests {
<a href=#1567 id=1567 data-nosnippet>1567</a> <span class="kw">use super</span>::<span class="kw-2">*</span>;
<a href=#1568 id=1568 data-nosnippet>1568</a>
<a href=#1569 id=1569 data-nosnippet>1569</a> <span class="attr">#[test]
<a href=#1570 id=1570 data-nosnippet>1570</a> </span><span class="kw">fn </span>assemble_contiguous() {
<a href=#1571 id=1571 data-nosnippet>1571</a> <span class="kw">let </span>data = <span class="string">b"hello world"</span>;
<a href=#1572 id=1572 data-nosnippet>1572</a> <span class="kw">let </span><span class="kw-2">mut </span>frames = <span class="macro">vec!</span>[
<a href=#1573 id=1573 data-nosnippet>1573</a> frame::Crypto {
<a href=#1574 id=1574 data-nosnippet>1574</a> offset: <span class="number">0</span>,
<a href=#1575 id=1575 data-nosnippet>1575</a> data: Bytes::from_static(<span class="kw-2">&amp;</span>data[..<span class="number">5</span>]),
<a href=#1576 id=1576 data-nosnippet>1576</a> },
<a href=#1577 id=1577 data-nosnippet>1577</a> frame::Crypto {
<a href=#1578 id=1578 data-nosnippet>1578</a> offset: <span class="number">5</span>,
<a href=#1579 id=1579 data-nosnippet>1579</a> data: Bytes::from_static(<span class="kw-2">&amp;</span>data[<span class="number">5</span>..]),
<a href=#1580 id=1580 data-nosnippet>1580</a> },
<a href=#1581 id=1581 data-nosnippet>1581</a> ];
<a href=#1582 id=1582 data-nosnippet>1582</a> <span class="macro">assert_eq!</span>(<span class="kw-2">&amp;</span>assemble_crypto_frames(<span class="kw-2">&amp;mut </span>frames).unwrap()[..], <span class="kw-2">&amp;</span>data[..]);
<a href=#1583 id=1583 data-nosnippet>1583</a> }
<a href=#1584 id=1584 data-nosnippet>1584</a>
<a href=#1585 id=1585 data-nosnippet>1585</a> <span class="attr">#[test]
<a href=#1586 id=1586 data-nosnippet>1586</a> </span><span class="kw">fn </span>assemble_out_of_order() {
<a href=#1587 id=1587 data-nosnippet>1587</a> <span class="kw">let </span>data = <span class="string">b"hello world"</span>;
<a href=#1588 id=1588 data-nosnippet>1588</a> <span class="kw">let </span><span class="kw-2">mut </span>frames = <span class="macro">vec!</span>[
<a href=#1589 id=1589 data-nosnippet>1589</a> frame::Crypto {
<a href=#1590 id=1590 data-nosnippet>1590</a> offset: <span class="number">5</span>,
<a href=#1591 id=1591 data-nosnippet>1591</a> data: Bytes::from_static(<span class="kw-2">&amp;</span>data[<span class="number">5</span>..]),
<a href=#1592 id=1592 data-nosnippet>1592</a> },
<a href=#1593 id=1593 data-nosnippet>1593</a> frame::Crypto {
<a href=#1594 id=1594 data-nosnippet>1594</a> offset: <span class="number">0</span>,
<a href=#1595 id=1595 data-nosnippet>1595</a> data: Bytes::from_static(<span class="kw-2">&amp;</span>data[..<span class="number">5</span>]),
<a href=#1596 id=1596 data-nosnippet>1596</a> },
<a href=#1597 id=1597 data-nosnippet>1597</a> ];
<a href=#1598 id=1598 data-nosnippet>1598</a> <span class="macro">assert_eq!</span>(<span class="kw-2">&amp;</span>assemble_crypto_frames(<span class="kw-2">&amp;mut </span>frames).unwrap()[..], <span class="kw-2">&amp;</span>data[..]);
<a href=#1599 id=1599 data-nosnippet>1599</a> }
<a href=#1600 id=1600 data-nosnippet>1600</a>
<a href=#1601 id=1601 data-nosnippet>1601</a> <span class="attr">#[test]
<a href=#1602 id=1602 data-nosnippet>1602</a> </span><span class="kw">fn </span>assemble_with_overlap() {
<a href=#1603 id=1603 data-nosnippet>1603</a> <span class="kw">let </span>data = <span class="string">b"hello world"</span>;
<a href=#1604 id=1604 data-nosnippet>1604</a> <span class="kw">let </span><span class="kw-2">mut </span>frames = <span class="macro">vec!</span>[
<a href=#1605 id=1605 data-nosnippet>1605</a> frame::Crypto {
<a href=#1606 id=1606 data-nosnippet>1606</a> offset: <span class="number">0</span>,
<a href=#1607 id=1607 data-nosnippet>1607</a> data: Bytes::from_static(<span class="kw-2">&amp;</span>data[..<span class="number">7</span>]),
<a href=#1608 id=1608 data-nosnippet>1608</a> },
<a href=#1609 id=1609 data-nosnippet>1609</a> frame::Crypto {
<a href=#1610 id=1610 data-nosnippet>1610</a> offset: <span class="number">5</span>,
<a href=#1611 id=1611 data-nosnippet>1611</a> data: Bytes::from_static(<span class="kw-2">&amp;</span>data[<span class="number">5</span>..]),
<a href=#1612 id=1612 data-nosnippet>1612</a> },
<a href=#1613 id=1613 data-nosnippet>1613</a> ];
<a href=#1614 id=1614 data-nosnippet>1614</a> <span class="macro">assert_eq!</span>(<span class="kw-2">&amp;</span>assemble_crypto_frames(<span class="kw-2">&amp;mut </span>frames).unwrap()[..], <span class="kw-2">&amp;</span>data[..]);
<a href=#1615 id=1615 data-nosnippet>1615</a> }
<a href=#1616 id=1616 data-nosnippet>1616</a>
<a href=#1617 id=1617 data-nosnippet>1617</a> <span class="attr">#[test]
<a href=#1618 id=1618 data-nosnippet>1618</a> </span><span class="kw">fn </span>assemble_with_gap() {
<a href=#1619 id=1619 data-nosnippet>1619</a> <span class="kw">let </span><span class="kw-2">mut </span>frames = <span class="macro">vec!</span>[frame::Crypto {
<a href=#1620 id=1620 data-nosnippet>1620</a> offset: <span class="number">10</span>,
<a href=#1621 id=1621 data-nosnippet>1621</a> data: Bytes::from_static(<span class="string">b"world"</span>),
<a href=#1622 id=1622 data-nosnippet>1622</a> }];
<a href=#1623 id=1623 data-nosnippet>1623</a> <span class="macro">assert!</span>(assemble_crypto_frames(<span class="kw-2">&amp;mut </span>frames).is_none());
<a href=#1624 id=1624 data-nosnippet>1624</a> }
<a href=#1625 id=1625 data-nosnippet>1625</a>}</code></pre></div></section></main></body></html>
<a href=#1459 id=1459 data-nosnippet>1459</a><span class="kw">impl </span>IncomingImproperDropWarner {
<a href=#1460 id=1460 data-nosnippet>1460</a> <span class="kw">fn </span>dismiss(<span class="self">self</span>) {
<a href=#1461 id=1461 data-nosnippet>1461</a> mem::forget(<span class="self">self</span>);
<a href=#1462 id=1462 data-nosnippet>1462</a> }
<a href=#1463 id=1463 data-nosnippet>1463</a>}
<a href=#1464 id=1464 data-nosnippet>1464</a>
<a href=#1465 id=1465 data-nosnippet>1465</a><span class="kw">impl </span>Drop <span class="kw">for </span>IncomingImproperDropWarner {
<a href=#1466 id=1466 data-nosnippet>1466</a> <span class="kw">fn </span>drop(<span class="kw-2">&amp;mut </span><span class="self">self</span>) {
<a href=#1467 id=1467 data-nosnippet>1467</a> <span class="macro">warn!</span>(
<a href=#1468 id=1468 data-nosnippet>1468</a> <span class="string">"quinn_proto::Incoming dropped without passing to Endpoint::accept/refuse/retry/ignore \
<a href=#1469 id=1469 data-nosnippet>1469</a> (may cause memory leak and eventual inability to accept new connections)"
<a href=#1470 id=1470 data-nosnippet>1470</a> </span>);
<a href=#1471 id=1471 data-nosnippet>1471</a> }
<a href=#1472 id=1472 data-nosnippet>1472</a>}
<a href=#1473 id=1473 data-nosnippet>1473</a>
<a href=#1474 id=1474 data-nosnippet>1474</a><span class="doccomment">/// Errors in the parameters being used to create a new connection
<a href=#1475 id=1475 data-nosnippet>1475</a>///
<a href=#1476 id=1476 data-nosnippet>1476</a>/// These arise before any I/O has been performed.
<a href=#1477 id=1477 data-nosnippet>1477</a></span><span class="attr">#[derive(Debug, Error, Clone, PartialEq, Eq)]
<a href=#1478 id=1478 data-nosnippet>1478</a></span><span class="kw">pub enum </span>ConnectError {
<a href=#1479 id=1479 data-nosnippet>1479</a> <span class="doccomment">/// The endpoint can no longer create new connections
<a href=#1480 id=1480 data-nosnippet>1480</a> ///
<a href=#1481 id=1481 data-nosnippet>1481</a> /// Indicates that a necessary component of the endpoint has been dropped or otherwise disabled.
<a href=#1482 id=1482 data-nosnippet>1482</a> </span><span class="attr">#[error(<span class="string">"endpoint stopping"</span>)]
<a href=#1483 id=1483 data-nosnippet>1483</a> </span>EndpointStopping,
<a href=#1484 id=1484 data-nosnippet>1484</a> <span class="doccomment">/// The connection could not be created because not enough of the CID space is available
<a href=#1485 id=1485 data-nosnippet>1485</a> ///
<a href=#1486 id=1486 data-nosnippet>1486</a> /// Try using longer connection IDs
<a href=#1487 id=1487 data-nosnippet>1487</a> </span><span class="attr">#[error(<span class="string">"CIDs exhausted"</span>)]
<a href=#1488 id=1488 data-nosnippet>1488</a> </span>CidsExhausted,
<a href=#1489 id=1489 data-nosnippet>1489</a> <span class="doccomment">/// The given server name was malformed
<a href=#1490 id=1490 data-nosnippet>1490</a> </span><span class="attr">#[error(<span class="string">"invalid server name: {0}"</span>)]
<a href=#1491 id=1491 data-nosnippet>1491</a> </span>InvalidServerName(String),
<a href=#1492 id=1492 data-nosnippet>1492</a> <span class="doccomment">/// The remote [`SocketAddr`] supplied was malformed
<a href=#1493 id=1493 data-nosnippet>1493</a> ///
<a href=#1494 id=1494 data-nosnippet>1494</a> /// Examples include attempting to connect to port 0, or using an inappropriate address family.
<a href=#1495 id=1495 data-nosnippet>1495</a> </span><span class="attr">#[error(<span class="string">"invalid remote address: {0}"</span>)]
<a href=#1496 id=1496 data-nosnippet>1496</a> </span>InvalidRemoteAddress(SocketAddr),
<a href=#1497 id=1497 data-nosnippet>1497</a> <span class="doccomment">/// No default client configuration was set up
<a href=#1498 id=1498 data-nosnippet>1498</a> ///
<a href=#1499 id=1499 data-nosnippet>1499</a> /// Use `Endpoint::connect_with` to specify a client configuration.
<a href=#1500 id=1500 data-nosnippet>1500</a> </span><span class="attr">#[error(<span class="string">"no default client config"</span>)]
<a href=#1501 id=1501 data-nosnippet>1501</a> </span>NoDefaultClientConfig,
<a href=#1502 id=1502 data-nosnippet>1502</a> <span class="doccomment">/// The local endpoint does not support the QUIC version specified in the client configuration
<a href=#1503 id=1503 data-nosnippet>1503</a> </span><span class="attr">#[error(<span class="string">"unsupported QUIC version"</span>)]
<a href=#1504 id=1504 data-nosnippet>1504</a> </span>UnsupportedVersion,
<a href=#1505 id=1505 data-nosnippet>1505</a>}
<a href=#1506 id=1506 data-nosnippet>1506</a>
<a href=#1507 id=1507 data-nosnippet>1507</a><span class="doccomment">/// Error type for attempting to accept an [`Incoming`]
<a href=#1508 id=1508 data-nosnippet>1508</a></span><span class="attr">#[derive(Debug)]
<a href=#1509 id=1509 data-nosnippet>1509</a></span><span class="kw">pub struct </span>AcceptError {
<a href=#1510 id=1510 data-nosnippet>1510</a> <span class="doccomment">/// Underlying error describing reason for failure
<a href=#1511 id=1511 data-nosnippet>1511</a> </span><span class="kw">pub </span>cause: ConnectionError,
<a href=#1512 id=1512 data-nosnippet>1512</a> <span class="doccomment">/// Optional response to transmit back
<a href=#1513 id=1513 data-nosnippet>1513</a> </span><span class="kw">pub </span>response: <span class="prelude-ty">Option</span>&lt;Transmit&gt;,
<a href=#1514 id=1514 data-nosnippet>1514</a>}
<a href=#1515 id=1515 data-nosnippet>1515</a>
<a href=#1516 id=1516 data-nosnippet>1516</a><span class="doccomment">/// Error for attempting to retry an [`Incoming`] which already bears a token from a previous retry
<a href=#1517 id=1517 data-nosnippet>1517</a></span><span class="attr">#[derive(Debug, Error)]
<a href=#1518 id=1518 data-nosnippet>1518</a>#[error(<span class="string">"retry() with validated Incoming"</span>)]
<a href=#1519 id=1519 data-nosnippet>1519</a></span><span class="kw">pub struct </span>RetryError(Box&lt;Incoming&gt;);
<a href=#1520 id=1520 data-nosnippet>1520</a>
<a href=#1521 id=1521 data-nosnippet>1521</a><span class="kw">impl </span>RetryError {
<a href=#1522 id=1522 data-nosnippet>1522</a> <span class="doccomment">/// Get the [`Incoming`]
<a href=#1523 id=1523 data-nosnippet>1523</a> </span><span class="kw">pub fn </span>into_incoming(<span class="self">self</span>) -&gt; Incoming {
<a href=#1524 id=1524 data-nosnippet>1524</a> <span class="kw-2">*</span><span class="self">self</span>.<span class="number">0
<a href=#1525 id=1525 data-nosnippet>1525</a> </span>}
<a href=#1526 id=1526 data-nosnippet>1526</a>}
<a href=#1527 id=1527 data-nosnippet>1527</a>
<a href=#1528 id=1528 data-nosnippet>1528</a><span class="doccomment">/// Reset Tokens which are associated with peer socket addresses
<a href=#1529 id=1529 data-nosnippet>1529</a>///
<a href=#1530 id=1530 data-nosnippet>1530</a>/// The standard `HashMap` is used since both `SocketAddr` and `ResetToken` are
<a href=#1531 id=1531 data-nosnippet>1531</a>/// peer generated and might be usable for hash collision attacks.
<a href=#1532 id=1532 data-nosnippet>1532</a></span><span class="attr">#[derive(Default, Debug)]
<a href=#1533 id=1533 data-nosnippet>1533</a></span><span class="kw">struct </span>ResetTokenTable(HashMap&lt;SocketAddr, HashMap&lt;ResetToken, ConnectionHandle&gt;&gt;);
<a href=#1534 id=1534 data-nosnippet>1534</a>
<a href=#1535 id=1535 data-nosnippet>1535</a><span class="kw">impl </span>ResetTokenTable {
<a href=#1536 id=1536 data-nosnippet>1536</a> <span class="kw">fn </span>insert(<span class="kw-2">&amp;mut </span><span class="self">self</span>, remote: SocketAddr, token: ResetToken, ch: ConnectionHandle) -&gt; bool {
<a href=#1537 id=1537 data-nosnippet>1537</a> <span class="self">self</span>.<span class="number">0
<a href=#1538 id=1538 data-nosnippet>1538</a> </span>.entry(remote)
<a href=#1539 id=1539 data-nosnippet>1539</a> .or_default()
<a href=#1540 id=1540 data-nosnippet>1540</a> .insert(token, ch)
<a href=#1541 id=1541 data-nosnippet>1541</a> .is_some()
<a href=#1542 id=1542 data-nosnippet>1542</a> }
<a href=#1543 id=1543 data-nosnippet>1543</a>
<a href=#1544 id=1544 data-nosnippet>1544</a> <span class="kw">fn </span>remove(<span class="kw-2">&amp;mut </span><span class="self">self</span>, remote: SocketAddr, token: ResetToken) {
<a href=#1545 id=1545 data-nosnippet>1545</a> <span class="kw">use </span>std::collections::hash_map::Entry;
<a href=#1546 id=1546 data-nosnippet>1546</a> <span class="kw">match </span><span class="self">self</span>.<span class="number">0</span>.entry(remote) {
<a href=#1547 id=1547 data-nosnippet>1547</a> Entry::Vacant(<span class="kw">_</span>) =&gt; {}
<a href=#1548 id=1548 data-nosnippet>1548</a> Entry::Occupied(<span class="kw-2">mut </span>e) =&gt; {
<a href=#1549 id=1549 data-nosnippet>1549</a> e.get_mut().remove(<span class="kw-2">&amp;</span>token);
<a href=#1550 id=1550 data-nosnippet>1550</a> <span class="kw">if </span>e.get().is_empty() {
<a href=#1551 id=1551 data-nosnippet>1551</a> e.remove_entry();
<a href=#1552 id=1552 data-nosnippet>1552</a> }
<a href=#1553 id=1553 data-nosnippet>1553</a> }
<a href=#1554 id=1554 data-nosnippet>1554</a> }
<a href=#1555 id=1555 data-nosnippet>1555</a> }
<a href=#1556 id=1556 data-nosnippet>1556</a>
<a href=#1557 id=1557 data-nosnippet>1557</a> <span class="kw">fn </span>get(<span class="kw-2">&amp;</span><span class="self">self</span>, remote: SocketAddr, token: <span class="kw-2">&amp;</span>[u8]) -&gt; <span class="prelude-ty">Option</span>&lt;<span class="kw-2">&amp;</span>ConnectionHandle&gt; {
<a href=#1558 id=1558 data-nosnippet>1558</a> <span class="kw">let </span>token = ResetToken::from(&lt;[u8; RESET_TOKEN_SIZE]&gt;::try_from(token).ok()<span class="question-mark">?</span>);
<a href=#1559 id=1559 data-nosnippet>1559</a> <span class="self">self</span>.<span class="number">0</span>.get(<span class="kw-2">&amp;</span>remote)<span class="question-mark">?</span>.get(<span class="kw-2">&amp;</span>token)
<a href=#1560 id=1560 data-nosnippet>1560</a> }
<a href=#1561 id=1561 data-nosnippet>1561</a>}
<a href=#1562 id=1562 data-nosnippet>1562</a>
<a href=#1563 id=1563 data-nosnippet>1563</a><span class="attr">#[cfg(test)]
<a href=#1564 id=1564 data-nosnippet>1564</a></span><span class="kw">mod </span>tests {
<a href=#1565 id=1565 data-nosnippet>1565</a> <span class="kw">use super</span>::<span class="kw-2">*</span>;
<a href=#1566 id=1566 data-nosnippet>1566</a>
<a href=#1567 id=1567 data-nosnippet>1567</a> <span class="attr">#[test]
<a href=#1568 id=1568 data-nosnippet>1568</a> </span><span class="kw">fn </span>assemble_contiguous() {
<a href=#1569 id=1569 data-nosnippet>1569</a> <span class="kw">let </span>data = <span class="string">b"hello world"</span>;
<a href=#1570 id=1570 data-nosnippet>1570</a> <span class="kw">let </span><span class="kw-2">mut </span>frames = <span class="macro">vec!</span>[
<a href=#1571 id=1571 data-nosnippet>1571</a> frame::Crypto {
<a href=#1572 id=1572 data-nosnippet>1572</a> offset: <span class="number">0</span>,
<a href=#1573 id=1573 data-nosnippet>1573</a> data: Bytes::from_static(<span class="kw-2">&amp;</span>data[..<span class="number">5</span>]),
<a href=#1574 id=1574 data-nosnippet>1574</a> },
<a href=#1575 id=1575 data-nosnippet>1575</a> frame::Crypto {
<a href=#1576 id=1576 data-nosnippet>1576</a> offset: <span class="number">5</span>,
<a href=#1577 id=1577 data-nosnippet>1577</a> data: Bytes::from_static(<span class="kw-2">&amp;</span>data[<span class="number">5</span>..]),
<a href=#1578 id=1578 data-nosnippet>1578</a> },
<a href=#1579 id=1579 data-nosnippet>1579</a> ];
<a href=#1580 id=1580 data-nosnippet>1580</a> <span class="macro">assert_eq!</span>(<span class="kw-2">&amp;</span>assemble_crypto_frames(<span class="kw-2">&amp;mut </span>frames).unwrap()[..], <span class="kw-2">&amp;</span>data[..]);
<a href=#1581 id=1581 data-nosnippet>1581</a> }
<a href=#1582 id=1582 data-nosnippet>1582</a>
<a href=#1583 id=1583 data-nosnippet>1583</a> <span class="attr">#[test]
<a href=#1584 id=1584 data-nosnippet>1584</a> </span><span class="kw">fn </span>assemble_out_of_order() {
<a href=#1585 id=1585 data-nosnippet>1585</a> <span class="kw">let </span>data = <span class="string">b"hello world"</span>;
<a href=#1586 id=1586 data-nosnippet>1586</a> <span class="kw">let </span><span class="kw-2">mut </span>frames = <span class="macro">vec!</span>[
<a href=#1587 id=1587 data-nosnippet>1587</a> frame::Crypto {
<a href=#1588 id=1588 data-nosnippet>1588</a> offset: <span class="number">5</span>,
<a href=#1589 id=1589 data-nosnippet>1589</a> data: Bytes::from_static(<span class="kw-2">&amp;</span>data[<span class="number">5</span>..]),
<a href=#1590 id=1590 data-nosnippet>1590</a> },
<a href=#1591 id=1591 data-nosnippet>1591</a> frame::Crypto {
<a href=#1592 id=1592 data-nosnippet>1592</a> offset: <span class="number">0</span>,
<a href=#1593 id=1593 data-nosnippet>1593</a> data: Bytes::from_static(<span class="kw-2">&amp;</span>data[..<span class="number">5</span>]),
<a href=#1594 id=1594 data-nosnippet>1594</a> },
<a href=#1595 id=1595 data-nosnippet>1595</a> ];
<a href=#1596 id=1596 data-nosnippet>1596</a> <span class="macro">assert_eq!</span>(<span class="kw-2">&amp;</span>assemble_crypto_frames(<span class="kw-2">&amp;mut </span>frames).unwrap()[..], <span class="kw-2">&amp;</span>data[..]);
<a href=#1597 id=1597 data-nosnippet>1597</a> }
<a href=#1598 id=1598 data-nosnippet>1598</a>
<a href=#1599 id=1599 data-nosnippet>1599</a> <span class="attr">#[test]
<a href=#1600 id=1600 data-nosnippet>1600</a> </span><span class="kw">fn </span>assemble_with_overlap() {
<a href=#1601 id=1601 data-nosnippet>1601</a> <span class="kw">let </span>data = <span class="string">b"hello world"</span>;
<a href=#1602 id=1602 data-nosnippet>1602</a> <span class="kw">let </span><span class="kw-2">mut </span>frames = <span class="macro">vec!</span>[
<a href=#1603 id=1603 data-nosnippet>1603</a> frame::Crypto {
<a href=#1604 id=1604 data-nosnippet>1604</a> offset: <span class="number">0</span>,
<a href=#1605 id=1605 data-nosnippet>1605</a> data: Bytes::from_static(<span class="kw-2">&amp;</span>data[..<span class="number">7</span>]),
<a href=#1606 id=1606 data-nosnippet>1606</a> },
<a href=#1607 id=1607 data-nosnippet>1607</a> frame::Crypto {
<a href=#1608 id=1608 data-nosnippet>1608</a> offset: <span class="number">5</span>,
<a href=#1609 id=1609 data-nosnippet>1609</a> data: Bytes::from_static(<span class="kw-2">&amp;</span>data[<span class="number">5</span>..]),
<a href=#1610 id=1610 data-nosnippet>1610</a> },
<a href=#1611 id=1611 data-nosnippet>1611</a> ];
<a href=#1612 id=1612 data-nosnippet>1612</a> <span class="macro">assert_eq!</span>(<span class="kw-2">&amp;</span>assemble_crypto_frames(<span class="kw-2">&amp;mut </span>frames).unwrap()[..], <span class="kw-2">&amp;</span>data[..]);
<a href=#1613 id=1613 data-nosnippet>1613</a> }
<a href=#1614 id=1614 data-nosnippet>1614</a>
<a href=#1615 id=1615 data-nosnippet>1615</a> <span class="attr">#[test]
<a href=#1616 id=1616 data-nosnippet>1616</a> </span><span class="kw">fn </span>assemble_with_gap() {
<a href=#1617 id=1617 data-nosnippet>1617</a> <span class="kw">let </span><span class="kw-2">mut </span>frames = <span class="macro">vec!</span>[frame::Crypto {
<a href=#1618 id=1618 data-nosnippet>1618</a> offset: <span class="number">10</span>,
<a href=#1619 id=1619 data-nosnippet>1619</a> data: Bytes::from_static(<span class="string">b"world"</span>),
<a href=#1620 id=1620 data-nosnippet>1620</a> }];
<a href=#1621 id=1621 data-nosnippet>1621</a> <span class="macro">assert!</span>(assemble_crypto_frames(<span class="kw-2">&amp;mut </span>frames).is_none());
<a href=#1622 id=1622 data-nosnippet>1622</a> }
<a href=#1623 id=1623 data-nosnippet>1623</a>}</code></pre></div></section></main></body></html>