Table of Contents

Namespace VpnHood.Net.Toolkit.Utils

Classes

AccessCodeUtils

Provides access codes: 20 characters, the version digit 1, a check digit, and 18 random characters.

AsyncLock

Provides a lock an async method can wait for, held until the returned result is disposed: an instance's own, or a process-wide one by name.

AutoDispose

Provides an IDisposable that runs an action when disposed, for a using scope.

DnsUtils

Provides DNS helpers: the network's resolvers, and a minimal A-record lookup over UDP.

EventReporter

Provides a counter of a repeated event that logs a summary at an interval instead of a line per event: the message, the events since the last report, their span and the total.

ExponentialBackoff

Tracks consecutive failures and gates retries behind an exponential backoff window: baseDelay, 2×baseDelay, 4×baseDelay ... capped at maxDelay. The window grows on each failure and clears on success/reset. Not thread-safe; callers sharing an instance must synchronize.

FastDateTime

Provides a cached UTC clock for hot paths, refreshed at most once per Precision.

FileUtils

Provides file helpers: moves, atomic writes, and reads and writes that wait out another process's sharing.

JsonSerializerExt

Provides the means to merge JSON into an existing object, by reflection.

JsonUtils

Provides JSON helpers: comparison, cloning, reading text and files, and redaction.

MimeTypeUtils

Helper class for determining MIME content types based on file extensions

OsUtils

Provides the means to run a program or a shell command and read its output.

Patch<T>

Represents a value set in a patch, so a patch can tell a property set to null from one left out, which a null Patch<T> stands for.

Redactor

Redacts identifying values for logs and screens: a globally routable address becomes a keyed token that cannot be turned back without the process's key, which dies with it; a private or local address stays readable, and host names and IDs keep some of their characters.

Whether redaction applies is carried by the instance, not by the method you pick, so a call site states its own guarantee. Always redacts whatever the settings say — the app UI and the tracking log need that, since neither should start printing real addresses because logging was switched out of anonymous mode.

Redact* produces a string now; Format* wraps the same work in a Redactor.RedactedValue<T> that redacts on its ToString, which a logger calls when it writes the record.

Singleton<T>

Provides a base for a class with one registered instance in the process, which Instance gives.

UserAgentParser

Provides the means to read the operating system from a browser's User-Agent.

VhInvoker

Provides the means to run what may fail without letting the failure out: it is logged as Could not {actionName}. at the level the caller gives.

VhTestUtil

Provides test assertions that wait for a value, or check the exception an API call throws.

VhTestUtil.AssertException

The exception that is thrown when an assertion fails.

VhUtils

Provides assorted helpers: sizes and their text, sockets and free ports, tasks with a timeout, keys and hashes, files, and countries.

VhUtilsExtensions

Provides the means to replace a timeout while a debugger is attached.

WindowsCommonFiles

Provides the means to install files, such as a vendor's DLL and driver, into a folder of their own under Common Files, which only administrators may change.

Structs

Redactor.RedactedValue<T>

Carries a value into a log record without redacting it yet.

A log argument is an ordinary method argument, so VhLogger.Format(x) runs before the logger is ever asked whether the level is enabled. Returning a string there means every disabled hot-path statement still pays for the redaction — an allocation, and since the redaction became keyed, an HMAC. This type defers that work to ToString(), which a logger calls when it writes the record; any other call to it redacts too.

The point is that no call site has to remember anything. Guarding hot statements with a level check works too, but it is a ritual that the next log statement someone adds will not repeat.

Interfaces

AsyncLock.ILockAsyncResult

Represents a wait for the lock: dispose every one, a timed-out one too, as it releases the lock it took, once, and ends a named lock's bookkeeping.