Commit Graph

50 Commits

Author SHA1 Message Date
Joseph Doherty
3941c85e76 Merge branch 'feature/core-lifecycle' into main
Reconcile close reason tracking: feature branch's MarkClosed() and
ShouldSkipFlush/FlushAndCloseAsync now use main's ClientClosedReason
enum. ClosedState enum retained for forward compatibility.
2026-02-23 00:09:30 -05:00
Joseph Doherty
2fb14821e0 feat: add no-responders CONNECT validation and tests
Reject connections that send no_responders:true without headers:true,
since the 503 HMSG response requires header support. Add three tests:
connection rejection, acceptance with headers, and 503 delivery flow.
2026-02-22 23:56:49 -05:00
Joseph Doherty
04305447f9 feat: implement verbose mode (+OK after commands)
When a client sends CONNECT {"verbose":true}, the server now responds
with +OK\r\n after successfully processing CONNECT, PING, SUB, UNSUB,
and PUB/HPUB commands, matching the Go NATS server behavior.
2026-02-22 23:54:41 -05:00
Joseph Doherty
e57605f090 feat: add PID file and ports file support 2026-02-22 23:50:22 -05:00
Joseph Doherty
34067f2b9b feat: add lame duck mode with staggered client shutdown 2026-02-22 23:48:06 -05:00
Joseph Doherty
b289041761 test: add write loop and slow consumer detection tests
Verify channel-based write loop behavior: QueueOutbound writes data
to client socket, PendingBytes tracking, slow consumer detection
when MaxPending is exceeded, close reason propagation, and server
stats incrementation on slow consumer events.
2026-02-22 23:47:31 -05:00
Joseph Doherty
45de110a84 feat: add flush-before-close for graceful client shutdown 2026-02-22 23:45:26 -05:00
Joseph Doherty
b68f898fa0 feat: add graceful shutdown, accept loop backoff, and task tracking 2026-02-22 23:43:25 -05:00
Joseph Doherty
31660a4187 feat: replace inline writes with channel-based write loop and batch flush 2026-02-22 23:41:44 -05:00
Joseph Doherty
600c6f9e5a feat: add system account ($SYS) and server NKey identity stubs 2026-02-22 23:39:22 -05:00
Joseph Doherty
38eaaa8b83 feat: add ephemeral port (port=0) support 2026-02-22 23:36:01 -05:00
Joseph Doherty
1a916a3f36 feat: add ClientFlags bitfield with thread-safe holder 2026-02-22 23:33:21 -05:00
Joseph Doherty
8bbfa54058 feat: add ClientClosedReason enum with 16 close reason values 2026-02-22 23:33:13 -05:00
Joseph Doherty
4d89661e79 feat: add monitoring HTTP endpoints and TLS support
Monitoring HTTP:
- /varz, /connz, /healthz via Kestrel Minimal API
- Pagination, sorting, subscription details on /connz
- ServerStats atomic counters, CPU/memory sampling
- CLI flags: -m, --http_port, --http_base_path, --https_port

TLS Support:
- 4-mode negotiation: no TLS, required, TLS-first, mixed
- Certificate loading, pinning (SHA-256), client cert verification
- PeekableStream for non-destructive TLS detection
- Token-bucket rate limiter for TLS handshakes
- CLI flags: --tls, --tlscert, --tlskey, --tlscacert, --tlsverify

29 new tests (78 → 107 total), all passing.

