@@ -47,7 +47,7 @@ use talpid_types::{
47
47
net:: {
48
48
obfuscation:: ObfuscatorConfig ,
49
49
proxy:: { CustomProxy , Shadowsocks } ,
50
- Endpoint , TransportProtocol , TunnelType ,
50
+ Endpoint , IpVersion , TransportProtocol , TunnelType ,
51
51
} ,
52
52
ErrorExt ,
53
53
} ;
@@ -182,63 +182,30 @@ pub struct AdditionalWireguardConstraints {
182
182
#[ derive( Clone , Debug ) ]
183
183
pub struct RuntimeParameters {
184
184
/// Whether IPv4, IPv6 or both is available
185
- pub ip_availability : IpAvailability ,
185
+ pub ip_availability : Option < Constraint < IpVersion > > ,
186
186
}
187
187
188
188
impl RuntimeParameters {
189
- /// Return whether a given [query][`RelayQuery`] is valid given the current runtime parameters
190
- pub fn compatible ( & self , query : & RelayQuery ) -> bool {
191
- match query. wireguard_constraints ( ) . ip_version {
192
- Constraint :: Any => true ,
193
- Constraint :: Only ( talpid_types:: net:: IpVersion :: V4 ) => self . ip_availability . has_ipv4 ( ) ,
194
- Constraint :: Only ( talpid_types:: net:: IpVersion :: V6 ) => self . ip_availability . has_ipv6 ( ) ,
195
- }
196
- }
197
-
198
189
pub fn new ( ipv4 : bool , ipv6 : bool ) -> RuntimeParameters {
199
- if ipv4 && ipv6 {
200
190
RuntimeParameters {
201
- ip_availability : IpAvailability :: All ,
202
- }
203
- } else if !ipv6 {
204
- RuntimeParameters {
205
- ip_availability : IpAvailability :: Ipv4 ,
206
- }
207
- } else if !ipv4 {
208
- RuntimeParameters {
209
- ip_availability : IpAvailability :: Ipv6 ,
210
- }
211
- } else {
212
- panic ! ( "Device is offline!" )
191
+ ip_availability : match ( ipv4, ipv6) {
192
+ ( true , true ) => Some ( Constraint :: Any ) ,
193
+ ( false , true ) => Some ( Constraint :: Only ( IpVersion :: V6 ) ) ,
194
+ ( true , false ) => Some ( Constraint :: Only ( IpVersion :: V4 ) ) ,
195
+ ( false , false ) => None ,
196
+ } ,
213
197
}
214
198
}
215
199
}
216
200
217
201
impl Default for RuntimeParameters {
218
202
fn default ( ) -> Self {
219
203
RuntimeParameters {
220
- ip_availability : IpAvailability :: Ipv4 ,
204
+ ip_availability : Some ( Constraint :: Only ( IpVersion :: V4 ) ) ,
221
205
}
222
206
}
223
207
}
224
208
225
- #[ derive( Clone , Debug , PartialEq , Eq ) ]
226
- pub enum IpAvailability {
227
- Ipv4 ,
228
- Ipv6 ,
229
- All ,
230
- }
231
-
232
- impl IpAvailability {
233
- fn has_ipv4 ( & self ) -> bool {
234
- self . clone ( ) == IpAvailability :: Ipv4 || self . clone ( ) == IpAvailability :: All
235
- }
236
-
237
- fn has_ipv6 ( & self ) -> bool {
238
- self . clone ( ) == IpAvailability :: Ipv6 || self . clone ( ) == IpAvailability :: All
239
- }
240
- }
241
-
242
209
/// This enum exists to separate the two types of [`SelectorConfig`] that exists.
243
210
///
244
211
/// The first one is a "regular" config, where [`SelectorConfig::relay_settings`] is
@@ -669,19 +636,12 @@ impl RelaySelector {
669
636
user_config : & NormalSelectorConfig < ' _ > ,
670
637
parsed_relays : & RelayList ,
671
638
) -> Result < RelayQuery , Error > {
672
- let user_query = RelayQuery :: try_from ( user_config. clone ( ) ) ?;
639
+ let mut user_query = RelayQuery :: try_from ( user_config. clone ( ) ) ?;
640
+ apply_ip_availability ( runtime_params, & mut user_query) ?;
673
641
log:: trace!( "Merging user preferences {user_query:?} with default retry strategy" ) ;
674
642
retry_order
675
643
. iter ( )
676
- // Remove candidate queries based on runtime parameters before trying to merge user
677
- // settings
678
- . filter ( |query| runtime_params. compatible ( query) )
679
- // Check if the user query aligns with the runtime parameters so that if the user
680
- // has selected an ip version that is not available it will return an error
681
- . filter ( |_query| runtime_params. compatible ( & user_query) )
682
644
. filter_map ( |query| query. clone ( ) . intersection ( user_query. clone ( ) ) )
683
- // Resolve query ip version set to Any based on runtime ip availability
684
- . map ( |query| resolve_valid_ip_version ( & query, & runtime_params) )
685
645
. filter ( |query| Self :: get_relay_inner ( query, parsed_relays, user_config. custom_lists ) . is_ok ( ) )
686
646
. cycle ( ) // If the above filters remove all relays, cycle will also return an empty iterator
687
647
. nth ( retry_attempt)
@@ -1213,24 +1173,22 @@ impl RelaySelector {
1213
1173
}
1214
1174
}
1215
1175
1216
- /// If the selected ip version is Any we want to resolve that to an Only ip version if only
1217
- /// one ip version is available on the network. This is to avoid situations where in other parts
1218
- /// of the relay selector that Any is resolved to IPv4 and IPv4 is not available.
1219
- fn resolve_valid_ip_version ( query : & RelayQuery , runtime_params : & RuntimeParameters ) -> RelayQuery {
1220
- let mut wireguard_constraints = query. wireguard_constraints ( ) . clone ( ) ;
1221
- if wireguard_constraints. ip_version . is_any ( ) {
1222
- if runtime_params. ip_availability == IpAvailability :: Ipv4 {
1223
- wireguard_constraints. ip_version = Constraint :: Only ( talpid_types:: net:: IpVersion :: V4 )
1224
- }
1225
- if runtime_params. ip_availability == IpAvailability :: Ipv6 {
1226
- wireguard_constraints. ip_version = Constraint :: Only ( talpid_types:: net:: IpVersion :: V6 )
1227
- }
1228
- }
1229
- let mut ret = query. clone ( ) ;
1230
- match ret. set_wireguard_constraints ( wireguard_constraints) {
1231
- Ok ( ( ) ) => ret,
1232
- _error => query. clone ( ) ,
1233
- }
1176
+ fn apply_ip_availability (
1177
+ runtime_params : RuntimeParameters ,
1178
+ user_query : & mut RelayQuery ,
1179
+ ) -> Result < ( ) , Error > {
1180
+ let wireguard_constraints = user_query
1181
+ . wireguard_constraints ( )
1182
+ . to_owned ( )
1183
+ . intersection ( WireguardRelayQuery {
1184
+ ip_version : runtime_params
1185
+ . ip_availability
1186
+ . ok_or ( Error :: IpVersionUnavailable ) ?,
1187
+ ..Default :: default ( )
1188
+ } )
1189
+ . ok_or ( Error :: IpVersionUnavailable ) ?;
1190
+ user_query. set_wireguard_constraints ( wireguard_constraints) ?;
1191
+ Ok ( ( ) )
1234
1192
}
1235
1193
1236
1194
#[ derive( Clone ) ]
0 commit comments