18
18
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
19
19
// DEALINGS IN THE SOFTWARE.
20
20
21
- use crate :: { provider:: Provider , transport:: SocketFamily , ConnectError , Connection , Error } ;
21
+ use crate :: {
22
+ provider:: Provider ,
23
+ transport:: { ProtocolVersion , SocketFamily } ,
24
+ ConnectError , Connection , Error ,
25
+ } ;
22
26
23
27
use bytes:: BytesMut ;
24
28
use futures:: {
@@ -69,6 +73,16 @@ pub struct Config {
69
73
/// of a connection.
70
74
pub max_connection_data : u32 ,
71
75
76
+ /// Support QUIC version draft-29 for dialing and listening.
77
+ ///
78
+ /// Per default only QUIC Version 1 / [`libp2p_core::multiaddr::Protocol::QuicV1`]
79
+ /// is supported.
80
+ ///
81
+ /// If support for draft-29 is enabled servers support draft-29 and version 1 on all
82
+ /// QUIC listening addresses.
83
+ /// As client the version is chosen based on the remote's address.
84
+ pub support_draft_29 : bool ,
85
+
72
86
/// TLS client config for the inner [`quinn_proto::ClientConfig`].
73
87
client_tls_config : Arc < rustls:: ClientConfig > ,
74
88
/// TLS server config for the inner [`quinn_proto::ServerConfig`].
@@ -83,6 +97,7 @@ impl Config {
83
97
Self {
84
98
client_tls_config,
85
99
server_tls_config,
100
+ support_draft_29 : false ,
86
101
handshake_timeout : Duration :: from_secs ( 5 ) ,
87
102
max_idle_timeout : 30 * 1000 ,
88
103
max_concurrent_stream_limit : 256 ,
@@ -113,6 +128,7 @@ impl From<Config> for QuinnConfig {
113
128
keep_alive_interval,
114
129
max_connection_data,
115
130
max_stream_data,
131
+ support_draft_29,
116
132
handshake_timeout : _,
117
133
} = config;
118
134
let mut transport = quinn_proto:: TransportConfig :: default ( ) ;
@@ -138,7 +154,10 @@ impl From<Config> for QuinnConfig {
138
154
let mut client_config = quinn_proto:: ClientConfig :: new ( client_tls_config) ;
139
155
client_config. transport_config ( transport) ;
140
156
141
- let endpoint_config = quinn_proto:: EndpointConfig :: default ( ) ;
157
+ let mut endpoint_config = quinn_proto:: EndpointConfig :: default ( ) ;
158
+ if !support_draft_29 {
159
+ endpoint_config. supported_versions ( vec ! [ 1 ] ) ;
160
+ }
142
161
143
162
QuinnConfig {
144
163
client_config,
@@ -280,6 +299,8 @@ pub enum ToEndpoint {
280
299
Dial {
281
300
/// UDP address to connect to.
282
301
addr : SocketAddr ,
302
+ /// Version to dial the remote on.
303
+ version : ProtocolVersion ,
283
304
/// Channel to return the result of the dialing to.
284
305
result : oneshot:: Sender < Result < Connection , Error > > ,
285
306
} ,
@@ -403,18 +424,25 @@ impl<P: Provider> Driver<P> {
403
424
to_endpoint : ToEndpoint ,
404
425
) -> ControlFlow < ( ) , Option < quinn_proto:: Transmit > > {
405
426
match to_endpoint {
406
- ToEndpoint :: Dial { addr, result } => {
427
+ ToEndpoint :: Dial {
428
+ addr,
429
+ result,
430
+ version,
431
+ } => {
432
+ let mut config = self . client_config . clone ( ) ;
433
+ if version == ProtocolVersion :: Draft29 {
434
+ config. version ( 0xff00_001d ) ;
435
+ }
407
436
// This `"l"` seems necessary because an empty string is an invalid domain
408
437
// name. While we don't use domain names, the underlying rustls library
409
438
// is based upon the assumption that we do.
410
- let ( connection_id, connection) =
411
- match self . endpoint . connect ( self . client_config . clone ( ) , addr, "l" ) {
412
- Ok ( c) => c,
413
- Err ( err) => {
414
- let _ = result. send ( Err ( ConnectError :: from ( err) . into ( ) ) ) ;
415
- return ControlFlow :: Continue ( None ) ;
416
- }
417
- } ;
439
+ let ( connection_id, connection) = match self . endpoint . connect ( config, addr, "l" ) {
440
+ Ok ( c) => c,
441
+ Err ( err) => {
442
+ let _ = result. send ( Err ( ConnectError :: from ( err) . into ( ) ) ) ;
443
+ return ControlFlow :: Continue ( None ) ;
444
+ }
445
+ } ;
418
446
419
447
debug_assert_eq ! ( connection. side( ) , quinn_proto:: Side :: Client ) ;
420
448
let ( tx, rx) = mpsc:: channel ( CHANNEL_CAPACITY ) ;
0 commit comments