123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154 |
- #include "private-libwebsockets.h"
- #ifndef LWS_NO_SERVER
- #ifdef LWS_OPENSSL_SUPPORT
- #if OPENSSL_VERSION_NUMBER >= 0x10002000L
- struct alpn_ctx {
- unsigned char *data;
- unsigned short len;
- };
- static int
- npn_cb(SSL *s, const unsigned char **data, unsigned int *len, void *arg)
- {
- struct alpn_ctx *alpn_ctx = arg;
- lwsl_info("%s\n", __func__);
- *data = alpn_ctx->data;
- *len = alpn_ctx->len;
- return SSL_TLSEXT_ERR_OK;
- }
- static int
- alpn_cb(SSL *s, const unsigned char **out, unsigned char *outlen,
- const unsigned char *in, unsigned int inlen, void *arg)
- {
- struct alpn_ctx *alpn_ctx = arg;
- if (SSL_select_next_proto((unsigned char **)out, outlen, alpn_ctx->data,
- alpn_ctx->len, in, inlen) !=
- OPENSSL_NPN_NEGOTIATED)
- return SSL_TLSEXT_ERR_NOACK;
- return SSL_TLSEXT_ERR_OK;
- }
- #endif
- LWS_VISIBLE void
- lws_context_init_http2_ssl(struct lws_vhost *vhost)
- {
- #if OPENSSL_VERSION_NUMBER >= 0x10002000L
- static struct alpn_ctx protos = { (unsigned char *)"\x02h2"
- "\x08http/1.1", 6 + 9 };
- SSL_CTX_set_next_protos_advertised_cb(vhost->ssl_ctx, npn_cb, &protos);
-
- SSL_CTX_set_alpn_select_cb(vhost->ssl_ctx, alpn_cb, &protos);
- lwsl_notice(" HTTP2 / ALPN enabled\n");
- #else
- lwsl_notice(
- " HTTP2 / ALPN configured but not supported by OpenSSL 0x%lx\n",
- OPENSSL_VERSION_NUMBER);
- #endif
- }
- void lws_http2_configure_if_upgraded(struct lws *wsi)
- {
- #if OPENSSL_VERSION_NUMBER >= 0x10002000L
- struct allocated_headers *ah;
- const char *method = "alpn";
- const unsigned char *name;
- unsigned len;
- SSL_get0_alpn_selected(wsi->ssl, &name, &len);
- if (!len) {
- SSL_get0_next_proto_negotiated(wsi->ssl, &name, &len);
- method = "npn";
- }
- if (!len) {
- lwsl_info("no npn/alpn upgrade\n");
- return;
- }
- (void)method;
- lwsl_info("negotiated %s using %s\n", name, method);
- wsi->use_ssl = 1;
- if (strncmp((char *)name, "http/1.1", 8) == 0)
- return;
-
-
- ah = wsi->u.hdr.ah;
- lws_union_transition(wsi, LWSCM_HTTP2_SERVING);
- wsi->state = LWSS_HTTP2_AWAIT_CLIENT_PREFACE;
-
- wsi->u.http.ah = ah;
- lws_http2_init(&wsi->u.http2.peer_settings);
- lws_http2_init(&wsi->u.http2.my_settings);
-
- #endif
- }
- #endif
- #endif
|