The current locking mechanism (global read-write spinlock) works fine for client (since almost all operations are read-only, such as encrypt/decrypt) but doesn't scale well for multipeer, since amount of state-modifying operations (add/remove peer, modify keys) increases a lot. Instead of a single lock:
Use a global spinlock when accessing peers tables (by peer-id, by vpn4 and vpn6 addresses). Acquire for shared access for lookup and for exclusive access when modifying the tables. After lookup, increment peer reference counter and return a pointer to a peer context.
When doing read-only operation on a peer, acquire peer-specific spinlock for shared access. For state-modifying operation, acquire peer-specific spinlock for exclusive access.
After finishing operations on a peer, decrement peer reference counter.
If after decrement peer reference counter is zero, free peer context.
This approach reduces contention and ensures that peer context won't be deleted during peer-specific operation.
The current locking mechanism (global read-write spinlock) works fine for client (since almost all operations are read-only, such as encrypt/decrypt) but doesn't scale well for multipeer, since amount of state-modifying operations (add/remove peer, modify keys) increases a lot. Instead of a single lock:
This approach reduces contention and ensures that peer context won't be deleted during peer-specific operation.