@@ -1257,16 +1257,24 @@ impl Connecting {
1257
1257
}
1258
1258
1259
1259
/// Extracts the ALPN protocol from the peer's handshake data.
1260
- // Note, we could totally provide this method to be on a Connection as well. But we'd
1261
- // need to wrap Connection too.
1262
- pub async fn alpn ( & mut self ) -> Result < Vec < u8 > > {
1260
+ pub async fn alpn ( & mut self ) -> Result < Vec < u8 > , ConnectionError > {
1263
1261
let data = self . handshake_data ( ) . await ?;
1264
- match data. downcast :: < quinn:: crypto:: rustls:: HandshakeData > ( ) {
1265
- Ok ( data) => match data. protocol {
1266
- Some ( protocol) => Ok ( protocol) ,
1267
- None => bail ! ( "no ALPN protocol available" ) ,
1268
- } ,
1269
- Err ( _) => bail ! ( "unknown handshake type" ) ,
1262
+ let data = data
1263
+ . downcast :: < quinn:: crypto:: rustls:: HandshakeData > ( )
1264
+ . expect ( "fixed crypto setup for iroh" ) ;
1265
+ match data. protocol {
1266
+ Some ( proto) => Ok ( proto) ,
1267
+ None => {
1268
+ // Using QUIC's CONNECTION_REFUSED error on the server-side is a bit odd,
1269
+ // but perhaps not a total crime. Strictly speaking for QUIC this is an
1270
+ // application error, but if we surfaced this as an application error it
1271
+ // would be even more confusing for the user.
1272
+ Err ( ConnectionError :: TransportError ( TransportError {
1273
+ code : TransportErrorCode :: CONNECTION_REFUSED ,
1274
+ frame : None ,
1275
+ reason : String :: from ( "iroh connections must use an ALPN" ) ,
1276
+ } ) )
1277
+ }
1270
1278
}
1271
1279
}
1272
1280
}
@@ -1281,6 +1289,27 @@ impl Future for Connecting {
1281
1289
Poll :: Ready ( Err ( err) ) => Poll :: Ready ( Err ( err) ) ,
1282
1290
Poll :: Ready ( Ok ( inner) ) => {
1283
1291
let conn = Connection { inner } ;
1292
+
1293
+ // An iroh connection MUST always have an ALPN. Note that this check is
1294
+ // only valid for accepting connections, but we **currently** do not use
1295
+ // this `Connecting` struct when establishing connections. Once we do we'll
1296
+ // have to make this check conditional.
1297
+ let handshake_data = conn. handshake_data ( ) ;
1298
+ let handshake_data = handshake_data
1299
+ . downcast :: < quinn:: crypto:: rustls:: HandshakeData > ( )
1300
+ . expect ( "fixed crypto setup for iroh" ) ;
1301
+ if handshake_data. protocol . is_none ( ) {
1302
+ // Using QUIC's CONNECTION_REFUSED error on the server-side is a bit odd,
1303
+ // but perhaps not a total crime. Strictly speaking for QUIC this is an
1304
+ // application error, but if we surfaced this as an application error it
1305
+ // would be even more confusing for the user.
1306
+ return Poll :: Ready ( Err ( ConnectionError :: TransportError ( TransportError {
1307
+ code : TransportErrorCode :: CONNECTION_REFUSED ,
1308
+ frame : None ,
1309
+ reason : String :: from ( "iroh connections must use an ALPN" ) ,
1310
+ } ) ) ) ;
1311
+ }
1312
+
1284
1313
try_send_rtt_msg ( & conn, this. ep ) ;
1285
1314
Poll :: Ready ( Ok ( conn) )
1286
1315
}
@@ -1511,17 +1540,20 @@ impl Connection {
1511
1540
///
1512
1541
/// [`Connection::handshake_data()`]: crate::Connecting::handshake_data
1513
1542
#[ inline]
1514
- pub fn handshake_data ( & self ) -> Option < Box < dyn Any > > {
1515
- self . inner . handshake_data ( )
1543
+ pub fn handshake_data ( & self ) -> Box < dyn Any > {
1544
+ self . inner
1545
+ . handshake_data ( )
1546
+ . expect ( "we always have handshake data" )
1516
1547
}
1517
1548
1518
1549
/// Extracts the ALPN protocol from the peer's handshake data.
1519
- pub fn alpn ( & self ) -> Option < Vec < u8 > > {
1520
- let data = self . handshake_data ( ) ?;
1521
- match data. downcast :: < quinn:: crypto:: rustls:: HandshakeData > ( ) {
1522
- Ok ( data) => data. protocol ,
1523
- Err ( _) => None ,
1524
- }
1550
+ pub fn alpn ( & self ) -> Vec < u8 > {
1551
+ let data = self . handshake_data ( ) ;
1552
+ let data = data
1553
+ . downcast :: < quinn:: crypto:: rustls:: HandshakeData > ( )
1554
+ . expect ( "fixed crypto setup for iroh" ) ;
1555
+ data. protocol
1556
+ . expect ( "checked in <Connecting as Future>::poll" )
1525
1557
}
1526
1558
1527
1559
/// Cryptographic identity of the peer.
@@ -1533,8 +1565,10 @@ impl Connection {
1533
1565
/// [`Session`]: quinn_proto::crypto::Session
1534
1566
/// [`downcast`]: Box::downcast
1535
1567
#[ inline]
1536
- pub fn peer_identity ( & self ) -> Option < Box < dyn Any > > {
1537
- self . inner . peer_identity ( )
1568
+ pub fn peer_identity ( & self ) -> Box < dyn Any > {
1569
+ self . inner
1570
+ . peer_identity ( )
1571
+ . expect ( "we always have a peer identity" )
1538
1572
}
1539
1573
1540
1574
/// Returns the [`NodeId`] from the peer's TLS certificate.
@@ -1545,25 +1579,14 @@ impl Connection {
1545
1579
/// connection.
1546
1580
///
1547
1581
/// [`PublicKey`]: iroh_base::PublicKey
1548
- // TODO: Would be nice if this could be infallible.
1549
- pub fn remote_node_id ( & self ) -> Result < NodeId > {
1582
+ pub fn remote_node_id ( & self ) -> NodeId {
1550
1583
let data = self . peer_identity ( ) ;
1551
- match data {
1552
- None => bail ! ( "no peer certificate found" ) ,
1553
- Some ( data) => match data. downcast :: < Vec < rustls:: pki_types:: CertificateDer > > ( ) {
1554
- Ok ( certs) => {
1555
- if certs. len ( ) != 1 {
1556
- bail ! (
1557
- "expected a single peer certificate, but {} found" ,
1558
- certs. len( )
1559
- ) ;
1560
- }
1561
- let cert = tls:: certificate:: parse ( & certs[ 0 ] ) ?;
1562
- Ok ( cert. peer_id ( ) )
1563
- }
1564
- Err ( _) => bail ! ( "invalid peer certificate" ) ,
1565
- } ,
1566
- }
1584
+ let certs = data
1585
+ . downcast :: < Vec < rustls:: pki_types:: CertificateDer > > ( )
1586
+ . expect ( "we always have a cert" ) ;
1587
+ debug_assert_eq ! ( certs. len( ) , 1 ) ;
1588
+ let cert = tls:: certificate:: parse ( & certs[ 0 ] ) . expect ( "valid cert" ) ;
1589
+ cert. peer_id ( )
1567
1590
}
1568
1591
1569
1592
/// A stable identifier for this connection.
@@ -1624,10 +1647,7 @@ impl Connection {
1624
1647
/// function.
1625
1648
fn try_send_rtt_msg ( conn : & Connection , magic_ep : & Endpoint ) {
1626
1649
// If we can't notify the rtt-actor that's not great but not critical.
1627
- let Ok ( node_id) = conn. remote_node_id ( ) else {
1628
- warn ! ( ?conn, "failed to get remote node id" ) ;
1629
- return ;
1630
- } ;
1650
+ let node_id = conn. remote_node_id ( ) ;
1631
1651
let Ok ( conn_type_changes) = magic_ep. conn_type ( node_id) else {
1632
1652
warn ! ( ?conn, "failed to create conn_type stream" ) ;
1633
1653
return ;
@@ -1953,7 +1973,7 @@ mod tests {
1953
1973
info ! ( "[server] round {i}" ) ;
1954
1974
let incoming = ep. accept ( ) . await . unwrap ( ) ;
1955
1975
let conn = incoming. await . unwrap ( ) ;
1956
- let node_id = conn. remote_node_id ( ) . unwrap ( ) ;
1976
+ let node_id = conn. remote_node_id ( ) ;
1957
1977
info ! ( %i, peer = %node_id. fmt_short( ) , "accepted connection" ) ;
1958
1978
let ( mut send, mut recv) = conn. accept_bi ( ) . await . unwrap ( ) ;
1959
1979
let mut buf = vec ! [ 0u8 ; chunk_size] ;
@@ -2066,10 +2086,10 @@ mod tests {
2066
2086
2067
2087
async fn accept_world ( ep : Endpoint , src : NodeId ) {
2068
2088
let incoming = ep. accept ( ) . await . unwrap ( ) ;
2069
- let mut iconn = incoming. accept ( ) . unwrap ( ) ;
2070
- let alpn = iconn. alpn ( ) . await . unwrap ( ) ;
2089
+ let iconn = incoming. accept ( ) . unwrap ( ) ;
2071
2090
let conn = iconn. await . unwrap ( ) ;
2072
- let node_id = conn. remote_node_id ( ) . unwrap ( ) ;
2091
+ let alpn = conn. alpn ( ) ;
2092
+ let node_id = conn. remote_node_id ( ) ;
2073
2093
assert_eq ! ( node_id, src) ;
2074
2094
assert_eq ! ( alpn, TEST_ALPN ) ;
2075
2095
let ( mut send, mut recv) = conn. accept_bi ( ) . await . unwrap ( ) ;
@@ -2159,7 +2179,7 @@ mod tests {
2159
2179
async fn accept ( ep : & Endpoint ) -> NodeId {
2160
2180
let incoming = ep. accept ( ) . await . unwrap ( ) ;
2161
2181
let conn = incoming. await . unwrap ( ) ;
2162
- let node_id = conn. remote_node_id ( ) . unwrap ( ) ;
2182
+ let node_id = conn. remote_node_id ( ) ;
2163
2183
tracing:: info!( node_id=%node_id. fmt_short( ) , "accepted connection" ) ;
2164
2184
node_id
2165
2185
}
0 commit comments