Class WindowsVpnKillSwitch
- Namespace
- VpnHood.Core.Client.Devices.WindowsTun
- Assembly
- VpnHood.Core.Client.Devices.WindowsTun.dll
Represents the kill switch's block on Windows: the Windows Filtering Platform's own filters, under a provider and a sublayer of ours.
public sealed class WindowsVpnKillSwitch : IVpnKillSwitch
- Inheritance
-
WindowsVpnKillSwitch
- Implements
- Inherited Members
Remarks
The filters are persistent: the Base Filtering Engine keeps them through a crash of the service and restores them when it starts at boot, so the block holds through both, as a crash lifting it would defeat its purpose. They are not boot-time filters, so they hold once the engine has started. Not a dynamic session's, which the engine deletes with its process: WireGuard for Windows uses one, and its block goes with a crash.
The connect and accept layers (ALE) judge a flow at its start, and again where Windows reauthorizes it, nothing per packet; the forward layers judge what Windows routes itself, which would otherwise go around the block. They have no port field, so DNS routed to an address of the split passes. A known limit: WinNAT's traffic — WSL2's NAT mode, so Docker Desktop's too — is seen by no WFP layer (seen on Windows Server 2025 with WSL 3.0.3), so it goes into the tunnel while one is up and around the block while none is. The Hyper-V firewall could stop it only while the service runs, never after a crash.
The keys are the SDK's, so every app built on VpnHood shares the one block; the provider's data names the app whose block it is. It needs an administrator: the service, which runs as SYSTEM.
Constructors
WindowsVpnKillSwitch(string, string?)
Represents the kill switch's block on Windows: the Windows Filtering Platform's own filters, under a provider and a sublayer of ours.
public WindowsVpnKillSwitch(string owner, string? serviceName)
Parameters
ownerstringThe app's storage folder, which names the app whose block it is and an update keeps, where the exe's folder changes.
serviceNamestringThe service whose processes the block lets out; null in a run as the person, whose block lets out none of its processes.
Remarks
The filters are persistent: the Base Filtering Engine keeps them through a crash of the service and restores them when it starts at boot, so the block holds through both, as a crash lifting it would defeat its purpose. They are not boot-time filters, so they hold once the engine has started. Not a dynamic session's, which the engine deletes with its process: WireGuard for Windows uses one, and its block goes with a crash.
The connect and accept layers (ALE) judge a flow at its start, and again where Windows reauthorizes it, nothing per packet; the forward layers judge what Windows routes itself, which would otherwise go around the block. They have no port field, so DNS routed to an address of the split passes. A known limit: WinNAT's traffic — WSL2's NAT mode, so Docker Desktop's too — is seen by no WFP layer (seen on Windows Server 2025 with WSL 3.0.3), so it goes into the tunnel while one is up and around the block while none is. The Hyper-V firewall could stop it only while the service runs, never after a crash.
The keys are the SDK's, so every app built on VpnHood shares the one block; the provider's data names the app whose block it is. It needs an administrator: the service, which runs as SYSTEM.
Methods
Block(VpnKillSwitchRules, CancellationToken)
Puts this app's block up, or re-points it, in one change with no gap, in place of any app's.
public Task Block(VpnKillSwitchRules rules, CancellationToken cancellationToken)
Parameters
rulesVpnKillSwitchRulesWhat the block lets pass.
cancellationTokenCancellationTokenThe token to monitor for cancellation requests.
Returns
- Task
A task that completes once the block is up.
Remarks
It fails where it cannot, and then nothing may connect: a connect never goes on unprotected.
Exceptions
- NotSupportedException
Linux has no nftables, or the service is in no cgroup v2 group of its own.
- ExternalException
The OS refused the block: Linux's
nft, or Windows' filtering engine, as without an administrator.- OperationCanceledException
cancellationTokenwas canceled.- Win32Exception
The filtering engine refused a change, as without an administrator.
IsBlocking(CancellationToken)
Determines whether this app's block is up.
public Task<bool> IsBlocking(CancellationToken cancellationToken)
Parameters
cancellationTokenCancellationTokenThe token to monitor for cancellation requests.
Returns
Remarks
It runs at once; the token is not watched.
Exceptions
- ExternalException
The OS's rules could not be read: Linux's
nft, or Windows' filtering engine.- OperationCanceledException
cancellationTokenwas canceled.- Win32Exception
The filtering engine could not be opened or read.
Unblock(bool, CancellationToken)
Removes this app's block, or, with anyApp, any app's: the tunnel's holder's call.
public Task Unblock(bool anyApp, CancellationToken cancellationToken)
Parameters
anyAppbooltrue to remove any app's block; false to remove this app's only.
cancellationTokenCancellationTokenThe token to monitor for cancellation requests.
Returns
- Task
A task that completes once the block is gone.
Remarks
It runs at once, in one transaction of the filtering engine; the token is not watched.
Exceptions
- ExternalException
The OS refused the change: Linux's
nft, or Windows' filtering engine.- OperationCanceledException
cancellationTokenwas canceled.- Win32Exception
The filtering engine refused a change, as without an administrator.