iroh::endpoint

Struct Endpoint

Source
pub struct Endpoint { /* private fields */ }
Expand description

Controls an iroh node, establishing connections with other nodes.

This is the main API interface to create connections to, and accept connections from other iroh nodes. The connections are peer-to-peer and encrypted, a Relay server is used to make the connections reliable. See the [crate docs] for a more detailed overview of iroh.

It is recommended to only create a single instance per application. This ensures all the connections made share the same peer-to-peer connections to other iroh nodes, while still remaining independent connections. This will result in more optimal network behaviour.

The endpoint is created using the Builder, which can be created using Endpoint::builder.

Once an endpoint exists, new connections are typically created using the Endpoint::connect and Endpoint::accept methods. Once established, the Connection gives access to most QUIC features. Individual streams to send data to the peer are created using the Connection::open_bi, Connection::accept_bi, Connection::open_uni and Connection::open_bi functions.

Note that due to the light-weight properties of streams a stream will only be accepted once the initiating peer has sent some data on it.

Implementations§

Source§

impl Endpoint

Source

pub fn builder() -> Builder

Returns the builder for an Endpoint, with a production configuration.

Source

pub fn set_alpns(&self, alpns: Vec<Vec<u8>>) -> Result<()>

Sets the list of accepted ALPN protocols.

This will only affect new incoming connections. Note that this overrides the current list of ALPNs.

Source

pub async fn connect( &self, node_addr: impl Into<NodeAddr>, alpn: &[u8], ) -> Result<Connection>

Connects to a remote Endpoint.

A value that can be converted into a NodeAddr is required. This can be either a NodeAddr, a NodeId or a iroh_base::ticket::NodeTicket.

The NodeAddr must contain the NodeId to dial and may also contain a RelayUrl and direct addresses. If direct addresses are provided, they will be used to try and establish a direct connection without involving a relay server.

If neither a RelayUrl or direct addresses are configured in the NodeAddr it may still be possible a connection can be established. This depends on other calls to Endpoint::add_node_addr which may provide contact information, or via the Discovery service configured using Builder::discovery. The discovery service will also be used if the remote node is not reachable on the provided direct addresses and there is no RelayUrl.

If addresses or relay servers are neither provided nor can be discovered, the connection attempt will fail with an error.

The alpn, or application-level protocol identifier, is also required. The remote endpoint must support this alpn, otherwise the connection attempt will fail with an error.

Source

pub async fn connect_with_opts( &self, node_addr: impl Into<NodeAddr>, alpn: &[u8], options: ConnectOptions, ) -> Result<Connecting>

Starts a connection attempt with a remote Endpoint.

Like Endpoint::connect (see also its docs for general details), but allows for a more advanced connection setup with more customization in two aspects:

  1. The returned future resolves to a Connecting, which can be further processed into a Connection by awaiting, or alternatively allows connecting with 0RTT via Connecting::into_0rtt. Note: Please read the documentation for into_0rtt carefully to assess security concerns.
  2. The TransportConfig for the connection can be modified via the provided ConnectOptions. Note: Please be aware that changing transport config settings may have adverse effects on establishing and maintaining direct connections. Carefully test settings you use and consider this currently as still rather experimental.
Source

pub fn accept(&self) -> Accept<'_>

Accepts an incoming connection on the endpoint.

Only connections with the ALPNs configured in Builder::alpns will be accepted. If multiple ALPNs have been configured the ALPN can be inspected before accepting the connection using Connecting::alpn.

The returned future will yield None if the endpoint is closed by calling Endpoint::close.

Source

pub fn add_node_addr(&self, node_addr: NodeAddr) -> Result<()>

Informs this Endpoint about addresses of the iroh node.

This updates the local state for the remote node. If the provided NodeAddr contains a RelayUrl this will be used as the new relay server for this node. If it contains any new IP endpoints they will also be stored and tried when next connecting to this node. Any address that matches this node’s direct addresses will be silently ignored.

See also Endpoint::add_node_addr_with_source.

§Using node discovery instead

It is strongly advised to use node discovery using the StaticProvider instead. This provides more flexibility and future proofing.

§Errors

Will return an error if we attempt to add our own NodeId to the node map or if the direct addresses are a subset of ours.

Source