# Conflicts:
#	src/NATS.Server.Host/Program.cs
#	src/NATS.Server/NATS.Server.csproj
#	src/NATS.Server/NatsClient.cs
#	src/NATS.Server/NatsOptions.cs
#	src/NATS.Server/NatsServer.cs
#	src/NATS.Server/Protocol/NatsProtocol.cs
#	tests/NATS.Server.Tests/ClientTests.cs
2026-02-22 23:13:22 -05:00
Joseph Doherty
543b185f7e fix: address code quality issues from review
- Make ConnectReceived thread-safe with Volatile.Read/Write (accessed from auth timeout task and command pipeline)
- Include authTimeoutTask in Task.WhenAny to propagate exceptions
- Clear nonce after authentication with CryptographicOperations.ZeroMemory
- Avoid closure allocation on publish permission cache hot path (method group)
- Update AuthTimeout default to 2s to match Go server
2026-02-22 23:07:31 -05:00
Joseph Doherty
c40c2cd994 test: add permission enforcement and NKey integration tests
Fix NKey nonce verification: the NATS client signs the nonce string
(ASCII bytes of the base64url-encoded nonce), not the raw nonce bytes.
Pass the encoded nonce string bytes to the authenticator for verification.
2026-02-22 23:03:41 -05:00
Joseph Doherty
9cb3e2fe0f feat: add per-account SubList isolation for message routing
Subscriptions and message routing now go through account-specific SubLists
instead of a single global SubList. Clients in different accounts cannot
see each other's messages. When no account is specified (or auth is not
configured), all clients share the global $G account.
2026-02-22 23:00:59 -05:00
Joseph Doherty
2980a343c1 feat: integrate authentication into server accept loop and client CONNECT processing
Wire AuthService into NatsServer and NatsClient to enforce authentication
on incoming connections. The server builds an AuthService from NatsOptions,
sets auth_required in ServerInfo, and generates per-client nonces when
NKey auth is configured. NatsClient validates credentials in ProcessConnect,
enforces publish/subscribe permissions, and implements an auth timeout that
closes connections that don't send CONNECT in time. Existing tests without
auth continue to work since AuthService.IsAuthRequired is false by default.
2026-02-22 22:55:50 -05:00
Joseph Doherty
2a2cc6f0a2 feat: add AuthService orchestrator with priority-ordered authentication 2026-02-22 22:44:58 -05:00
Joseph Doherty
6ebe791c6d feat: add authenticators, Account, and ClientPermissions (Tasks 3-7, 9)
- Account: per-account SubList and client tracking
- IAuthenticator interface, AuthResult, ClientAuthContext
- TokenAuthenticator: constant-time token comparison
- UserPasswordAuthenticator: multi-user with bcrypt/plain support
- SimpleUserPasswordAuthenticator: single user/pass config
- NKeyAuthenticator: Ed25519 nonce signature verification
- ClientPermissions: SubList-based publish/subscribe authorization
2026-02-22 22:41:45 -05:00
Joseph Doherty
3b6bd08248 feat: add TLS mixed mode tests and monitoring TLS field verification
Add TlsMixedModeTests verifying that a server with AllowNonTls=true
accepts both plaintext and TLS clients on the same port. Add
MonitorTlsTests verifying that /connz reports TlsVersion and
TlsCipherSuite for TLS-connected clients.
2026-02-22 22:40:03 -05:00
Joseph Doherty
9eb108b1df feat: add /connz endpoint with pagination, sorting, and subscription details 2026-02-22 22:36:28 -05:00
Joseph Doherty
87746168ba feat: wire TLS negotiation into NatsServer accept loop
Integrate TLS support into the server's connection accept path:
- Add SslServerAuthenticationOptions and TlsRateLimiter fields to NatsServer
- Extract AcceptClientAsync method for TLS negotiation, rate limiting, and
  TLS state extraction (protocol version, cipher suite, peer certificate)
- Add InfoAlreadySent flag to NatsClient to skip redundant INFO when
  TlsConnectionWrapper already sent it during negotiation
