From 6fcc9d1fd594f14257d3d943e8b538f68eba883f Mon Sep 17 00:00:00 2001 From: Joseph Doherty Date: Mon, 23 Feb 2026 04:47:41 -0500 Subject: [PATCH] docs: update differences.md to reflect all remaining lower-priority gaps resolved Mark JWT auth, OCSP, subject mapping, Windows Service, per-subsystem log control, per-client trace, per-account stats, TLS cert expiry, permission templates, bearer tokens, and user revocation as implemented. --- differences.md | 44 +++++++++++++++++++++++++------------------- 1 file changed, 25 insertions(+), 19 deletions(-) diff --git a/differences.md b/differences.md index 829df24..9adb727 100644 --- a/differences.md +++ b/differences.md @@ -43,7 +43,7 @@ | SIGUSR1 (reopen logs) | Y | Y | SIGUSR1 handler calls ReOpenLogFile | | SIGUSR2 (lame duck mode) | Y | Y | Triggers `LameDuckShutdownAsync()` | | SIGHUP (config reload) | Y | Stub | Signal registered, handler logs "not yet implemented" | -| Windows Service integration | Y | N | | +| Windows Service integration | Y | Y | `--service` flag with `Microsoft.Extensions.Hosting.WindowsServices` | --- @@ -79,7 +79,7 @@ | Slow consumer detection | Y | Y | Pending bytes threshold (64MB) + write deadline timeout (10s) | | Write deadline / timeout policies | Y | Y | `WriteDeadline` option with `CancellationTokenSource.CancelAfter` on flush | | RTT measurement | Y | Y | `_rttStartTicks`/`Rtt` property, computed on PONG receipt | -| Per-client trace mode | Y | N | | +| Per-client trace mode | Y | Y | `SetTraceMode()` toggles parser logger dynamically via `ClientFlags.TraceMode` | | Detailed close reason tracking | Y | Y | 37-value `ClosedState` enum with CAS-based `MarkClosed()` | | Connection state flags (16 flags) | Y | Y | 7-flag `ClientFlagHolder` with `Interlocked.Or`/`And` | @@ -98,7 +98,7 @@ Go implements a sophisticated slow consumer detection system: |---------|:--:|:----:|-------| | Per-connection atomic stats | Y | Y | .NET uses `Interlocked` for stats access | | Per-read-cycle stat batching | Y | Y | Local accumulators flushed via `Interlocked.Add` per read cycle | -| Per-account stats | Y | N | | +| Per-account stats | Y | Y | `Interlocked` counters for InMsgs/OutMsgs/InBytes/OutBytes per `Account` | | Slow consumer counters | Y | Y | `SlowConsumers` and `SlowConsumerClients` incremented on detection | --- @@ -136,7 +136,7 @@ Go implements a sophisticated slow consumer detection system: |---------|:--:|:----:|-------| | Multi-client-type command routing | Y | N | Go checks `c.kind` to allow/reject commands | | Protocol tracing in parser | Y | Y | `TraceInOp()` logs `<<- OP arg` at `LogLevel.Trace` via optional `ILogger` | -| Subject mapping (input→output) | Y | N | Go transforms subjects via mapping rules | +| Subject mapping (input→output) | Y | Y | Compiled `SubjectTransform` engine with 9 function tokens; wired into `ProcessMessage` | | MIME header parsing | Y | Y | `NatsHeaderParser.Parse()` — status line + key-value headers from `ReadOnlySpan` | | Message trace event initialization | Y | N | | @@ -204,14 +204,14 @@ Go implements a sophisticated slow consumer detection system: | Username/password | Y | Y | | | Token | Y | Y | | | NKeys (Ed25519) | Y | Y | .NET has framework but integration is basic | -| JWT validation | Y | N | | +| JWT validation | Y | Y | `NatsJwt` decode/verify, `JwtAuthenticator` with account resolution + revocation | | Bcrypt password hashing | Y | Y | .NET supports bcrypt (`$2*` prefix) with constant-time fallback | | TLS certificate mapping | Y | Y | X500DistinguishedName with full DN match and CN fallback | | Custom auth interface | Y | N | | | External auth callout | Y | N | | | Proxy authentication | Y | N | | -| Bearer tokens | Y | N | | -| User revocation tracking | Y | N | | +| Bearer tokens | Y | Y | `UserClaims.BearerToken` skips nonce signature verification | +| User revocation tracking | Y | Y | Per-account `ConcurrentDictionary` with wildcard (`*`) revocation support | ### Account System | Feature | Go | .NET | Notes | @@ -234,7 +234,7 @@ Go implements a sophisticated slow consumer detection system: | Permission caching (128 entries) | Y | Y | `PermissionLruCache` — Dictionary+LinkedList LRU, matching Go's `maxPermCacheSize` | | Response permissions (reply tracking) | Y | Y | `ResponseTracker` with configurable TTL + max messages; not LRU-cached | | Auth expiry enforcement | Y | Y | `Task.Delay` timer closes client when JWT/auth expires | -| Permission templates (JWT) | Y | N | e.g., `{{name()}}`, `{{account-tag(...)}}` | +| Permission templates (JWT) | Y | Y | `PermissionTemplates.Expand()` — 6 functions with cartesian product for multi-value tags | --- @@ -263,12 +263,12 @@ Go implements a sophisticated slow consumer detection system: | ~450 option fields | Y | ~62 | .NET covers core + debug/trace/logging/limits/tags options | ### Missing Options Categories -- ~~Logging options~~ — file logging, rotation, syslog, debug/trace, color, timestamps all implemented; only per-subsystem log control remains +- ~~Logging options~~ — file logging, rotation, syslog, debug/trace, color, timestamps, per-subsystem log control all implemented - ~~Advanced limits (MaxSubs, MaxSubTokens, MaxPending, WriteDeadline)~~ — `MaxSubs`, `MaxSubTokens` implemented; MaxPending/WriteDeadline already existed - ~~Tags/metadata~~ — `Tags` dictionary implemented in `NatsOptions` -- OCSP configuration +- ~~OCSP configuration~~ — `OcspConfig` with 4 modes (Auto/Always/Must/Never), peer verification, and stapling - WebSocket/MQTT options -- Operator mode / account resolver +- ~~Operator mode / account resolver~~ — `JwtAuthenticator` + `IAccountResolver` + `MemAccountResolver` with trusted keys --- @@ -303,7 +303,7 @@ Go implements a sophisticated slow consumer detection system: | SlowConsumer breakdown | Y | N | Go tracks per connection type | | Cluster/Gateway/Leaf blocks | Y | N | Excluded per scope | | JetStream block | Y | N | Excluded per scope | -| TLS cert expiry info | Y | N | | +| TLS cert expiry info | Y | Y | `TlsCertNotAfter` loaded via `X509CertificateLoader` in `/varz` | ### Connz Response | Feature | Go | .NET | Notes | @@ -343,7 +343,7 @@ Go implements a sophisticated slow consumer detection system: | TLS rate limiting | Y | Y | Rate enforcement with refill; unit tests cover rate limiting and refill | | First-byte peeking (0x16 detection) | Y | Y | | | Cert subject→user mapping | Y | Y | X500DistinguishedName with full DN match and CN fallback | -| OCSP stapling | Y | N | | +| OCSP stapling | Y | Y | `SslStreamCertificateContext.Create` with `offline:false` for runtime OCSP fetch | | Min TLS version control | Y | Y | | --- @@ -358,7 +358,7 @@ Go implements a sophisticated slow consumer detection system: | Log reopening (SIGUSR1) | Y | Y | SIGUSR1 handler calls ReOpenLogFile callback | | Trace mode (protocol-level) | Y | Y | `-V`/`-T`/`--trace` flags; parser `TraceInOp()` logs at Trace level | | Debug mode | Y | Y | `-D`/`--debug` flag lowers Serilog minimum to Debug | -| Per-subsystem log control | Y | N | | +| Per-subsystem log control | Y | Y | `--log_level_override ns=level` CLI flag with Serilog `MinimumLevel.Override` | | Color output on TTY | Y | Y | Auto-detected via `Console.IsOutputRedirected`, uses `AnsiConsoleTheme.Code` | | Timestamp format control | Y | Y | `--logtime` and `--logtime_utc` flags | @@ -393,6 +393,17 @@ The following items from the original gap list have been implemented: - **Subscription statistics** — `Stats()`, `HasInterest()`, `NumInterest()`, etc. - **Per-account limits** — connection + subscription limits via `AccountConfig` - **Reply subject tracking** — `ResponseTracker` with TTL + max messages +- **JWT authentication** — `JwtAuthenticator` with decode/verify, account resolution, revocation, permission templates +- **OCSP support** — peer verification via `X509RevocationMode.Online`, stapling via `SslStreamCertificateContext` +- **Subject mapping** — compiled `SubjectTransform` engine with 9 function tokens, wired into message delivery +- **Windows Service integration** — `--service` flag with `Microsoft.Extensions.Hosting.WindowsServices` +- **Per-subsystem log control** — `--log_level_override` CLI flag with Serilog overrides +- **Per-client trace mode** — `SetTraceMode()` with dynamic parser logger toggling +- **Per-account stats** — `Interlocked` counters for InMsgs/OutMsgs/InBytes/OutBytes +- **TLS cert expiry in /varz** — `TlsCertNotAfter` populated via `X509CertificateLoader` +- **Permission templates** — `PermissionTemplates.Expand()` with 6 functions and cartesian product +- **Bearer tokens** — `UserClaims.BearerToken` skips nonce verification +- **User revocation** — per-account tracking with wildcard (`*`) revocation ### Remaining High Priority 1. **Config file parsing** — needed for production deployment (CLI stub exists) @@ -400,8 +411,3 @@ The following items from the original gap list have been implemented: ### Remaining Lower Priority 3. **Dynamic buffer sizing** — delegated to Pipe, less optimized for long-lived connections -4. **JWT authentication** — needed for operator mode -5. **OCSP support** — certificate revocation checking -6. **Subject mapping** — input→output subject transformation -7. **Windows Service integration** — needed for Windows deployment -8. **Per-subsystem log control** — granular log levels per component