pub fn add_node_addr_with_source( &self, node_addr: NodeAddr, source: &'static str, ) -> Result<()>

Informs this Endpoint about addresses of the iroh node, noting the source.

This updates the local state for the remote node. If the provided NodeAddr contains a RelayUrl this will be used as the new relay server for this node. If it contains any new IP endpoints they will also be stored and tried when next connecting to this node. Any address that matches this node’s direct addresses will be silently ignored. The source is used for logging exclusively and will not be stored.

§Using node discovery instead

It is strongly advised to use node discovery using the StaticProvider instead. This provides more flexibility and future proofing.

§Errors

Will return an error if we attempt to add our own NodeId to the node map or if the direct addresses are a subset of ours.

Source

pub fn secret_key(&self) -> &SecretKey

Returns the secret_key of this endpoint.

Source

pub fn node_id(&self) -> NodeId

Returns the node id of this endpoint.

This ID is the unique addressing information of this node and other peers must know it to be able to connect to this node.

Source

pub async fn node_addr(&self) -> Result<NodeAddr>

Returns the current NodeAddr for this endpoint.

The returned NodeAddr will have the current RelayUrl and direct addresses as they would be returned by Endpoint::home_relay and Endpoint::direct_addresses.

In browsers, because direct addresses are unavailable, this will only wait for the home relay to be available before returning.

Source

pub fn home_relay(&self) -> Watcher<Option<RelayUrl>>

Returns a Watcher for the RelayUrl of the Relay server used as home relay.

Every endpoint has a home Relay server which it chooses as the server with the lowest latency out of the configured servers provided by Builder::relay_mode. This is the server other iroh nodes can use to reliably establish a connection to this node.

The watcher stores None if we are not connected to any Relay server.

Note that this will store None right after the Endpoint is created since it takes some time to connect to find and connect to the home relay server.

§Examples

To wait for a home relay connection to be established, use Watcher::initialized:

use futures_lite::StreamExt;
use iroh::Endpoint;

let mep = Endpoint::builder().bind().await.unwrap();
let _relay_url = mep.home_relay().initialized().await.unwrap();
Source

pub fn direct_addresses(&self) -> Watcher<Option<BTreeSet<DirectAddr>>>

Returns a Watcher for the direct addresses of this Endpoint.

The direct addresses of the Endpoint are those that could be used by other iroh nodes to establish direct connectivity, depending on the network situation. The yielded lists of direct addresses contain both the locally-bound addresses and the Endpoint’s publicly reachable addresses discovered through mechanisms such as STUN and port mapping. Hence usually only a subset of these will be applicable to a certain remote iroh node.

The Endpoint continuously monitors the direct addresses for changes as its own location in the network might change. Whenever changes are detected this stream will yield a new list of direct addresses.

When issuing the first call to this method the first direct address discovery might still be underway, in this case the Watcher might not be initialized with Some value yet. Once the first set of local direct addresses are discovered the Watcher will always return Some set of direct addresses immediately, which are the most recently discovered direct addresses.

§Examples

To get the first set of direct addresses use Watcher::initialized:

use futures_lite::StreamExt;
use iroh::Endpoint;

let mep = Endpoint::builder().bind().await.unwrap();
let _addrs = mep.direct_addresses().initialized().await.unwrap();
Source

pub fn bound_sockets(&self) -> (SocketAddr, Option<SocketAddr>)

Available on non-wasm_browser only.

Returns the local socket addresses on which the underlying sockets are bound.

The Endpoint always binds on an IPv4 address and also tries to bind on an IPv6 address if available.

Source

pub fn remote_info(&self, node_id: NodeId) -> Option<RemoteInfo>

Returns information about the remote node identified by a NodeId.

The Endpoint keeps some information about remote iroh nodes, which it uses to find the best path to a node. Having information on a remote node, however, does not mean we have ever connected to it to or even whether a connection is even possible. The information about a remote node will change over time, as the Endpoint learns more about the node. Future calls may return different information. Furthermore, node information may even be completely evicted as it becomes stale.

See also Endpoint::remote_info_iter which returns information on all nodes known by this Endpoint.

Source

pub fn remote_info_iter(&self) -> impl Iterator<Item = RemoteInfo>

Returns information about all the remote nodes this Endpoint knows about.

This returns the same information as Endpoint::remote_info for each node known to this Endpoint.

The Endpoint keeps some information about remote iroh nodes, which it uses to find the best path to a node. This returns all the nodes it knows about, regardless of whether a connection was ever made or is even possible.

See also Endpoint::remote_info to only retrieve information about a single node.

Source

pub fn discovery_stream( &self, ) -> impl Stream<Item = Result<DiscoveryItem, Lagged>>

Returns a stream of all remote nodes discovered through the endpoint’s discovery services.

Whenever a node is discovered via the endpoint’s discovery service, the corresponding DiscoveryItem is yielded from this stream. This includes nodes discovered actively through Discovery::resolve, which is invoked automatically when calling Endpoint::connect for a NodeId unknown to the endpoint. It also includes nodes that the endpoint discovers passively from discovery services that implement Discovery::subscribe, which e.g. MdnsDiscovery does.

The stream does not yield information about nodes that are added manually to the endpoint’s addressbook by calling Endpoint::add_node_addr or by supplying a full NodeAddr to Endpoint::connect. It also does not yield information about nodes that we only know about because they connected to us. When using the StaticProvider discovery, discovery info is only emitted once connecting to a node added to the static provider, not at the time of adding it to the static provider.

The stream should be processed in a loop. If the stream is not processed fast enough, Lagged may be yielded, indicating that items were missed.

See also Endpoint::remote_info_iter, which returns an iterator over all remotes the endpoint knows about at a specific point in time.

Source

pub fn conn_type(&self, node_id: NodeId) -> Result<Watcher<ConnectionType>>

Returns a Watcher that reports the current connection type and any changes for given remote node.

This watcher allows observing a stream of ConnectionType items by calling Watcher::stream(). If the underlying connection to a remote node changes, it will yield a new item. These connection changes are when the connection switches between using the Relay server and a direct connection.

Note that this does not guarantee each connection change is yielded in the stream. If the connection type changes several times before this stream is polled, only the last recorded state is returned. This can be observed e.g. right at the start of a connection when the switch from a relayed to a direct connection can be so fast that the relayed state is never exposed.

If there is currently a connection with the remote node, then using Watcher::get will immediately return either ConnectionType::Relay, ConnectionType::Direct or ConnectionType::Mixed.

It is possible for the connection type to be ConnectionType::None if you’ve recently connected to this node id but previous methods of reaching the node have become inaccessible.

§Errors

Will error if we do not have any address information for the given node_id.

Source

pub fn dns_resolver(&self) -> &DnsResolver

Available on non-wasm_browser only.

Returns the DNS resolver used in this Endpoint.

See Builder::dns_resolver.

Source

pub fn discovery(&self) -> Option<&dyn Discovery>

Returns the discovery mechanism, if configured.

See Builder::discovery.

Source

pub async fn network_change(&self)

Notifies the system of potential network changes.

On many systems iroh is able to detect network changes by itself, however some systems like android do not expose this functionality to native code. Android does however provide this functionality to Java code. This function allows for notifying iroh of any potential network changes like this.

Even when the network did not change, or iroh was already able to detect the network change itself, there is no harm in calling this function.

Source

pub fn set_user_data_for_discovery(&self, user_data: Option<UserData>)

Sets the initial user-defined data to be published in discovery services for this node.

If the user-defined data passed to this function is different to the previous one, the endpoint will republish its node info to the configured discovery services.

See also Builder::user_data_for_discovery for setting an initial value when building the endpoint.

Source

pub async fn close(&self)

Closes the QUIC endpoint and the magic socket.

This will close any remaining open Connections with an error code of 0 and an empty reason. Though it is best practice to close those explicitly before with a custom error code and reason.

It will then make a best effort to wait for all close notifications to be acknowledged by the peers, re-transmitting them if needed. This ensures the peers are aware of the closed connections instead of having to wait for a timeout on the connection. Once all connections are closed or timed out, the future finishes.

The maximum time-out that this future will wait for depends on QUIC transport configurations of non-drained connections at the time of calling, and their current estimates of round trip time. With default parameters and a conservative estimate of round trip time, this call’s future should take 3 seconds to resolve in cases of bad connectivity or failed connections. In the usual case, this call’s future should return much more quickly.

It is highly recommended you do wait for this close call to finish, if possible. Not doing so will make connections that were still open while closing the endpoint time out on the remote end. Thus remote ends will assume connections to have failed even if all application data was transmitted successfully.

Note: Someone used to closing TCP sockets might wonder why it is necessary to wait for timeouts when closing QUIC endpoints, while they don’t have to do this for TCP sockets. This is due to QUIC and its acknowledgments being implemented in user-land, while TCP sockets usually get closed and drained by the operating system in the kernel during the “Time-Wait” period of the TCP socket.

Be aware however that the underlying UDP sockets are only closed once all clones of the the respective Endpoint are dropped.

Source

pub fn is_closed(&self) -> bool

Check if this endpoint is still alive, or already closed.

Trait Implementations§

Source§

impl Clone for Endpoint

Source§

fn clone(&self) -> Endpoint

Returns a copy of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for Endpoint

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
§

impl<'a, T, E> AsTaggedExplicit<'a, E> for T
where T: 'a,

§

fn explicit(self, class: Class, tag: u32) -> TaggedParser<'a, Explicit, Self, E>

§

impl<'a, T, E> AsTaggedImplicit<'a, E> for T
where T: 'a,

§

fn implicit( self, class: Class, constructed: bool, tag: u32, ) -> TaggedParser<'a, Implicit, Self, E>

Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dst: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dst. Read more
Source§

impl<T> DynClone for T
where T: Clone,

Source§

fn __clone_box(&self, _: Private) -> *mut ()

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

§

impl<T> FromRef<T> for T
where T: Clone,

§

fn from_ref(input: &T) -> T

Converts to this type from a reference to the input type.
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

§

impl<T> Pointable for T

§

const ALIGN: usize = _

The alignment of pointer.
§

type Init = T

The type for initializers.
§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a [WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a [WithDispatch] wrapper. Read more
§

impl<T> ErasedDestructor for T
where T: 'static,

§

impl<T> MaybeSendSync for T