in native/src/sslutils.c [432:485]
int select_next_proto(SSL *ssl, const unsigned char **out, unsigned char *outlen,
const unsigned char *in, unsigned int inlen, unsigned char *supported_protos,
unsigned int supported_protos_len, int failure_behavior) {
unsigned int i = 0;
unsigned char target_proto_len;
const unsigned char *p;
const unsigned char *end;
const unsigned char *proto;
unsigned char proto_len = '\0';
while (i < supported_protos_len) {
target_proto_len = *supported_protos;
++supported_protos;
p = in;
end = in + inlen;
while (p < end) {
proto_len = *p;
proto = ++p;
if (proto + proto_len <= end && target_proto_len == proto_len &&
memcmp(supported_protos, proto, proto_len) == 0) {
// We found a match, so set the output and return with OK!
*out = proto;
*outlen = proto_len;
return SSL_TLSEXT_ERR_OK;
}
// Move on to the next protocol.
p += proto_len;
}
// increment len and pointers.
i += target_proto_len;
supported_protos += target_proto_len;
}
if (supported_protos_len > 0 && inlen > 0 && failure_behavior == SSL_SELECTOR_FAILURE_CHOOSE_MY_LAST_PROTOCOL) {
// There were no match but we just select our last protocol and hope the other peer support it.
//
// decrement the pointer again so the pointer points to the start of the protocol.
p -= proto_len;
*out = p;
*outlen = proto_len;
return SSL_TLSEXT_ERR_OK;
}
// TODO: OpenSSL currently not support to fail with fatal error. Once this changes we can also support it here.
// Issue https://github.com/openssl/openssl/issues/188 has been created for this.
// Nothing matched so not select anything and just accept.
return SSL_TLSEXT_ERR_NOACK;
}