CodeLogic.NetUtils 5.0.114-preview

This is a prerelease version of CodeLogic.NetUtils.
This package has a SemVer 2.0.0 package version: 5.0.114-preview+d5246b7.
There is a newer prerelease version of this package available.
See the version list below for details.
dotnet add package CodeLogic.NetUtils --version 5.0.114-preview
                    
NuGet\Install-Package CodeLogic.NetUtils -Version 5.0.114-preview
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="CodeLogic.NetUtils" Version="5.0.114-preview" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="CodeLogic.NetUtils" Version="5.0.114-preview" />
                    
Directory.Packages.props
<PackageReference Include="CodeLogic.NetUtils" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add CodeLogic.NetUtils --version 5.0.114-preview
                    
#r "nuget: CodeLogic.NetUtils, 5.0.114-preview"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package CodeLogic.NetUtils@5.0.114-preview
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=CodeLogic.NetUtils&version=5.0.114-preview&prerelease
                    
Install as a Cake Addin
#tool nuget:?package=CodeLogic.NetUtils&version=5.0.114-preview&prerelease
                    
Install as a Cake Tool

CodeLogic.NetUtils

NuGet License: MIT

DNSBL blacklist checking and MaxMind GeoIP geolocation for CodeLogic 5 — screen abusive IPs and locate visitors with one library.

Bundles two network-reputation tools behind a single NetUtilsLibrary. The DNSBL checker queries multiple blacklist zones (IPv4 and IPv6, primary plus fallback) in parallel and short-circuits private/loopback addresses without a DNS query. The GeoIP service does city-level lookups against a MaxMind GeoLite2/GeoIP2 .mmdb database — loaded from disk or auto-downloaded with your MaxMind credentials.

Install

dotnet add package CodeLogic.NetUtils

Quick start

using CL.NetUtils;

await Libraries.LoadAsync<NetUtilsLibrary>();   // register before ConfigureAsync()
await CodeLogic.ConfigureAsync();
await CodeLogic.StartAsync();

var net = Libraries.Get<NetUtilsLibrary>();

// 1. Is this IP on a blacklist? (uses the zones from config.netutils.json)
DnsblCheckResult check = await net.Dnsbl.CheckIpAsync("203.0.113.1");
if (check.IsBlacklisted)
    Console.WriteLine($"Listed by {check.MatchedService}");
else if (check.Status == DnsblCheckStatus.Indeterminate)
    Console.WriteLine($"Not listed by the zones that answered; unchecked: {string.Join(", ", check.FailedServices)}");

// 2. Where is this IP? Guard with HasGeoIp — GeoIP needs a MaxMind database.
if (net.HasGeoIp)
{
    IpLocationResult geo = await net.GeoIp.LookupIpAsync("203.0.113.1");
    if (geo.IsSuccessful)
        Console.WriteLine($"{geo.CityName}, {geo.CountryName} ({geo.CountryCode})");
}

Local and private addresses (loopback, RFC 1918, link-local, CGNAT, documentation/reserved ranges, IPv6 link/site-local and unique-local) are returned as not blacklisted without any DNS query.

Features

  • DNSBL checking — query multiple blacklist zones per address family, concurrently or one at a time (ParallelQueries), with primary/fallback providers. A check where zones could not be queried is Indeterminate, never reported as clean.
  • Per-call overrides — CheckIpAsync(ip, DnsblCheckRequest) supplies your own zones, timeout, and an async allowlist predicate.
  • Private-address short-circuit — loopback and RFC 1918 / IPv6 local ranges skip DNS and return not blacklisted.
  • IP geolocation — city-level country/city/coordinates/time-zone lookups via MaxMind GeoLite2/GeoIP2.
  • Auto-download — fetch the .mmdb when it is missing, using your MaxMind AccountId + LicenseKey, only from an https URL on a trusted host; only the .mmdb is extracted and it replaces the database in one rename.
  • Own result records — DnsblCheckResult and IpLocationResult, each with success/error factories.

Configuration

Auto-generated on first run as config.netutils.json (section netutils). Keys are camelCase and matched case-sensitively, so a PascalCase key is ignored and its default stays active:

