Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reduce the number of REGISTER_IP_ADDRESSES calls #4219

Open
wants to merge 4 commits into
base: main
Choose a base branch
from

Conversation

dlon
Copy link
Member

@dlon dlon commented Dec 14, 2022

Follow-up to #4218. This PR makes a couple of changes:

  • Don't unregister tunnel IP in ST driver when reconnecting
  • When entering the error state due to being offline, don't send an update.

Most of the time, this should lower the number of IOCTL calls from 2 to 0 when reconnecting, and from 2 to 1 when connecting if the tunnel IP has changed.

There is a small risk that some other network interface will take over the previous tunnel IP. If that happens, excluded connections will be incorrectly redirected to the default interface, though this is unlikely and is irrelevant from a security standpoint. As long as the tunnel IP is correct when there is a tunnel device, leaks are not possible.


This change is Reviewable

@dlon dlon force-pushed the win-st-simplify-ip-reg branch from dc0e143 to ac7cb5a Compare December 14, 2022 14:23
@dlon dlon requested a review from Jontified December 19, 2022 12:37
Copy link
Contributor

@Jontified Jontified left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed 6 of 6 files at r1, all commit messages.
Reviewable status: all files reviewed, 5 unresolved discussions (waiting on @dlon)


talpid-core/src/split_tunnel/windows/mod.rs line 115 at r1 (raw file):

    excluded_processes: Arc<RwLock<HashMap<usize, ExcludedProcess>>>,
    _route_change_callback: Option<CallbackHandle>,
    daemon_tx: Weak<mpsc::UnboundedSender<TunnelCommand>>,

Discussed in previous PR


talpid-core/src/split_tunnel/windows/mod.rs line 857 at r1 (raw file):

    }

    fn create_burst_guard(

Perhaps we'd like to create a generic implementation of a burst guard and use it for taplid-routing/src/windows/default_route_monitor.rs as well? I guess the abort handle is here to make cancelling the task a bit quicker? Just dropping the tx would do and would make it a bit simpler but the task would cancel only at the point were rx.next() returns None. Not saying it is better.


talpid-core/src/split_tunnel/windows/mod.rs line 875 at r1 (raw file):

                Ok(None) => {
                    log::warn!("Failed to obtain default route interface address");
                    match address_family {

The only time that get_up_address_for_interface returns Ok(None) here is when the new default interface has lost internet connection?

Previously we'd have cleared the ST drivers IP addresses but now we don't which means that if the old default interface still has connectivity we'll keep using that for the ST. The reason it is impossible for this to leak inside of the tunnel is that the old default interface can not have been the tunnel interface and the tunnel interface can not change to be the old default interface. The reason this is impossible to leak outside of the tunnel is that this is already leaking outside of the tunnel, that's the point.

Am I understanding correctly? If I am then that sounds reasonable in order to avoid having unnecessary calls to the ST driver.


talpid-core/src/tunnel_state_machine/disconnected_state.rs line 55 at r1 (raw file):

    ) {
        if shared_values.block_when_disconnected {
            if let Err(error) = shared_values.split_tunnel.set_tunnel_addresses(None) {

General question here. Why do we reset the split tunnel when block_when_disconnected is set to true? I'm guessing blocking it would not be what we want since only vpn tunnel traffic should be blocked?


talpid-types/src/tunnel.rs line 120 at r1 (raw file):

    #[cfg(target_os = "windows")]
    pub fn prevents_split_tunneling(&self) -> bool {
        matches!(self, Self::SplitTunnelError | Self::IsOffline)

If the error is SplitTunnelError we will not clear the split tunnel IPs, why? I thought this was because we want to be able to disconnect and reconnect to networks without having to spend time clearing and resetting the ST IPs. If there is an ST error isn't that a different scenario?

Copy link
Member Author

@dlon dlon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewable status: all files reviewed, 5 unresolved discussions (waiting on @Jontified)


talpid-core/src/split_tunnel/windows/mod.rs line 115 at r1 (raw file):

Previously, Jontified wrote…

Discussed in previous PR

Done.


talpid-core/src/split_tunnel/windows/mod.rs line 857 at r1 (raw file):

Previously, Jontified wrote…

Perhaps we'd like to create a generic implementation of a burst guard and use it for taplid-routing/src/windows/default_route_monitor.rs as well? I guess the abort handle is here to make cancelling the task a bit quicker? Just dropping the tx would do and would make it a bit simpler but the task would cancel only at the point were rx.next() returns None. Not saying it is better.

We should probably consider generalizing them, but the gain isn't massive.


talpid-core/src/split_tunnel/windows/mod.rs line 875 at r1 (raw file):

Previously, Jontified wrote…

The only time that get_up_address_for_interface returns Ok(None) here is when the new default interface has lost internet connection?

Previously we'd have cleared the ST drivers IP addresses but now we don't which means that if the old default interface still has connectivity we'll keep using that for the ST. The reason it is impossible for this to leak inside of the tunnel is that the old default interface can not have been the tunnel interface and the tunnel interface can not change to be the old default interface. The reason this is impossible to leak outside of the tunnel is that this is already leaking outside of the tunnel, that's the point.

Am I understanding correctly? If I am then that sounds reasonable in order to avoid having unnecessary calls to the ST driver.

That's correct.


talpid-core/src/tunnel_state_machine/disconnected_state.rs line 55 at r1 (raw file):

Previously, Jontified wrote…

General question here. Why do we reset the split tunnel when block_when_disconnected is set to true? I'm guessing blocking it would not be what we want since only vpn tunnel traffic should be blocked?

What we're doing is really just setting the tunnel IP in win-split-tunnel to a reserved IP.

This prevents some other network device from stealing the IP of the last Mullvad interface, while keeping the device in the engaged state to allow some traffic (eg LAN) to leak outside the tunnel in excluded apps. We don't clear the tunnel IP because doing so would force win-split-tunnel out of the engaged state.

If we didn't use a reserved IP, and some interface took over the IP, its connections would be incorrectly redirected to the default interface. Not a vuln, since it would only affect excluded apps, but definitely unexpected.


talpid-types/src/tunnel.rs line 120 at r1 (raw file):

Previously, Jontified wrote…

If the error is SplitTunnelError we will not clear the split tunnel IPs, why? I thought this was because we want to be able to disconnect and reconnect to networks without having to spend time clearing and resetting the ST IPs. If there is an ST error isn't that a different scenario?

Basically, it is likely to fail and stall, since changing the addrs was the reason for entering the error state in the first place. But perhaps it should try anyway.

Jontified
Jontified previously approved these changes Jan 9, 2023
Copy link
Contributor

@Jontified Jontified left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:lgtm:

Reviewable status: all files reviewed, 1 unresolved discussion (waiting on @dlon)


talpid-core/src/split_tunnel/windows/mod.rs line 857 at r1 (raw file):

Previously, dlon (David Lönnhager) wrote…

We should probably consider generalizing them, but the gain isn't massive.

Fair enough, OOS for this PR.

@dlon dlon marked this pull request as ready for review September 29, 2023 13:53
Similarly, if we enter the error state due to being offline, don't
send an update

Since the IP is likely to be identical after reconnecting, this should
lower the number of IOCTLs to 0 from 2. There is a small risk that
some other network interface will take over the previous tunnel IP and
be incorrectly redirected to the default interface, though this should not
be dangerous from a security standpoint, since it only applies to
excluded processes
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants