Skip to content

Commit 1d518cc

Browse files
committed
no hostname option and fixes
1 parent 251ca0b commit 1d518cc

File tree

10 files changed

+129
-65
lines changed

10 files changed

+129
-65
lines changed

common/client-core/src/cli_helpers/client_add_gateway.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ where
8787
user_chosen_gateway_id.map(|id| id.to_base58_string()),
8888
Some(common_args.latency_based_selection),
8989
common_args.force_tls_gateway,
90+
false,
9091
);
9192
tracing::debug!("Gateway selection specification: {selection_spec:?}");
9293

common/client-core/src/cli_helpers/client_init.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,7 @@ where
140140
user_chosen_gateway_id.map(|id| id.to_base58_string()),
141141
Some(common_args.latency_based_selection),
142142
common_args.force_tls_gateway,
143+
false,
143144
);
144145
tracing::debug!("Gateway selection specification: {selection_spec:?}");
145146

common/client-core/src/error.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,9 @@ pub enum ClientCoreError {
4646
#[error("Invalid URL: {0}")]
4747
InvalidUrl(String),
4848

49+
#[error("node doesn't advertise ip addresses : {0}")]
50+
MissingIpAddress(String),
51+
4952
#[cfg(not(target_arch = "wasm32"))]
5053
#[error("resolution failed: {0}")]
5154
ResolutionFailed(#[from] nym_http_api_client::ResolveError),

common/client-core/src/init/mod.rs

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -71,21 +71,28 @@ where
7171
let mut rng = OsRng;
7272

7373
let selected_gateway = match selection_specification {
74-
GatewaySelectionSpecification::UniformRemote { must_use_tls } => {
74+
GatewaySelectionSpecification::UniformRemote {
75+
must_use_tls,
76+
no_hostname,
77+
} => {
7578
let gateway = uniformly_random_gateway(&mut rng, &available_gateways, must_use_tls)?;
76-
SelectedGateway::from_topology_node(gateway, must_use_tls)?
79+
SelectedGateway::from_topology_node(gateway, must_use_tls, no_hostname)?
7780
}
78-
GatewaySelectionSpecification::RemoteByLatency { must_use_tls } => {
81+
GatewaySelectionSpecification::RemoteByLatency {
82+
must_use_tls,
83+
no_hostname,
84+
} => {
7985
let gateway =
8086
choose_gateway_by_latency(&mut rng, &available_gateways, must_use_tls).await?;
81-
SelectedGateway::from_topology_node(gateway, must_use_tls)?
87+
SelectedGateway::from_topology_node(gateway, must_use_tls, no_hostname)?
8288
}
8389
GatewaySelectionSpecification::Specified {
8490
must_use_tls,
91+
no_hostname,
8592
identity,
8693
} => {
8794
let gateway = get_specified_gateway(&identity, &available_gateways, must_use_tls)?;
88-
SelectedGateway::from_topology_node(gateway, must_use_tls)?
95+
SelectedGateway::from_topology_node(gateway, must_use_tls, no_hostname)?
8996
}
9097
GatewaySelectionSpecification::Custom {
9198
gateway_identity,
@@ -150,6 +157,7 @@ pub async fn update_gateway_details<D>(
150157
mut registration: GatewayRegistration,
151158
available_gateways: Vec<RoutingNode>,
152159
must_use_tls: bool,
160+
no_hostname: bool,
153161
) -> Result<(), ClientCoreError>
154162
where
155163
D: GatewaysDetailsStore,
@@ -159,7 +167,7 @@ where
159167
tracing::trace!("Updating gateway details : {gateway_id}");
160168

161169
let gateway = get_specified_gateway(&gateway_id, &available_gateways, must_use_tls)?;
162-
let selected_gateway = SelectedGateway::from_topology_node(gateway, must_use_tls)?;
170+
let selected_gateway = SelectedGateway::from_topology_node(gateway, must_use_tls, no_hostname)?;
163171

164172
let new_gateway_listeners = match selected_gateway {
165173
SelectedGateway::Remote {

common/client-core/src/init/types.rs

Lines changed: 56 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -39,34 +39,47 @@ impl SelectedGateway {
3939
pub fn from_topology_node(
4040
node: RoutingNode,
4141
must_use_tls: bool,
42+
no_hostname: bool,
4243
) -> Result<Self, ClientCoreError> {
4344
// for now, let's use 'old' behaviour, if you want to change it, you can pass it up the enum stack yourself : )
4445
let prefer_ipv6 = false;
4546

46-
let gateway_listener = if must_use_tls {
47-
node.ws_entry_address_tls()
48-
.ok_or(ClientCoreError::UnsupportedWssProtocol {
49-
gateway: node.identity_key.to_base58_string(),
50-
})?
47+
let (gateway_listener, fallback_listener) = if must_use_tls {
48+
// WSS main, no fallback
49+
let primary =
50+
node.ws_entry_address_tls()
51+
.ok_or(ClientCoreError::UnsupportedWssProtocol {
52+
gateway: node.identity_key.to_base58_string(),
53+
})?;
54+
(primary, None)
55+
} else if no_hostname {
56+
// First IP address for main, second if it exists for fallback
57+
let primary = node.ws_entry_address_no_hostname(prefer_ipv6, 0).ok_or(
58+
ClientCoreError::MissingIpAddress(node.identity_key.to_base58_string()),
59+
)?;
60+
let fallback = node.ws_entry_address_no_hostname(prefer_ipv6, 1);
61+
(primary, fallback)
5162
} else {
52-
node.ws_entry_address(prefer_ipv6)
53-
.ok_or(ClientCoreError::UnsupportedEntry {
54-
id: node.node_id,
55-
identity: node.identity_key.to_base58_string(),
56-
})?
63+
// WS hostname main, IP address fallback
64+
let primary =
65+
node.ws_entry_address(prefer_ipv6)
66+
.ok_or(ClientCoreError::UnsupportedEntry {
67+
id: node.node_id,
68+
identity: node.identity_key.to_base58_string(),
69+
})?;
70+
let fallback = node.ws_entry_address_no_hostname(prefer_ipv6, 0);
71+
(primary, fallback)
5772
};
5873

59-
let fallback_listener =
60-
node.ws_entry_address_no_hostname(prefer_ipv6)
61-
.and_then(|address| {
62-
Url::parse(&address)
63-
.inspect_err(|err| {
64-
tracing::warn!("Malformed fallback listener, none will be used : {err}")
65-
})
66-
.ok()
67-
});
68-
69-
let gateway_listener =
74+
let fallback_listener_url = fallback_listener.and_then(|address| {
75+
Url::parse(&address)
76+
.inspect_err(|err| {
77+
tracing::warn!("Malformed fallback listener, none will be used : {err}")
78+
})
79+
.ok()
80+
});
81+
82+
let gateway_listener_url =
7083
Url::parse(&gateway_listener).map_err(|source| ClientCoreError::MalformedListener {
7184
gateway_id: node.identity_key.to_base58_string(),
7285
raw_listener: gateway_listener,
@@ -76,8 +89,8 @@ impl SelectedGateway {
7689
Ok(SelectedGateway::Remote {
7790
gateway_id: node.identity_key,
7891
gateway_listeners: GatewayListeners {
79-
primary: gateway_listener,
80-
fallback: fallback_listener,
92+
primary: gateway_listener_url,
93+
fallback: fallback_listener_url,
8194
},
8295
})
8396
}
@@ -168,15 +181,22 @@ impl InitialisationResult {
168181
#[derive(Clone, Debug)]
169182
pub enum GatewaySelectionSpecification {
170183
/// Uniformly choose a random remote gateway.
171-
UniformRemote { must_use_tls: bool },
184+
UniformRemote {
185+
must_use_tls: bool,
186+
no_hostname: bool,
187+
},
172188

173189
/// Should the new, remote, gateway be selected based on latency.
174-
RemoteByLatency { must_use_tls: bool },
190+
RemoteByLatency {
191+
must_use_tls: bool,
192+
no_hostname: bool,
193+
},
175194

176195
/// Gateway with this specific identity should be chosen.
177196
// JS: I don't really like the name of this enum variant but couldn't think of anything better at the time
178197
Specified {
179198
must_use_tls: bool,
199+
no_hostname: bool,
180200
identity: IdentityKey,
181201
},
182202

@@ -192,6 +212,7 @@ impl Default for GatewaySelectionSpecification {
192212
fn default() -> Self {
193213
GatewaySelectionSpecification::UniformRemote {
194214
must_use_tls: false,
215+
no_hostname: false,
195216
}
196217
}
197218
}
@@ -201,16 +222,24 @@ impl GatewaySelectionSpecification {
201222
gateway_identity: Option<String>,
202223
latency_based_selection: Option<bool>,
203224
must_use_tls: bool,
225+
no_hostname: bool,
204226
) -> Self {
205227
if let Some(identity) = gateway_identity {
206228
GatewaySelectionSpecification::Specified {
207229
identity,
208230
must_use_tls,
231+
no_hostname,
209232
}
210233
} else if let Some(true) = latency_based_selection {
211-
GatewaySelectionSpecification::RemoteByLatency { must_use_tls }
234+
GatewaySelectionSpecification::RemoteByLatency {
235+
must_use_tls,
236+
no_hostname,
237+
}
212238
} else {
213-
GatewaySelectionSpecification::UniformRemote { must_use_tls }
239+
GatewaySelectionSpecification::UniformRemote {
240+
must_use_tls,
241+
no_hostname,
242+
}
214243
}
215244
}
216245
}

common/client-libs/gateway-client/src/client/websockets.rs

Lines changed: 22 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,6 @@ use url::{Host, Url};
1515

1616
use std::{net::SocketAddr, time::Duration};
1717

18-
const INITIAL_CONNECTION_TIMEOUT: Duration = Duration::from_secs(5);
19-
2018
#[cfg(not(target_arch = "wasm32"))]
2119
pub(crate) async fn connect_async(
2220
endpoint: &str,
@@ -40,6 +38,8 @@ pub(crate) async fn connect_async(
4038
Host::Ipv6(addr) => vec![SocketAddr::new(addr.into(), port)],
4139
Host::Domain(domain) => {
4240
// Do a DNS lookup for the domain using our custom DNS resolver
41+
println!("I'M TIRED BOSS");
42+
tokio::time::sleep(Duration::from_secs(20)).await;
4343
resolver
4444
.resolve_str(domain)
4545
.await?
@@ -95,33 +95,29 @@ pub(crate) async fn connect_async_with_fallback(
9595
endpoints: &GatewayListeners,
9696
#[cfg(unix)] connection_fd_callback: Option<Arc<dyn Fn(RawFd) + Send + Sync>>,
9797
) -> Result<(WebSocketStream<MaybeTlsStream<TcpStream>>, Response), GatewayClientError> {
98-
// Hickory DNS has a non cofigurable 2 * 10 seconds timeout so we have to add one here as well
99-
match tokio::time::timeout(
100-
INITIAL_CONNECTION_TIMEOUT,
101-
connect_async(
102-
endpoints.primary.as_ref(),
103-
#[cfg(unix)]
104-
connection_fd_callback.clone(),
105-
),
98+
match connect_async(
99+
endpoints.primary.as_ref(),
100+
#[cfg(unix)]
101+
connection_fd_callback.clone(),
106102
)
107103
.await
108104
{
109-
Ok(inner) => inner,
110-
Err(_) if endpoints.fallback.is_some() => {
111-
// SAFTEY: We know there is a fallback here
112-
#[allow(clippy::unwrap_used)]
113-
let fallback = endpoints.fallback.as_ref().unwrap().to_string();
114-
tracing::warn!(
115-
"Timeout trying to connect to endpoint {}, trying fallback : {fallback}",
116-
endpoints.primary
117-
);
118-
connect_async(
119-
&fallback,
120-
#[cfg(unix)]
121-
connection_fd_callback,
122-
)
123-
.await
105+
Ok(inner) => Ok(inner),
106+
Err(e) => {
107+
if let Some(fallback) = &endpoints.fallback {
108+
tracing::warn!(
109+
"Main endpoint failed {} : {e}, trying fallback : {fallback}",
110+
endpoints.primary
111+
);
112+
connect_async(
113+
fallback.as_ref(),
114+
#[cfg(unix)]
115+
connection_fd_callback,
116+
)
117+
.await
118+
} else {
119+
Err(e)
120+
}
124121
}
125-
Err(_) => Err(GatewayClientError::Timeout),
126122
}
127123
}

common/gateway-storage/migrations/20251126120000_remove_aes128ctr_key.sql

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,12 @@ CREATE TABLE shared_keys_tmp
99
(
1010
client_id INTEGER NOT NULL PRIMARY KEY REFERENCES clients (id),
1111
client_address_bs58 TEXT NOT NULL UNIQUE,
12-
derived_aes256_gcm_siv_key BLOB NOT NULL
12+
derived_aes256_gcm_siv_key BLOB NOT NULL,
13+
last_used_authentication TIMESTAMP WITHOUT TIME ZONE
1314
);
1415

15-
INSERT INTO shared_keys_tmp (client_id, client_address_bs58, derived_aes256_gcm_siv_key)
16-
SELECT client_id, client_address_bs58, derived_aes256_gcm_siv_key
16+
INSERT INTO shared_keys_tmp (client_id, client_address_bs58, derived_aes256_gcm_siv_key, last_used_authentication)
17+
SELECT client_id, client_address_bs58, derived_aes256_gcm_siv_key, last_used_authentication
1718
FROM shared_keys
1819
WHERE derived_aes256_gcm_siv_key IS NOT NULL;
1920

common/topology/src/node.rs

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -89,14 +89,20 @@ impl RoutingNode {
8989
self.ws_entry_address_no_tls(prefer_ipv6)
9090
}
9191

92-
pub fn ws_entry_address_no_hostname(&self, prefer_ipv6: bool) -> Option<String> {
92+
pub fn ws_entry_address_no_hostname(&self, prefer_ipv6: bool, index: usize) -> Option<String> {
9393
let entry = self.entry.as_ref()?;
9494

95-
if prefer_ipv6 && let Some(ipv6) = entry.ip_addresses.iter().find(|ip| ip.is_ipv6()) {
95+
if prefer_ipv6
96+
&& let Some(ipv6) = entry
97+
.ip_addresses
98+
.iter()
99+
.filter(|ip| ip.is_ipv6())
100+
.nth(index)
101+
{
96102
return Some(format!("ws://{ipv6}:{}", entry.clients_ws_port));
97103
}
98104

99-
let any_ip = entry.ip_addresses.first()?;
105+
let any_ip = entry.ip_addresses.get(index)?;
100106
Some(format!("ws://{any_ip}:{}", entry.clients_ws_port))
101107
}
102108

nym-registration-client/src/builder/config.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,7 @@ impl BuilderConfig {
119119
.network_details(self.network_env)
120120
.debug_config(debug_config)
121121
.credentials_mode(true)
122+
.no_hostname(true)
122123
.with_remember_me(remember_me)
123124
.custom_topology_provider(self.custom_topology_provider);
124125

0 commit comments

Comments
 (0)