{
  "enabled": true,
  "dnsbl": {
    "enabled": true,
    "ipv4Services": ["zen.spamhaus.org", "dnsbl.sorbs.net"],
    "ipv4FallbackServices": ["b.barracudacentral.org"],
    "ipv6Services": ["zen.spamhaus.org", "dnsbl6.sorbs.net"],
    "ipv6FallbackServices": ["v6.b.barracudacentral.org"],
    "timeoutSeconds": 5,
    "parallelQueries": true,
    "detailedLogging": false
  },
  "geoIp": {
    "enabled": true,
    "databasePath": "",
    "autoUpdate": false,
    "accountId": 0,
    "licenseKey": "",
    "downloadUrl": "https://download.maxmind.com/geoip/databases/GeoLite2-City/download?suffix=tar.gz",
    "trustedDownloadHosts": ["download.maxmind.com"],
    "databaseType": "GeoLite2-City",
    "timeoutSeconds": 30
  }
}
Setting Default Description
Enabled true Master switch for the library.
Dnsbl.Enabled true Enable the DNSBL checker.
Dnsbl.Ipv4Services ["zen.spamhaus.org","dnsbl.sorbs.net"] Primary IPv4 blacklist zones.
Dnsbl.Ipv4FallbackServices ["b.barracudacentral.org"] Queried when no primary zone lists the address.
Dnsbl.Ipv6Services ["zen.spamhaus.org","dnsbl6.sorbs.net"] Primary IPv6 blacklist zones.
Dnsbl.Ipv6FallbackServices ["v6.b.barracudacentral.org"] IPv6 fallback zones.
Dnsbl.TimeoutSeconds 5 Per-zone DNS timeout; a zone that times out is reported in FailedServices.
Dnsbl.ParallelQueries true Query the zones of a list concurrently; false queries one at a time and stops at the first listing.
Dnsbl.DetailedLogging false Log each zone query.
GeoIp.Enabled true Enable the GeoIP service.
GeoIp.DatabasePath "" Explicit .mmdb path; blank auto-resolves to {dataDir}/geoip/{DatabaseType}.mmdb.
GeoIp.AutoUpdate false Refresh the database on startup when credentials are set (a missing database is always downloaded; a failed refresh keeps the old one).
GeoIp.AccountId 0 MaxMind account id (required for download).
GeoIp.LicenseKey "" MaxMind license key (secret; required for download).
GeoIp.DownloadUrl MaxMind GeoLite2-City Download endpoint (tar.gz or zip). Must be https on a host in TrustedDownloadHosts, because the credentials are sent to it.
GeoIp.TrustedDownloadHosts ["download.maxmind.com"] Hosts DownloadUrl may use (exact match).
GeoIp.DatabaseType GeoLite2-City Database/edition id.
GeoIp.TimeoutSeconds 30 Download timeout.

Documentation

Full guide: CL.NetUtils documentation

Requirements

  • CodeLogic 5.0+ · .NET 11
  • MaxMind.GeoIP2 6.x
  • A MaxMind GeoLite2/GeoIP2 .mmdb for GeoIP (on disk, or auto-downloaded with credentials)

License

MIT — see LICENSE.

Product Compatible and additional computed target framework versions.
.NET net11.0 is compatible. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (1)

Showing the top 1 NuGet packages that depend on CodeLogic.NetUtils:

Package Downloads
CodeLogic.WebLogic

Web application toolkit for CodeLogic 4 — routing, templates, forms, an ordered security pipeline, auth flows and realtime. No third-party dependencies beyond CodeLogic.*.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
5.0.116-preview 46 11/1/2026
5.0.115-preview 103 11/1/2026
5.0.114-preview 31 10/31/2026
5.0.113-preview 35 10/31/2026
4.9.106 41 10/30/2026
4.9.98 538 10/25/2026
4.8.93 70 9/23/2026
4.8.87 108 9/13/2026
4.8.85 58 9/12/2026
4.6.75-preview 60 8/1/2026
4.6.73 228 7/13/2026
4.6.72 70 6/20/2026
4.6.69-preview 65 6/20/2026
4.5.2 139 5/24/2026
4.5.2-preview.68 96 6/20/2026
4.5.1 185 5/24/2026
4.5.1-preview.56 117 5/24/2026
4.4.2-preview.53 89 5/24/2026
4.4.1 139 5/24/2026
4.0.5 128 5/15/2026
Loading failed

# CL.NetUtils — Changelog

