Heavily based on the existing NPN wrapping code. Naming of public
functions is identical to the NPN ones with `s/npn/alpn/` applied to
prevent devs from needing to remember 2 names (and to let my copy the
npn tests and perform the subistution to generate the apln tests).
It might make sense to (at some point) use macros or a trait to cut down
the duplication.
Rather than having the verification data idx generation and NPN use
there own (similar) impls to generate indexes with destructors, unify
them.
Make NPNs use of indexes more idomatic by storing the index in a
lazyref rather than having a function with static data members.
Turns out this is called with a null pointer if you never set the data
which didn't end up doing anything until the recent zeroing drop
changes.
Also use a map of indexes since statics in generic functions don't
monomorphize
If a server socket is created with a context on which the
`set_npn_protocols` method has been called, during TLS connection
establishment, the server will advertise the list of protocols given to
the method, in case the client indicates that it supports the NPN TLS
extension.
The method is added to the `Ssl` struct, since this is how the native
OpenSSL API works. It is also added to the `SslStream` convenience
struct, since the `Ssl` instance that it wraps is not public and clients
may want to check which protocol is in use on a particular SSL stream.
After the `set_npn_protocols` method of the `SslContext` struct is
called, any future TLS connections established with this context will
perform NPN negotiation.
The chosen protocol is the one with the highest priority in the
server's protocol list that is also in the client's protocol list.
(This is the default behavior provided by OpenSSL's
`SSL_select_next_proto` function.)
If there is no overlap between the two lists, no error is raised.
A new method `set_npn_protocols` is added to the `SslContext` struct,
when the `npn` feature is enabled.
The method takes a list of protocols that are supported by the peer.
These protocols will be used during Next Protocol Negotiation.
The method saves the given list within the extra data of the OpenSSL
Context structure, so that the list can be referred to later on by the
callbacks invoked during TLS connection establishment.