willardf / Hazel-Networking

Hazel Networking is a low level networking library for C# providing connection-oriented, message-based communication via RUDP.
MIT License
391 stars 60 forks source link

Alternative fix for managing HMAC-per-thread with synchronized key #32

Closed Mukikaizoku closed 2 years ago

Mukikaizoku commented 2 years ago

Context: The HMAC object is not thread-safe, but having only one HMAC object across n-threads requires locking during a frequent operation during handshake, so alternative approaches that manage an HMAC object per thread were explored. This solution provides an alternative to using the [ThreadStatic] attribute, which creates some problems during disposal and key synchronization.

Proposed Solution: A helper class was added to manage the responsibility of HMAC objects and their thread distribution. The helper: -Provides simple properties for accessing the calling thread's current HMAC objects -Lazily initializes the thread's HMAC objects -HMAC getters are lockless in the general case (CurrentDictionary reads) -Manages key rotation with a timer -Key generation uses cryptographically safe random and synchronized across all threads -Dispose is thread-safe*

*My only critique is that, to prevent locking, I had to add another hmac rotation hmacToDispose as a thread might be using a previousHmac while a key rotation is happening (so we can't call previousHmac.Dispose() during rotation). However and regardless, this assumes that the calling threads do not hold their references to the HMAC objects for a long time, which if they did, could lead to an ObjectDisposedException