All notable changes to **CodeLogic.NetUtils** are documented here. Versions follow
[Semantic Versioning](https://semver.org/).

## 5.0 (unreleased)

### Breaking

- Targets **.NET 11** (`net11.0`) and requires **CodeLogic 5.0** (`[5.0.0, 6.0.0)`). On .NET 10, stay on
 4.9.x. CodeLogic 5 makes `Result<T>` / `Result` C# 15 unions and `Error` a closed record with
 kind subtypes (`NotFoundError`, `ValidationError`, ...). Results can now be matched exhaustively
 with `switch`.
- **A DNSBL check that could not query a zone is no longer reported as clean.** Timeouts, resolver
 failures and DNSBL error answers (Spamhaus `127.255.255.x`) used to end as `NotBlacklisted`. When no
 zone lists the address but some zone failed, the result is now `Status = DnsblCheckStatus.Indeterminate`
 with the zones in `FailedServices` and a message in `ErrorMessage`; `IsBlacklisted` stays `false`.
 NXDOMAIN is still "not listed". Check `Status` where an unchecked address must not pass.
- **`GeoIp.DownloadUrl` must be `https` on a trusted host.** The MaxMind credentials were sent to any
 configured URL. The host must now be listed in the new `GeoIp.TrustedDownloadHosts` (default
 `["download.maxmind.com"]`); otherwise the download is refused before any request and configuration
 validation fails.
- **SharpCompress dependency removed.** The GeoIP archive is read with the built-in `System.Formats.Tar`
 and `System.IO.Compression` (`tar.gz` and `zip`).

### Added

- `DnsblCheckStatus` (`NotBlacklisted`, `Blacklisted`, `Indeterminate`, `Error`), `DnsblCheckResult.Status`,
 `DnsblCheckResult.FailedServices` and `DnsblCheckResult.Indeterminate(...)`.
- `DnsblCheckRequest.ParallelQueries` (default `true`).
- `GeoIpConfig.TrustedDownloadHosts` and `GeoIpConfig.TryGetTrustedDownloadUri(...)`.

### Fixed

- **A corrupt GeoIP download can no longer replace a working database (re-audit R2).** The extracted file is opened with the MaxMind reader, must be a City database, and must answer a test lookup. Only then is it renamed into place. The open reader switches without a gap, and on any failure the old file and reader stay in use. Readers load the database into memory, so the file is never locked.
- **`GeoIp.AutoUpdate` now works:** before, nothing read it. On startup it refreshes an existing database when credentials are set; a failed refresh is logged and the existing database stays in use. A missing database is downloaded regardless.
- **`Dnsbl.ParallelQueries` is honoured.** Zones were always queried one at a time. Now the zones of a
 list are queried concurrently by default, and with `ParallelQueries = false` one at a time, stopping at
 the first listing. DNS lookups use the asynchronous resolver, so the per-zone timeout is enforced.
- **GeoIP database replacement is selective and atomic.** Every archive entry (licence, readme, ...) was
 extracted straight into the database directory, over the live file. Now the archive is unpacked in a
 private temporary directory, only the `.mmdb` entry is extracted (by content, never by entry path),
 checked for the MaxMind metadata marker, and moved over the database in one rename; an open reader is
 switched to the new file. A failed or invalid download leaves the existing database untouched. A custom
 `DatabasePath` with a different file name than the archive's `.mmdb` now gets the database too.
- `LookupIpAsync` reads the database reader under its lock, so a concurrent reload or dispose cannot
 race it.
- Package versions are pinned (`MaxMind.GeoIP2` 6.1.0) instead of floating.
- **DNSBL queries are built from the parsed address.** The IPv4 query label reversed the dot-separated input
 text, so a shorthand that `IPAddress.TryParse` accepts (`1.2.3` = 1.2.0.3, hex `0x01.0x02.0x03.0x04`,
 a single 32-bit number) queried the wrong name and was never found listed. The label now comes from the
 address bytes, and an IPv4-mapped IPv6 address (`::ffff:a.b.c.d`) is checked against the IPv4 zones.
- **More non-routable addresses skip the DNSBL query:** IPv4 `0.0.0.0/8`, link-local `169.254/16`, shared
 address space (CGNAT) `100.64/10`, `192.0.0/24`, the documentation ranges (`192.0.2/24`, `198.51.100/24`,
 `203.0.113/24`), benchmarking `198.18/15`, multicast `224/4`, reserved `240/4` and broadcast; IPv6 unspecified
 `::` and documentation `2001:db8::/32`. Like the existing private ranges they return *not blacklisted*.

### Documentation

- Configuration examples use the camelCase keys the CodeLogic loader reads (PascalCase keys were ignored).
- The DNSBL guide describes the actual query order, fallback rule and failure handling.

## 2026-10-30

### Fixed

- **Health no longer reports optional features that are off as faults.** GeoIP with neither a database file
 nor MaxMind credentials is now *not configured* and Healthy (it was Degraded "GeoIP unavailable"), and is
 logged at Info instead of a startup warning. Degraded now means GeoIP was set up (database file or
 credentials) and still failed to start; the message carries the reason. The health message lists both
 services, e.g. `DNSBL on, GeoIP not configured`. A library with both services switched off is Healthy too.

### Added

- `GeoIpService.DatabasePath` and `GeoIpService.CanDownload`.

## 2026-10-24

### Changed

- Requires **CodeLogic 4.9+**. The official libraries move to the 4.9 line together with the framework,
 whose live config changes the stateful libraries now use. No API changes in this library.

## 2026-09-12

### Changed

- Unified the version line with the CodeLogic framework on **4.8.x**. Every official
 library and the framework now share one `major.minor`, so a given `4.8.<patch>`
 means the same generation across all packages.
- `version.txt` moved from `4.6` to `4.8`. The patch component remains the CI run
 number, composed at pack time; `AssemblyVersion` stays pinned at `Major.Minor.0.0`
 (now `4.8.0.0`) so every patch in the line loads interchangeably.

## 2026-06-20

### Documentation

- Full rewrite of the README and the deep docs page to house style: NuGet + MIT
 badges, blockquote tagline, concise quick-start, feature list, and a complete
 configuration table covering every `Dnsbl.*` and `GeoIp.*` field.
- Documented the correct load pattern (`Libraries.LoadAsync<NetUtilsLibrary>()`
 → `ConfigureAsync` → `StartAsync` → `Libraries.Get`) and both `Dnsbl` /
 `GeoIp` accessors, with the `HasGeoIp` guard for the optional GeoIP service.
- Documented both `CheckIpAsync` overloads, the default IPv4/IPv6 blacklist
 zones, and the per-call `DnsblCheckRequest` (per-call zone lists, timeout, and
 async allowlist predicate).
- Documented the `DnsblCheckResult` and `IpLocationResult` records field by
 field, including `IpLocationResult.IsSuccessful`.
- Documented GeoIP database resolution and auto-download: `DatabasePath` vs the
 `{dataDir}/geoip/{DatabaseType}.mmdb` fallback, and `DownloadDatabaseAsync`
 fetching/extracting the `.mmdb` via HTTP Basic Auth with `AccountId` +
 `LicenseKey`.

## [4.5.2] — 2026-06-20

### Documentation

- Corrected the README Quick Start to match the real API: `Dnsbl.CheckIpAsync`
 (was `CheckAsync`) returning `DnsblCheckResult.IsBlacklisted` / `MatchedService`
 (was `IsListed`), and the async `GeoIp.LookupIpAsync` returning
 `IpLocationResult.CountryName` / `CityName` (was a synchronous `Lookup`).
- Documented the `DnsblCheckRequest` overload of `CheckIpAsync` — per-call
 service lists plus an optional async allowlist predicate (`IsAllowedAsync`).
- Documented the `DnsblCheckResult` and `IpLocationResult` result records and
 the `IpLocationResult.IsSuccessful` helper.
- Documented that local/private addresses are short-circuited as not blacklisted.
- Added the `GeoIp.DownloadUrl` field to the sample `config.netutils.json`.

## [4.5.0] — 2026-05-24

### Changed

- **Unified versioning.** All CodeLogic.Libs now share a single version line
 controlled by `version.txt` in the repo root. This is a version alignment
 release — no functional changes to this library.
## [4.0.4] — 2026-04-16

### Changed

- README + manifest refresh for the v4 baseline. No functional changes vs 4.0.3.
- `LibraryManifest.Version` now reads from assembly metadata.

## [4.0.2] — 2026-04-09

### Added

- `DnsblCheckRequest` overload that accepts a caller-supplied DNSBL service
 list — useful when the calling app stores its own service registry instead
 of relying on the bundled defaults.

### Changed

- Annotated NetUtils configuration with `[ConfigField]` for the admin UI surface.
- Aligned with the v4 baseline across all libraries.

## [4.0.0] — 2026-04-09

Major rewrite. Republished as v4.0.0 to reset the version line under the
unified v4 baseline. GeoIP, DNSBL, and IP/CIDR utilities.

### Notes

- Earlier history is retained in the
 [git log](https://github.com/zyntal-com/CodeLogic.Libs/commits/main/CL.NetUtils).