@@ -18,96 +18,103 @@ use crate::{EndpointId, PublicKey, RelayUrl};
1818/// contact the endpoint.
1919///
2020/// To establish a network connection to an endpoint both the [`EndpointId`] and one or more network
21- /// paths are needed. The network paths can come from various sources:
21+ /// paths are needed. The network paths can come from various sources, current sources can come from
2222///
2323/// - A [discovery] service which can provide routing information for a given [`EndpointId`].
2424///
2525/// - A [`RelayUrl`] of the endpoint's [home relay], this allows establishing the connection via
2626/// the Relay server and is very reliable.
2727///
28- /// - One or more *direct addresses* on which the endpoint might be reachable. Depending on the
28+ /// - One or more *IP based addresses* on which the endpoint might be reachable. Depending on the
2929/// network location of both endpoints it might not be possible to establish a direct
3030/// connection without the help of a [Relay server].
3131///
3232/// This structure will always contain the required [`EndpointId`] and will contain an optional
33- /// number of network-level addressing information. It is a generic addressing type used
34- /// whenever a connection to other endpoints needs to be established.
33+ /// number of other addressing information. It is a generic addressing type used whenever a connection
34+ /// to other endpoints needs to be established.
3535///
3636/// [discovery]: https://docs.rs/iroh/*/iroh/index.html#endpoint-discovery
3737/// [home relay]: https://docs.rs/iroh/*/iroh/relay/index.html
3838/// [Relay server]: https://docs.rs/iroh/*/iroh/index.html#relay-servers
3939#[ derive( Debug , Clone , Serialize , Deserialize , PartialEq , Eq , PartialOrd , Ord , Hash ) ]
4040pub struct EndpointAddr {
4141 /// The endpoint's identifier.
42- pub endpoint_id : EndpointId ,
43- /// The endpoint's home relay url.
44- pub relay_url : Option < RelayUrl > ,
45- /// Socket addresses where the peer might be reached directly.
46- pub direct_addresses : BTreeSet < SocketAddr > ,
42+ pub id : EndpointId ,
43+ /// The endpoint's addresses
44+ pub addrs : BTreeSet < TransportAddr > ,
45+ }
46+
47+ /// Available address types.
48+ #[ derive( Debug , Clone , Serialize , Deserialize , PartialEq , Eq , PartialOrd , Ord , Hash ) ]
49+ #[ non_exhaustive]
50+ pub enum TransportAddr {
51+ /// Relays
52+ Relay ( RelayUrl ) ,
53+ /// IP based addresses
54+ Ip ( SocketAddr ) ,
4755}
4856
4957impl EndpointAddr {
50- /// Creates a new [`EndpointAddr`] with no `relay_url` and no `direct_addresses`.
51- pub fn new ( endpoint_id : PublicKey ) -> Self {
58+ /// Creates a new [`EndpointAddr`] with no network level addresses.
59+ ///
60+ /// This still is usable with e.g. a discovery service to establish a connection,
61+ /// depending on the situation.
62+ pub fn new ( id : PublicKey ) -> Self {
5263 EndpointAddr {
53- endpoint_id,
54- relay_url : None ,
55- direct_addresses : Default :: default ( ) ,
64+ id,
65+ addrs : Default :: default ( ) ,
5666 }
5767 }
5868
59- /// Adds a relay url.
69+ /// Creates a new [`EndpointAddr`] from its parts.
70+ pub fn from_parts ( id : PublicKey , addrs : impl IntoIterator < Item = TransportAddr > ) -> Self {
71+ Self {
72+ id,
73+ addrs : addrs. into_iter ( ) . collect ( ) ,
74+ }
75+ }
76+
77+ /// Adds a [`RelayUrl`] address.
6078 pub fn with_relay_url ( mut self , relay_url : RelayUrl ) -> Self {
61- self . relay_url = Some ( relay_url) ;
79+ self . addrs . insert ( TransportAddr :: Relay ( relay_url) ) ;
6280 self
6381 }
6482
65- /// Adds the given direct addresses.
66- pub fn with_direct_addresses (
67- mut self ,
68- addresses : impl IntoIterator < Item = SocketAddr > ,
69- ) -> Self {
70- self . direct_addresses = addresses. into_iter ( ) . collect ( ) ;
83+ /// Adds an IP based address.
84+ pub fn with_ip_addr ( mut self , addr : SocketAddr ) -> Self {
85+ self . addrs . insert ( TransportAddr :: Ip ( addr) ) ;
7186 self
7287 }
7388
74- /// Creates a new [`EndpointAddr`] from its parts.
75- pub fn from_parts (
76- endpoint_id : PublicKey ,
77- relay_url : Option < RelayUrl > ,
78- direct_addresses : impl IntoIterator < Item = SocketAddr > ,
79- ) -> Self {
80- Self {
81- endpoint_id,
82- relay_url,
83- direct_addresses : direct_addresses. into_iter ( ) . collect ( ) ,
89+ /// Adds a list of addresses.
90+ pub fn with_addrs ( mut self , addrs : impl IntoIterator < Item = TransportAddr > ) -> Self {
91+ for addr in addrs. into_iter ( ) {
92+ self . addrs . insert ( addr) ;
8493 }
94+ self
8595 }
8696
8797 /// Returns true, if only a [`EndpointId`] is present.
8898 pub fn is_empty ( & self ) -> bool {
89- self . relay_url . is_none ( ) && self . direct_addresses . is_empty ( )
90- }
91-
92- /// Returns the direct addresses of this peer.
93- pub fn direct_addresses ( & self ) -> impl Iterator < Item = & SocketAddr > {
94- self . direct_addresses . iter ( )
99+ self . addrs . is_empty ( )
95100 }
96101
97- /// Returns the relay url of this peer.
98- pub fn relay_url ( & self ) -> Option < & RelayUrl > {
99- self . relay_url . as_ref ( )
102+ /// Returns a list of IP addresses of this peer.
103+ pub fn ip_addrs ( & self ) -> impl Iterator < Item = & SocketAddr > {
104+ self . addrs . iter ( ) . filter_map ( |addr| match addr {
105+ TransportAddr :: Ip ( addr) => Some ( addr) ,
106+ _ => None ,
107+ } )
100108 }
101- }
102109
103- impl From < ( PublicKey , Option < RelayUrl > , & [ SocketAddr ] ) > for EndpointAddr {
104- fn from ( value : ( PublicKey , Option < RelayUrl > , & [ SocketAddr ] ) ) -> Self {
105- let ( endpoint_id , relay_url , direct_addresses_iter ) = value ;
106- EndpointAddr {
107- endpoint_id ,
108- relay_url ,
109- direct_addresses : direct_addresses_iter . iter ( ) . copied ( ) . collect ( ) ,
110- }
110+ /// Returns a list of relay urls of this peer.
111+ ///
112+ /// In practice this is expected to be zero or one home relay for all known cases currently.
113+ pub fn relay_urls ( & self ) -> impl Iterator < Item = & RelayUrl > {
114+ self . addrs . iter ( ) . filter_map ( |addr| match addr {
115+ TransportAddr :: Relay ( url ) => Some ( url ) ,
116+ _ => None ,
117+ } )
111118 }
112119}
113120
@@ -116,3 +123,51 @@ impl From<EndpointId> for EndpointAddr {
116123 EndpointAddr :: new ( endpoint_id)
117124 }
118125}
126+
127+ #[ cfg( test) ]
128+ mod tests {
129+ use super :: * ;
130+
131+ #[ derive( Debug , Clone , Serialize , Deserialize , PartialEq , Eq , PartialOrd , Ord , Hash ) ]
132+ #[ non_exhaustive]
133+ enum NewAddrType {
134+ /// Relays
135+ Relay ( RelayUrl ) ,
136+ /// IP based addresses
137+ Ip ( SocketAddr ) ,
138+ /// New addr type for testing
139+ Cool ( u16 ) ,
140+ }
141+
142+ #[ test]
143+ fn test_roundtrip_new_addr_type ( ) {
144+ let old = vec ! [
145+ TransportAddr :: Ip ( "127.0.0.1:9" . parse( ) . unwrap( ) ) ,
146+ TransportAddr :: Relay ( "https://example.com" . parse( ) . unwrap( ) ) ,
147+ ] ;
148+ let old_ser = postcard:: to_stdvec ( & old) . unwrap ( ) ;
149+ let old_back: Vec < TransportAddr > = postcard:: from_bytes ( & old_ser) . unwrap ( ) ;
150+ assert_eq ! ( old, old_back) ;
151+
152+ let new = vec ! [
153+ NewAddrType :: Ip ( "127.0.0.1:9" . parse( ) . unwrap( ) ) ,
154+ NewAddrType :: Relay ( "https://example.com" . parse( ) . unwrap( ) ) ,
155+ NewAddrType :: Cool ( 4 ) ,
156+ ] ;
157+ let new_ser = postcard:: to_stdvec ( & new) . unwrap ( ) ;
158+ let new_back: Vec < NewAddrType > = postcard:: from_bytes ( & new_ser) . unwrap ( ) ;
159+
160+ assert_eq ! ( new, new_back) ;
161+
162+ // serialize old into new
163+ let old_new_back: Vec < NewAddrType > = postcard:: from_bytes ( & old_ser) . unwrap ( ) ;
164+
165+ assert_eq ! (
166+ old_new_back,
167+ vec![
168+ NewAddrType :: Ip ( "127.0.0.1:9" . parse( ) . unwrap( ) ) ,
169+ NewAddrType :: Relay ( "https://example.com" . parse( ) . unwrap( ) ) ,
170+ ]
171+ ) ;
172+ }
173+ }
0 commit comments