- Add TlsServerTests verifying TLS connect+INFO and TLS pub/sub
2026-02-22 22:35:42 -05:00
Joseph Doherty
818bc0ba1f fix: address MonitorServer review — dispose resources, add cancellation, improve test reliability 2026-02-22 22:30:14 -05:00
Joseph Doherty
63198ef83b fix: address TlsConnectionWrapper review — clone ServerInfo, fix SslStream leak, add TLS-first test 2026-02-22 22:28:19 -05:00
Joseph Doherty
562f89744d feat: add IAuthenticator interface and TokenAuthenticator with constant-time comparison 2026-02-22 22:24:53 -05:00
Joseph Doherty
0cce771907 feat: add Account type with per-account SubList and client tracking 2026-02-22 22:22:51 -05:00
Joseph Doherty
0409acc745 feat: add TlsConnectionWrapper with 4-mode TLS negotiation 2026-02-22 22:21:11 -05:00
Joseph Doherty
5305069dd8 feat: add auth model types (User, NKeyUser, Permissions) and auth config to NatsOptions 2026-02-22 22:21:00 -05:00
Joseph Doherty
f2badc3488 feat: add MonitorServer with /healthz and /varz endpoints 2026-02-22 22:20:44 -05:00
Joseph Doherty
11dc5e62f3 feat: add auth fields to ServerInfo and ClientOptions protocol types 2026-02-22 22:19:18 -05:00
Joseph Doherty
91aff1a867 chore: add NATS.NKeys and BCrypt.Net-Next packages for authentication 2026-02-22 22:17:42 -05:00
Joseph Doherty
f6b38df291 feat: add TlsHelper, PeekableStream, and TlsRateLimiter
Add TLS utility classes for certificate loading, peekable stream for TLS
detection, token-bucket rate limiter for handshake throttling, and
TlsConnectionState for post-handshake info. Add TlsState property to
NatsClient. Fix X509Certificate2 constructor usage for .NET 10 compat.
2026-02-22 22:13:53 -05:00
Joseph Doherty
045c12cce7 feat: add Varz and Connz monitoring JSON models with Go field name parity 2026-02-22 22:13:50 -05:00
Joseph Doherty
a26c1359de refactor: NatsClient accepts Stream parameter for TLS support 2026-02-22 22:09:48 -05:00
Joseph Doherty
1a777e09c9 feat: add ServerStats counters and NatsClient metadata for monitoring 2026-02-22 22:08:30 -05:00
Joseph Doherty
b744913296 feat: add server-side PING keepalive with stale connection detection 2026-02-22 21:53:42 -05:00
Joseph Doherty
d14d73a7d0 feat: add pedantic subject validation and max payload enforcement on PUB
Move max payload validation from the parser to ProcessPubAsync so the
server sends -ERR 'Maximum Payload Violation' and closes the connection
(matching Go reference client.go:2442). In pedantic mode, reject PUB
with wildcard subjects via -ERR 'Invalid Publish Subject' (client.go:2869).
Add disposed guard to SubList.Remove to prevent crash during shutdown.
2026-02-22 21:49:01 -05:00
Joseph Doherty
0c12b0f6e3 feat: enforce MaxConnections limit in accept loop 2026-02-22 21:44:18 -05:00
Joseph Doherty
19e8c65f6d feat: add -ERR response infrastructure with SendErrAsync and SendErrAndCloseAsync 2026-02-22 21:42:04 -05:00
Joseph Doherty
2e1e1bb341 fix: resolve slopwatch issues — add logging to empty catches and eliminate test timing delays
Replace empty catch blocks with meaningful log statements in NatsServer,
NatsClient, and Program. Add WaitForReadyAsync() to NatsServer for
deterministic server startup. Replace Task.Delay/Thread.Sleep in tests
with PING/PONG protocol flush and SubscribeCoreAsync for reliable
subscription synchronization.
2026-02-22 21:14:16 -05:00
Joseph Doherty
539b2b7588 feat: add structured logging, Shouldly assertions, CPM, and project documentation
- Add Microsoft.Extensions.Logging + Serilog to NatsServer and NatsClient
- Convert all test assertions from xUnit Assert to Shouldly
- Add NSubstitute package for future mocking needs
- Introduce Central Package Management via Directory.Packages.props
- Add documentation_rules.md with style guide, generation/update rules, component map
- Generate 10 documentation files across 5 component folders (GettingStarted, Protocol, Subscriptions, Server, Configuration/Operations)
- Update CLAUDE.md with logging, testing, porting, agent model, CPM, and documentation guidance
2026-02-22 21:05:53 -05:00
Joseph Doherty
b9f4dec523 docs: update CLAUDE.md with verified build and test commands
Remove template UnitTest1.cs placeholder. Add actual project structure,
run commands for the NATS server host, and update test command examples
to reference the real project paths.
2026-02-22 20:34:42 -05:00
Joseph Doherty
c7fc703d7e feat: add integration tests using NATS.Client.Core NuGet package
Validates the server against the official NATS .NET client library with
tests for basic pub/sub, wildcard (* and >) matching, fan-out to
multiple subscribers, and PING/PONG keepalive. All 5 tests pass without
requiring any server changes.
2026-02-22 20:32:16 -05:00
Joseph Doherty
1bc6870238 feat: implement NatsServer orchestrator with accept loop and message routing 2026-02-22 20:27:31 -05:00
Joseph Doherty
8db2de37cd feat: implement NatsClient connection handler with read/write pipeline 2026-02-22 20:24:35 -05:00
Joseph Doherty
c78dc67973 feat: implement NATS protocol parser with System.IO.Pipelines
Add NatsParser that reads NATS protocol commands from
ReadOnlySequence<byte>. Identifies commands by first 2 bytes using
case-insensitive bit masking. Handles PUB/HPUB payload reading with
stateful _awaitingPayload for split-packet scenarios. Uses Span<Range>
for zero-allocation argument splitting and ParseSize for ASCII decimal
parsing. Includes CommandType enum, ParsedCommand struct, and
ProtocolViolationException.

14 tests covering PING, PONG, CONNECT, INFO, SUB (with/without queue),
UNSUB (with/without max), PUB (with/without reply, zero payload),
HPUB, multiple commands, and case insensitivity.
2026-02-22 20:19:37 -05:00
Joseph Doherty
afc419ce3f feat: implement SubList trie with wildcard matching and cache 2026-02-22 20:07:35 -05:00
Joseph Doherty
270ab27ce3 feat: add Subscription types and subject validation with wildcard matching 2026-02-22 19:53:49 -05:00
Joseph Doherty
05b07407a8 feat: scaffold solution with NATS.Server library, host, and test projects 2026-02-22 19:48:44 -05:00