libp2p_webrtc_websys/
upgrade.rs

1use std::net::SocketAddr;
2
3use libp2p_identity::{Keypair, PeerId};
4use libp2p_webrtc_utils::{noise, Fingerprint};
5use send_wrapper::SendWrapper;
6
7use super::Error;
8use crate::{connection::RtcPeerConnection, error::AuthenticationError, sdp, Connection};
9
10/// Upgrades an outbound WebRTC connection by creating the data channel
11/// and conducting a Noise handshake
12pub(crate) async fn outbound(
13    sock_addr: SocketAddr,
14    remote_fingerprint: Fingerprint,
15    id_keys: Keypair,
16) -> Result<(PeerId, Connection), Error> {
17    let fut = SendWrapper::new(outbound_inner(sock_addr, remote_fingerprint, id_keys));
18    fut.await
19}
20
21/// Inner outbound function that is wrapped in [SendWrapper]
22async fn outbound_inner(
23    sock_addr: SocketAddr,
24    remote_fingerprint: Fingerprint,
25    id_keys: Keypair,
26) -> Result<(PeerId, Connection), Error> {
27    let rtc_peer_connection = RtcPeerConnection::new(remote_fingerprint.algorithm()).await?;
28
29    // Create stream for Noise handshake
30    // Must create data channel before Offer is created for it to be included in the SDP
31    let (channel, listener) = rtc_peer_connection.new_handshake_stream();
32    drop(listener);
33
34    let ufrag = libp2p_webrtc_utils::sdp::random_ufrag();
35
36    let offer = rtc_peer_connection.create_offer().await?;
37    let munged_offer = sdp::offer(offer, &ufrag);
38    rtc_peer_connection
39        .set_local_description(munged_offer)
40        .await?;
41
42    let answer = sdp::answer(sock_addr, remote_fingerprint, &ufrag);
43    rtc_peer_connection.set_remote_description(answer).await?;
44
45    let local_fingerprint = rtc_peer_connection.local_fingerprint()?;
46
47    tracing::trace!(?local_fingerprint);
48    tracing::trace!(?remote_fingerprint);
49
50    let peer_id = noise::outbound(id_keys, channel, remote_fingerprint, local_fingerprint)
51        .await
52        .map_err(AuthenticationError)?;
53
54    tracing::debug!(peer=%peer_id, "Remote peer identified");
55
56    Ok((peer_id, Connection::new(rtc_peer_connection)))
57}