Rewrite the majority of the packet processing logic

Introduce a request structure like we use in the server core, and use this to represent the request/response link.

This allows us to detect lost packets (where we never saw a response even after multiple requests), retransmissions where we see packets with the same src/dst parameters and request authenticator/nonce, and premature reuse of packet IDs.

This also implements the first required dequeueing scheme (previously there was none), which remove requests from the rbtree.  The second dequeuing scheme removes requests/responses immediately as soon as a response is received, and the third never bothers inserting requests/responses into the queue.

The other schemes need to be implemented later, and specified by the user for individual packet types.