@@ -28,7 +28,6 @@ use std::{
28
28
29
29
use chrono:: { DateTime , Local } ;
30
30
use itertools:: Itertools ;
31
-
32
31
use mullvad_types:: {
33
32
constraints:: Constraint ,
34
33
custom_list:: CustomListsSettings ,
@@ -186,13 +185,27 @@ pub struct AdditionalWireguardConstraints {
186
185
/// Values which affect the choice of relay but are only known at runtime.
187
186
#[ derive( Clone , Debug ) ]
188
187
pub struct RuntimeParameters {
188
+ /// Whether IPv6 is available
189
+ pub ipv4 : bool ,
189
190
/// Whether IPv6 is available
190
191
pub ipv6 : bool ,
191
192
}
192
193
193
194
impl RuntimeParameters {
194
195
/// Return whether a given [query][`RelayQuery`] is valid given the current runtime parameters
195
196
pub fn compatible ( & self , query : & RelayQuery ) -> bool {
197
+ if !self . ipv4 {
198
+ let must_use_ipv4 = matches ! (
199
+ query. wireguard_constraints( ) . ip_version,
200
+ Constraint :: Only ( talpid_types:: net:: IpVersion :: V4 )
201
+ ) ;
202
+ if must_use_ipv4 {
203
+ log:: trace!(
204
+ "{query:?} is incompatible with {self:?} due to IPv4 not being available"
205
+ ) ;
206
+ return false ;
207
+ }
208
+ }
196
209
if !self . ipv6 {
197
210
let must_use_ipv6 = matches ! (
198
211
query. wireguard_constraints( ) . ip_version,
@@ -214,7 +227,10 @@ impl RuntimeParameters {
214
227
#[ allow( clippy:: derivable_impls) ]
215
228
impl Default for RuntimeParameters {
216
229
fn default ( ) -> Self {
217
- RuntimeParameters { ipv6 : false }
230
+ RuntimeParameters {
231
+ ipv4 : true ,
232
+ ipv6 : false ,
233
+ }
218
234
}
219
235
}
220
236
@@ -655,7 +671,9 @@ impl RelaySelector {
655
671
// Remove candidate queries based on runtime parameters before trying to merge user
656
672
// settings
657
673
. filter ( |query| runtime_params. compatible ( query) )
674
+ . filter ( |query| runtime_params. compatible ( & user_query) )
658
675
. filter_map ( |query| query. clone ( ) . intersection ( user_query. clone ( ) ) )
676
+ . map ( |query| force_valid_ip_version ( & query, runtime_params. clone ( ) ) )
659
677
. filter ( |query| Self :: get_relay_inner ( query, parsed_relays, user_config. custom_lists ) . is_ok ( ) )
660
678
. cycle ( ) // If the above filters remove all relays, cycle will also return an empty iterator
661
679
. nth ( retry_attempt)
@@ -1187,6 +1205,23 @@ impl RelaySelector {
1187
1205
}
1188
1206
}
1189
1207
1208
+ fn force_valid_ip_version ( query : & RelayQuery , runtime_params : RuntimeParameters ) -> RelayQuery {
1209
+ let mut wireguard_constraints = query. wireguard_constraints ( ) . clone ( ) ;
1210
+ if wireguard_constraints. ip_version . is_any ( ) {
1211
+ if runtime_params. ipv4 && !runtime_params. ipv6 {
1212
+ wireguard_constraints. ip_version = Constraint :: Only ( talpid_types:: net:: IpVersion :: V4 )
1213
+ }
1214
+ if runtime_params. ipv6 && !runtime_params. ipv4 {
1215
+ wireguard_constraints. ip_version = Constraint :: Only ( talpid_types:: net:: IpVersion :: V6 )
1216
+ }
1217
+ }
1218
+ let mut ret = query. clone ( ) ;
1219
+ match ( ret. set_wireguard_constraints ( wireguard_constraints) ) {
1220
+ Ok ( ( ) ) => ret,
1221
+ _Error => query. clone ( ) ,
1222
+ }
1223
+ }
1224
+
1190
1225
#[ derive( Clone ) ]
1191
1226
struct RelayWithDistance {
1192
1227
distance : f64 ,
0 commit comments