# Nalix Nalix is a modular, high-performance networking framework for .NET 10 designed for building real-time server applications. It provides a complete stack from low-level transport (TCP/UDP) to middleware pipelines, packet routing, and client SDKs, with a focus on zero-allocation hot paths, pluggable protocols, and enterprise-grade security featuring AEAD encryption (ChaCha20-Poly1305, Salsa20-Poly1305), X25519 key exchange, and zero-RTT session resumption. The framework follows SOLID principles and Domain-Driven Design patterns, offering attribute-based packet routing, auto-discovered controllers, fluent builder APIs, and built-in middleware for authentication, rate limiting, traffic shaping, and audit logging. Nalix leverages modern C# 14 features including `Span`, `ref struct`, and pattern matching for maximum performance on Windows, Linux, and macOS. ## NetworkApplication.CreateBuilder The `NetworkApplication` class provides a Microsoft-style builder and host for creating Nalix servers. It simplifies setup of protocols, listeners, dispatchers, and dependency injection into a single fluent flow, managing the complete lifecycle from activation through graceful shutdown. ```csharp using Microsoft.Extensions.Logging; using Nalix.Framework.DataFrames.SignalFrames; using Nalix.Framework.Memory.Buffers; using Nalix.Logging; using Nalix.Logging.Sinks; using Nalix.Network.Connections; using Nalix.Network.Hosting; using Nalix.Network.Options; // Create shared infrastructure components ConnectionHub hub = new(); BufferPoolManager buffer = new(); ILogger logger = new NLogix(cfg => cfg.RegisterTarget(new BatchConsoleLogTarget())); // Build and configure the network application using NetworkApplication host = NetworkApplication.CreateBuilder() .ConfigureLogging(logger) .ConfigureConnectionHub(hub) .ConfigureBufferPoolManager(buffer) .Configure(options => options.Port = 57206) .AddPacket() // Register packet types .AddHandler() // Register packet handlers .AddMetadataProvider() .ConfigureDispatch(dispatchOptions => { dispatchOptions.WithMiddleware(new PacketTagMiddleware()); dispatchOptions.WithErrorHandling((exception, command) => logger.Error($"Error handling command: {command}", exception)); }) .AddTcp() // Add TCP server .Build(); using CancellationTokenSource shutdown = new(); Console.CancelKeyPress += (_, e) => { e.Cancel = true; shutdown.Cancel(); }; // Run the server until cancellation await host.RunAsync(shutdown.Token); ``` ## Protocol Implementation The `Protocol` abstract class serves as the transport-protocol base for TCP listeners, handling connection validation, inbound frame processing, and post-processing logic. Custom protocols should remain thin, delegating business logic to packet handlers and middleware. ```csharp using Nalix.Common.Networking; using Nalix.Network.Protocols; using Nalix.Runtime.Dispatching; public sealed class ExamplePacketProtocol : Protocol { private readonly IPacketDispatch _packetDispatch; public ExamplePacketProtocol(IPacketDispatch packetDispatch) { _packetDispatch = packetDispatch ?? throw new ArgumentNullException(nameof(packetDispatch)); this.IsAccepting = true; this.KeepConnectionOpen = true; } // Process inbound packets for a live connection public override void ProcessMessage(object? sender, IConnectEventArgs args) { ArgumentNullException.ThrowIfNull(args); if (args.Lease is null) return; // Delegate to packet dispatch pipeline for validation, middleware, and routing _packetDispatch.HandlePacket(args.Lease, args.Connection); } // Validate connections before acceptance protected override bool ValidateConnection(IConnection connection) => true; // Post-processing hook after packet handling protected override void OnPostProcess(IConnectEventArgs args) { } // Handle protocol-level errors protected override void OnConnectionError(IConnection connection, Exception exception) => base.OnConnectionError(connection, exception); } ``` ## PacketController and Handler Attributes Nalix uses attributes to declare packet handler routing and execution policies. Controllers are marked with `[PacketController]` and methods are bound to opcodes with policy attributes for permissions, rate limiting, concurrency, encryption, and timeouts. ```csharp using Nalix.Common.Networking.Packets; using Nalix.Common.Security; using Nalix.Framework.DataFrames.SignalFrames; [PacketController("SecureChat", version: "1.2")] public sealed class SecureChatController { // Handler with full policy configuration [PacketOpcode(0x3001)] [PacketPermission(PermissionLevel.USER)] [PacketRateLimit(10, burst: 2)] [PacketConcurrencyLimit(100, queue: true, queueMax: 1000)] [PacketEncryption(true)] [PacketTimeout(5000)] public static ValueTask HandleChatAsync(IPacketContext context) { // Handle encrypted chat message return ValueTask.CompletedTask; } // Simple ping handler without encryption [PacketOpcode(100)] [PacketEncryption(false)] [PacketPermission(PermissionLevel.NONE)] public static async Task Ping(IPacketContext context) { ArgumentNullException.ThrowIfNull(context); await context.Sender.SendAsync(context.Packet).ConfigureAwait(false); } // Generic packet handler [PacketOpcode(101)] [PacketEncryption(false)] [PacketPermission(PermissionLevel.NONE)] public static async Task Pong(IPacketContext context) { ArgumentNullException.ThrowIfNull(context); await context.Sender.SendAsync(context.Packet).ConfigureAwait(false); } } ``` ## LiteSerializer `LiteSerializer` provides zero-allocation serialization for primitives, collections, and automatic class/struct serialization. It supports unmanaged types, nullable values, arrays, lists, dictionaries, and auto-generated formatters for custom types. ```csharp using Nalix.Framework.Serialization; // Serialize and deserialize a model public class MyModel { public int Id { get; set; } public string Name { get; set; } public DateTime Created { get; set; } } MyModel model = new() { Id = 42, Name = "Test", Created = DateTime.UtcNow }; // Serialize to bytes byte[] bytes = LiteSerializer.Serialize(model); // Deserialize back MyModel clone = LiteSerializer.Deserialize(bytes, out int bytesRead); // Work with spans for zero-allocation paths ReadOnlySpan data = bytes; MyModel fromSpan = LiteSerializer.Deserialize(data, out int read); // Get formatter for lower-level control IFormatter formatter = FormatterProvider.Get(); // Register custom formatter LiteSerializer.Register(new MyCustomFormatter()); ``` ## BufferLease and BufferPoolManager `BufferLease` provides pooled byte storage for receive/send paths, minimizing allocations on hot network paths. `BufferPoolManager` organizes memory into size-aligned buckets with diagnostic reporting and adaptive trimming. ```csharp using Nalix.Framework.Memory.Buffers; // Rent a pooled buffer using BufferLease lease = BufferLease.Rent(1024); // Copy data and commit length payload.CopyTo(lease.SpanFull); lease.CommitLength(payload.Length); // Access data ReadOnlyMemory memory = lease.Memory; ReadOnlySpan span = lease.Span; // Create from existing data using BufferLease fromData = BufferLease.CopyFrom(existingSpan, zeroOnDispose: true); // Take ownership of rented array using BufferLease owned = BufferLease.TakeOwnership(rentedArray, start: 0, length: 512, zeroOnDispose: false); // BufferPoolManager for advanced scenarios BufferPoolManager poolManager = new(); byte[] buffer = poolManager.Rent(4096); poolManager.Return(buffer); // Generate diagnostic report string report = poolManager.GenerateReport(); Dictionary metrics = poolManager.GetReportData(); ``` ## ObjectPool and ObjectPoolManager `ObjectPool` provides reusable object storage for `IPoolable` instances, reducing GC pressure for frequently created objects. `ObjectPoolManager` adds reporting, health checks, and typed adapters. ```csharp using Nalix.Framework.Memory.Pools; using Nalix.Framework.Memory.Objects; // Basic object pooling MyPoolable item = ObjectPool.Default.Get(); // Use item... ObjectPool.Default.Return(item); // Preallocate objects during startup ObjectPool.Default.Prealloc(100); ObjectPool.Default.SetMaxCapacity(1000); // Get multiple objects MyPoolable[] batch = ObjectPool.Default.GetMultiple(10); ObjectPool.Default.ReturnMultiple(batch); // ObjectPoolManager for typed pools ObjectPoolManager manager = new(); var typedPool = manager.GetTypedPool(); MyPoolable obj = typedPool.Get(); typedPool.Return(obj); // Health monitoring manager.PerformHealthCheck(); manager.TrimAllPools(0.25); // Trim 25% of idle objects string report = manager.GenerateReport(); ``` ## PacketRegistry `PacketRegistry` is the immutable runtime catalog for packet type resolution and deserialization. `PacketRegistryFactory` builds the registry by scanning assemblies or registering types explicitly. ```csharp using Nalix.Framework.DataFrames; // Build packet registry PacketRegistryFactory factory = new(); factory.RegisterPacket() .RegisterPacket() .IncludeCurrentDomain() .IncludeNamespaceRecursive("MyApp.Packets"); PacketRegistry registry = factory.CreateCatalog(); // Use registry at runtime if (registry.TryDeserialize(buffer, out IPacket? packet)) { Console.WriteLine($"Opcode: {packet.OpCode}"); } // Check registration bool isKnown = registry.IsKnownMagic(magicNumber); bool isRegistered = registry.IsRegistered(); int count = registry.DeserializerCount; // Get deserializer directly if (registry.TryGetDeserializer(magic, out var deserializer)) { IPacket packet = deserializer(rawBuffer); } ``` ## EnvelopeCipher (AEAD Encryption) `EnvelopeCipher` provides high-level encryption using ChaCha20-Poly1305 or Salsa20-Poly1305 AEAD ciphers. It handles nonce generation, authenticated additional data (AAD), and envelope framing. ```csharp using Nalix.Framework.Security; // Encrypt data with ChaCha20-Poly1305 byte[] key = new byte[32]; // 256-bit key byte[] plaintext = Encoding.UTF8.GetBytes("Secret message"); byte[] aad = Encoding.UTF8.GetBytes("header"); Span ciphertext = stackalloc byte[plaintext.Length + EnvelopeCipher.HeaderSize + 32]; EnvelopeCipher.Encrypt( key, plaintext, ciphertext, aad, seq: null, algorithm: CipherSuiteType.Chacha20Poly1305, out int written); // Decrypt data Span decrypted = stackalloc byte[written]; EnvelopeCipher.Decrypt( key, ciphertext.Slice(0, written), decrypted, aad, algorithm: CipherSuiteType.Chacha20Poly1305, out int decryptedLength); // Get algorithm-specific sizes int nonceLen = EnvelopeCipher.GetNonceLength(CipherSuiteType.Chacha20Poly1305); // 12 int tagLen = EnvelopeCipher.GetTagLength(CipherSuiteType.Chacha20Poly1305); // 16 ``` ## Snowflake Identifiers `Snowflake` is a compact 56-bit identifier combining value, machine ID, and type. It's used for connection IDs, worker IDs, and system-generated identifiers. ```csharp using Nalix.Framework.Identifiers; // Generate new identifier Snowflake id = Snowflake.NewId(SnowflakeType.System); // Generate with specific values Snowflake customId = Snowflake.NewId(value: 12345, machineId: 7, SnowflakeType.System); // String representation string text = id.ToString(); // Binary serialization byte[] buffer = new byte[8]; id.TryWriteBytes(buffer); Snowflake parsed = Snowflake.FromBytes(buffer); // Equality comparison Snowflake id1 = Snowflake.NewId(SnowflakeType.Connection); Snowflake id2 = Snowflake.NewId(SnowflakeType.Connection); bool areEqual = id1 == id2; // false (different values) // Use in collections var connections = new Dictionary(); connections[id1] = myConnection; ``` ## TcpSession (Client SDK) `TcpSession` is the core TCP client transport in the SDK, handling connection lifecycle, packet serialization, framed transport, and asynchronous message dispatching. ```csharp using Nalix.SDK.Transport; using Nalix.SDK.Transport.Extensions; using Nalix.Framework.Configuration; using Nalix.Framework.Injection; // Get options and packet registry var options = ConfigurationManager.Instance.Get(); var catalog = InstanceManager.Instance.GetExistingInstance(); using var client = new TcpSession(options, catalog); // Wire up events client.OnConnected += (s, e) => Console.WriteLine("Connected!"); client.OnDisconnected += (s, e) => Console.WriteLine("Disconnected"); client.OnError += (s, e) => Console.WriteLine($"Error: {e}"); client.OnMessageReceived += (s, lease) => { using (lease) // Return buffer to pool { Console.WriteLine($"Received {lease.Length} bytes"); } }; // Connect and perform handshake await client.ConnectAsync("127.0.0.1", 57206); await client.HandshakeAsync(); // X25519 key exchange // Send packets (now encrypted) await client.SendAsync(new LoginPacket { Username = "Player1" }); // Request-response pattern var response = await client.RequestAsync( new LoginPacket { Username = "Player1" }, RequestOptions.Default.WithTimeout(5_000)); // Graceful disconnect await client.DisconnectAsync(); ``` ## Middleware Pipeline Nalix supports two middleware layers: buffer middleware (before deserialization) for decryption/decompression, and packet middleware (after deserialization) for permissions, rate limiting, and auditing. ```csharp using Nalix.Common.Middleware; using Nalix.Runtime.Middleware; // Buffer middleware for raw data processing public class DecryptionMiddleware : INetworkBufferMiddleware { public ValueTask InvokeAsync( IBufferLease buffer, IConnection connection, CancellationToken ct) { // Decrypt buffer, return modified lease var decrypted = Decrypt(buffer, connection.Secret); return ValueTask.FromResult(decrypted); } } // Packet middleware for typed packet processing public class AuditMiddleware : IPacketMiddleware { public async ValueTask InvokeAsync( PacketContext context, Func next) { // Pre-processing LogIncoming(context.Packet, context.Connection); // Call next middleware await next(context.CancellationToken); // Post-processing LogCompleted(context.Packet); } } // Register middleware in dispatch options builder.ConfigureDispatch(options => { options.NetworkPipeline.Use(new DecryptionMiddleware()); options.PacketPipeline.Use(new AuditMiddleware()); options.PacketPipeline.Use(new RateLimitMiddleware()); options.PacketPipeline.Use(new PermissionMiddleware()); }); ``` ## NLogix Logging `NLogix` provides high-throughput asynchronous logging with pluggable sinks, supporting console and file targets with color output and batching. ```csharp using Microsoft.Extensions.Logging; using Nalix.Logging; using Nalix.Logging.Sinks; using Nalix.Logging.Options; using Nalix.Framework.Injection; // Create logger with custom configuration NLogix logger = new(cfg => { cfg.SetMinimumLevel(LogLevel.Debug) .RegisterTarget(new BatchConsoleLogTarget(t => t.EnableColors = true)) .RegisterTarget(new BatchFileLogTarget(t => t.FilePath = "logs/app.log")); }); // Use built-in host instance NLogix hostLogger = NLogix.Host.Instance; // Log messages logger.Info("server-started"); logger.Warn("slow-handler"); logger.Error("dispatch-failed", exception); logger.Debug("connection-accepted", connectionId); // Register as shared logger InstanceManager.Instance.Register(logger); // Configure log options ConfigurationManager.Instance.Get().MinLevel = LogLevel.Trace; ``` ## X25519 Handshake The handshake protocol establishes encrypted sessions using X25519 key exchange and Keccak-256 transcript hashing. The SDK provides extension methods for automated client-side handshake. ```csharp using Nalix.SDK.Transport; using Nalix.SDK.Transport.Extensions; using Nalix.Framework.Security; // Client-side handshake using var session = new TcpSession(options, registry); await session.ConnectAsync("127.0.0.1", 5000); // Execute 4-stage X25519 handshake // 1. CLIENT_HELLO: Send ephemeral public key // 2. SERVER_HELLO: Receive server key and proof // 3. CLIENT_FINISH: Verify server and send client proof // 4. SERVER_FINISH: Receive session token await session.HandshakeAsync(cancellationToken); // Session is now encrypted with ChaCha20-Poly1305 // All subsequent packets are automatically encrypted await session.SendAsync(new SecurePacket { Data = "encrypted" }); // Server-side handshake is handled automatically by HandshakeHandlers // when Handshake packets are registered in the packet registry ``` ## Connection Management `Connection` provides session-level abstraction around transport, identity, security state, and lifecycle events. `ConnectionHub` manages active connections and session persistence. ```csharp using Nalix.Network.Connections; using Nalix.Common.Networking; // Create connection hub ConnectionHub hub = new(); // Access connection properties IConnection connection = args.Connection; Snowflake id = connection.ID; EndPoint endpoint = connection.NetworkEndpoint; // Security state PermissionLevel level = connection.Level; CipherSuiteType algorithm = connection.Algorithm; byte[] secret = connection.Secret; // Metrics long bytesSent = connection.BytesSent; TimeSpan uptime = connection.UpTime; DateTime lastPing = connection.LastPingTime; int errors = connection.ErrorCount; // Per-session attributes connection.Attributes["userId"] = userId; connection.Attributes["nalix.handshake.established"] = true; // Events connection.OnCloseEvent += (s, e) => Console.WriteLine("Closing"); connection.OnProcessEvent += (s, e) => ProcessPacket(e); // Lifecycle connection.Close(DisconnectReason.Normal); connection.Disconnect(ProtocolReason.TIMEOUT); connection.Dispose(); // Connection hub operations var allConnections = hub.GetConnections(); hub.BroadcastAsync(packet); ``` ## Summary Nalix provides a comprehensive toolkit for building high-performance real-time server applications in .NET 10. Key integration patterns include: using `NetworkApplication.CreateBuilder()` for fluent server configuration; implementing thin `Protocol` subclasses that delegate to `IPacketDispatch`; decorating handlers with policy attributes like `[PacketOpcode]`, `[PacketPermission]`, and `[PacketRateLimit]`; and leveraging `BufferLease` and `ObjectPool` for zero-allocation hot paths. The security stack offers enterprise-grade encryption with X25519 handshakes and ChaCha20-Poly1305 AEAD, while the middleware pipeline enables flexible request processing with rate limiting, permission checks, and auditing. For client applications, the SDK provides `TcpSession` and `UdpSession` with automatic framing, encryption, and request-response helpers. The `PacketRegistry` ensures consistent packet serialization between server and client, while `LiteSerializer` handles efficient binary serialization for custom types. Developers can extend the framework through custom middleware, protocols, and formatters while relying on built-in handlers for handshake, session resume, and control operations. The logging system (`NLogix`) integrates seamlessly with the .NET `ILogger` interface, providing high-throughput batched output to console and file targets.