Expand description
§librice
An async implementation based on rice-proto using the rice-c bindings.
§Relevant standards
- RFC5245: Interactive Connectivity Establishment (ICE): A Protocol for Network Address Translator (NAT) Traversal for Offer/Answer Protocols
- RFC5389: Session Traversal Utilities for NAT (STUN)
- RFC5766: Traversal Using Relays around NAT (TURN): Relay Extensions to Session Traversal Utilities for NAT (STUN)
- RFC5769: Test Vectors for Session Traversal Utilities for NAT (STUN)
- RFC6062: Traversal Using Relays around NAT (TURN) Extensions for TCP Allocations
- RFC6156: Traversal Using Relays around NAT (TURN) Extension for IPv6
- RFC6544: TCP Candidates with Interactive Connectivity Establishment (ICE)
- RFC7675: Session Traversal Utilities for NAT (STUN) Usage for Consent Freshness
- RFC8445: Interactive Connectivity Establishment (ICE): A Protocol for Network Address Translator (NAT) Traversal
- RFC8489: Session Traversal Utilities for NAT (STUN)
- RFC8656: Traversal Using Relays around NAT (TURN): Relay Extensions to Session Traversal Utilities for NAT (STUN)
- RFC8838: Trickle ICE: Incremental Provisioning of Candidates for the Interactive Connectivity Establishment (ICE) Protocol
§Building
librice has the same build requirements as rice-c and the crate level documentation for
rice-c provides guidelines on how to build rice-c and projects that depend on rice-c.
§Example
use core::net::SocketAddr;
use futures::stream::StreamExt;
use librice::agent::{Agent, AgentMessage};
use librice::stream::Credentials;
use librice::candidate::{Candidate, CandidateType, TransportType};
let agent = Agent::default();
// Configure the agent as you wish.
// e.g. add a stun server.
// agent.add_stun_server(TransportType::Udp, SocketAddr::new([192, 168, 0, 1], 3478));
// Add a stream and component within that stream for data flow.
let stream = agent.add_stream();
let local_credentials = Credentials::new("luser", "lpass");
stream.set_local_credentials(&local_credentials);
let component = stream.add_component().unwrap();
// At some point you will also need the remote credentials to be able to successfully connect
// with the peer. If trickle-ice, then this can occur during candidate gathering, otherwise,
// should occur before the remote candidates are added to the agent.
let remote_credentials = Credentials::new("ruser", "rpass");
stream.set_local_credentials(&remote_credentials);
// Retrieve the receive end of a message queue that indicates gathering state, component state,
// and other such messages.
let mut messages = agent.messages();
// start gathering candidates.
stream.gather_candidates().await.unwrap();
while let Some(msg) = messages.next().await {
match msg {
AgentMessage::GatheredCandidate(stream, gathered) => {
// based on local policy, you can choose to never add the locally gathered
// candidate to the stream to avoid using a candidate for connectivity checks later.
stream.add_local_gathered_candidate(gathered);
// For trickle-ice handling, you would send the gathered candidate to the peer.
}
AgentMessage::GatheringComplete(component) => {
// For non trickle-ice handling, if all relevant components in a stream have
// completed gathering, you would retrieve the list of local candidates
// and send that to the peer along with any other setup information required.
println!("component {} has completed gathering", component.id());
let stream = component.stream();
for cand in stream.local_candidates() {
println!(
"stream {} has gathered local candidate {}",
stream.id(),
cand.to_sdp_string()
);
}
break;
}
AgentMessage::ComponentStateChange(component, new_state) => {
println!("component {} has changed state to {new_state:?}", component.id());
},
}
}
// On receiving remote candidates from the peer you would add them to the agent in order to
// start connectivity checks.
stream.add_remote_candidate(&remote_candidate);
// Once the complete set of remote candidates have been received, then notify the agent of
// this.
stream.end_of_remote_candidates();
// connectivity checks will progress and either a successful pair (the selected pair) will be
// found, or failure will be signaled for the component's connection state.
// while let Some(msg) = messages.next().await {
// match msg {
// ...
// }
// }
// once a selected pair is chosen, data can be received.
let recv = component.recv();
// and sent
component.send([1, 2, 3, 4].as_slice()).await;Modules§
- agent
- ICE Agent implementation as specified in RFC 8445
- candidate
- ICE Candidates
- component
- A
Componentin an ICEStream - runtime
- Async runtime abstraction
- socket
- Socket helpers for handling UDP and TCP transports
- stream
- An ICE Stream
Structs§
- Address
- A network address.
Enums§
- Address
Family - The family of an address.
- Feature
- A feature.
- Integrity
Algorithm - The supported authentication mechanisms.
Functions§
- random_
string - Generate a random sequence of characters suitable for username fragments and passwords.