@@ -149,6 +149,7 @@ pub struct VpnInterface {
149
149
pub struct SplitTunnelHandle {
150
150
redir_handle : Option < RedirectHandle > ,
151
151
tun_name : String ,
152
+ route_manager : RouteManagerHandle ,
152
153
}
153
154
154
155
impl SplitTunnelHandle {
@@ -169,7 +170,9 @@ impl SplitTunnelHandle {
169
170
vpn_interface : Option < VpnInterface > ,
170
171
) -> Result < Self , Error > {
171
172
let handle = self . redir_handle . take ( ) . unwrap ( ) ;
172
- let ( st_utun, pktap_stream, classify, default_interface, _) = handle. stop ( ) . await ?;
173
+ let ( st_utun, pktap_stream, classify, _default_interface, _) = handle. stop ( ) . await ?;
174
+
175
+ let default_interface = get_default_interface ( & self . route_manager ) . await ?;
173
176
174
177
self . redir_handle = Some (
175
178
redirect_packets_for_pktap_stream (
@@ -198,6 +201,42 @@ pub async fn create_split_tunnel(
198
201
vpn_interface : Option < VpnInterface > ,
199
202
classify : impl Fn ( & PktapPacket ) -> RoutingDecision + Send + ' static ,
200
203
) -> Result < SplitTunnelHandle , Error > {
204
+ let default_interface = get_default_interface ( & route_manager) . await ?;
205
+
206
+ let mut tun_config = tun:: configure ( ) ;
207
+ tun_config. address ( ST_IFACE_IPV4 ) . up ( ) ;
208
+ let tun_device =
209
+ tun:: create_as_async ( & tun_config) . map_err ( Error :: CreateSplitTunnelInterface ) ?;
210
+ let tun_name = tun_device. get_ref ( ) . name ( ) . to_owned ( ) ;
211
+
212
+ // Add IPv6 address
213
+ // TODO: Only add IPv6 address if there's either a tun or a non-tun IPv6 route
214
+ // FIXME: Solve cleanly rather than using subcmd
215
+ let output = tokio:: process:: Command :: new ( "ifconfig" )
216
+ . args ( [ & tun_name, "inet6" , & ST_IFACE_IPV6 . to_string ( ) , "alias" ] )
217
+ . output ( )
218
+ . await
219
+ . map_err ( Error :: AddIpv6Address ) ?;
220
+ if !output. status . success ( ) {
221
+ return Err ( Error :: AddIpv6Address ( io:: Error :: new (
222
+ io:: ErrorKind :: Other ,
223
+ "ifconfig failed" ,
224
+ ) ) ) ;
225
+ }
226
+
227
+ let redir_handle =
228
+ redirect_packets ( tun_device, default_interface, vpn_interface, classify) . await ?;
229
+
230
+ Ok ( SplitTunnelHandle {
231
+ redir_handle : Some ( redir_handle) ,
232
+ tun_name,
233
+ route_manager,
234
+ } )
235
+ }
236
+
237
+ async fn get_default_interface (
238
+ route_manager : & RouteManagerHandle ,
239
+ ) -> Result < DefaultInterface , Error > {
201
240
let ( v4_default, v6_default) = route_manager
202
241
. get_default_routes ( )
203
242
. await
@@ -267,39 +306,10 @@ pub async fn create_split_tunnel(
267
306
None
268
307
} ;
269
308
270
- let default_interface = DefaultInterface {
309
+ Ok ( DefaultInterface {
271
310
name : default_interface,
272
311
v4_addrs : default_v4,
273
312
v6_addrs : default_v6,
274
- } ;
275
-
276
- let mut tun_config = tun:: configure ( ) ;
277
- tun_config. address ( ST_IFACE_IPV4 ) . up ( ) ;
278
- let tun_device =
279
- tun:: create_as_async ( & tun_config) . map_err ( Error :: CreateSplitTunnelInterface ) ?;
280
- let tun_name = tun_device. get_ref ( ) . name ( ) . to_owned ( ) ;
281
-
282
- // Add IPv6 address
283
- // TODO: Only add IPv6 address if there's either a tun or a non-tun IPv6 route
284
- // FIXME: Solve cleanly rather than using subcmd
285
- let output = tokio:: process:: Command :: new ( "ifconfig" )
286
- . args ( [ & tun_name, "inet6" , & ST_IFACE_IPV6 . to_string ( ) , "alias" ] )
287
- . output ( )
288
- . await
289
- . map_err ( Error :: AddIpv6Address ) ?;
290
- if !output. status . success ( ) {
291
- return Err ( Error :: AddIpv6Address ( io:: Error :: new (
292
- io:: ErrorKind :: Other ,
293
- "ifconfig failed" ,
294
- ) ) ) ;
295
- }
296
-
297
- let redir_handle =
298
- redirect_packets ( tun_device, default_interface, vpn_interface, classify) . await ?;
299
-
300
- Ok ( SplitTunnelHandle {
301
- redir_handle : Some ( redir_handle) ,
302
- tun_name,
303
313
} )
304
314
}
305
315
0 commit comments