int ssl_sock_prepare_srv_ctx(struct server *srv);
void ssl_sock_free_srv_ctx(struct server *srv);
void ssl_sock_free_all_ctx(struct bind_conf *bind_conf);
+int ssl_sock_get_alpn(const struct connection *conn, void *xprt_ctx,
+ const char **str, int *len);
int ssl_sock_load_ca(struct bind_conf *bind_conf);
void ssl_sock_free_ca(struct bind_conf *bind_conf);
int ssl_bio_and_sess_init(struct connection *conn, SSL_CTX *ssl_ctx,
/* Now that we have all the flow control information, we can finalize the application
* context.
*/
- qcc->app_ops->finalize(qcc->ctx);
+ if (qcc->app_ops)
+ qcc->app_ops->finalize(qcc->ctx);
}
/* Initialize the mux once it's attached. For outgoing connections, the context
qcc->conn->qc->qcc = qcc;
/* Application layer initialization. */
- qcc->app_ops = &h3_ops;
- if (!qcc->app_ops->init(qcc))
- goto fail;
+ qcc->app_ops = NULL;
/* The transports parameters which control the data sent have been stored
* in ->tx.params. The ones which control the received data are stored in
* freed by the caller. NPN is also checked if available since older versions
* of openssl (1.0.1) which are more common in field only support this one.
*/
-static int ssl_sock_get_alpn(const struct connection *conn, void *xprt_ctx, const char **str, int *len)
+int ssl_sock_get_alpn(const struct connection *conn, void *xprt_ctx, const char **str, int *len)
{
#if defined(TLSEXT_TYPE_application_layer_protocol_negotiation) || \
defined(OPENSSL_NPN_NEGOTIATED) && !defined(OPENSSL_NO_NEXTPROTONEG)
}
}
+int ssl_sock_get_alpn(const struct connection *conn, void *xprt_ctx,
+ const char **str, int *len);
+
/* Provide CRYPTO data to the TLS stack found at <data> with <len> as length
* from <qel> encryption level with <ctx> as QUIC connection context.
* Remaining parameter are there for debugging purposes.
{
int ssl_err, state;
struct quic_conn *qc;
+ const char *alpn;
+ int alpn_len;
TRACE_ENTER(QUIC_EV_CONN_SSLDATA, ctx->conn);
ssl_err = SSL_ERROR_NONE;
QUIC_EV_CONN_HDSHK, ctx->conn, &state);
}
+ conn_get_alpn(ctx->conn, &alpn, &alpn_len);
+ if (alpn_len >= 2 && memcmp(alpn, "h3", 2) == 0) {
+ qc->qcc->app_ops = &h3_ops;
+ if (!qc->qcc->app_ops->init(qc->qcc))
+ goto err;
+ }
+ else {
+ /* TODO RFC9001 8.1. Protocol Negotiation
+ * must return no_application_protocol TLS alert
+ */
+ ABORT_NOW();
+ }
+
out:
TRACE_LEAVE(QUIC_EV_CONN_SSLDATA, ctx->conn);
return 1;
.start = qc_xprt_start,
.prepare_bind_conf = ssl_sock_prepare_bind_conf,
.destroy_bind_conf = ssl_sock_destroy_bind_conf,
+ .get_alpn = ssl_sock_get_alpn,
.name = "QUIC",
};