ZeroTierOne icon indicating copy to clipboard operation
ZeroTierOne copied to clipboard

Add functionality to enable or disable networks (fixes #659)

Open GermanCoding opened this issue 4 years ago • 3 comments

So I'm mostly opening this PR because of recent popularity in issue #659. I originally did not intend to open this PR before 2.0 (e.g because of the UI changes and I also believe 2.0 will have stuff rewritten in Go?), but here we go anyway.

Description

This PR introduces the concept of a disabled network. Disabled networks behave like the user left them, except that local config data and the TAP interface is still retained (in an offline state).

This feature is useful when users do not always want to be part of a network. In some scenarios, users might want to temporarily leave a network, with the intention of re-joining (minutes/days/weeks/months) later. In this case ZeroTier's deleting of TAP interfaces (as well as the local config) is not desired. For these use-cases, networks can now be disabled. The old "leave the network and destroy everything" behaviour still exists, this is implemented as an optional feature.

The PR adds to new CLI commands (and corresponding HTTP endpoints in the service):

zerotier-cli enable <network>  - Enables a network
zerotier-cli disable <network> - Disables a network

Joining or leaving a disabled network won't work. In order to rejoin a disabled network, it must be re-enabled instead (disabling & enabling also auto-leaves/joins networks as appropriate).

This exact behaviour is up to discussion, and was mostly implemented because it was easier this way.

Disabled networks remain disabled, even across restarts, until enabled again via the appropriate command.

In order to be really useful for users, the ZeroTier UI should also enable usage of this feature. However, since that is now a different project, a different PR would be needed for this. I'm also not experienced in Rust, so not sure if I will be able to make a PR to the UI project.

Technical details

The PR adds a new local config object which stores the disabled state (true/false). On startup, if the disabled state is true, the network will be brought down again immediatly after loading it (this currently relies on some magic error signaling). The node no longer considers itself to be a member of this network. As soon as the network is re-enabled again, the node rejoins the network (and the TAP is brought up again). Disabling a network brings down the TAP interface and the node leaves the network, but the TAP as well as the local config is not destroyed.

A few changes to existing code were required:

  • Saving of network settings assumed that the network would exist in memory and would bail out if this wasn't the case. In order to change settings on a disabled network (which is not loaded at that time), this had to be changed to also allow changes to networks not currently joined by the node.
  • Loading of the local network config was previously inline and is now in its own function, to avoid code duplication.

Testing

I've been using this code (older commits, but functionally identical) in my fork of ZeroTier for over a year now, and I haven't seen many issues with the code, though I've never considered it production-ready. I have only ever tried this code under Windows.

GermanCoding avatar Oct 28 '21 23:10 GermanCoding

I'm not sure this patch is going to work for us as it changes the CLI. If this simply marked/reused Windows network profiles, that would probably get a faster track to the mainline code.

glimberg avatar Nov 08 '21 17:11 glimberg

Sorry for letting this sit for so long.

So just that I'm getting this right your policy is "no CLI changes at all"? Because this does not change existing commands, full compatibility is ensured and all existing commands work just the same as before. All this does is to add new commands with new features.

I believe reusing network profiles is an entirely different story that would also work differently - right now this is an optional feature. Users can either choose to keep their settings or lose them. Automatically reusing would make this no longer optional. This currently also keeps the local config (which is also a cross-platform feature of this) while your proposal won't be able to have this.

I'm not sure if I will find the time to rewrite the whole thing, and I'm also not 100% sure if network profile magic is possible without touching the driver (which I really don't want to do) - haven't yet looked where this is handled.

I have just rebased this on a recent ZT release, so if anyone has still interest in this feel free to have a look.

GermanCoding avatar Apr 20 '22 16:04 GermanCoding

We'll take another look. Thanks.

joseph-henry avatar Apr 20 '22 16:04 joseph-henry

Closing since this is on queue for V2, which is an entirely different code base...

adamierymenko avatar Nov 07 '22 16:11 adamierymenko