You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@httpd.apache.org by ic...@apache.org on 2015/10/12 15:13:45 UTC
svn commit: r1708107 - in /httpd/httpd/trunk: docs/manual/mod/mod_http2.xml
modules/http2/h2_config.c modules/http2/h2_h2.c
modules/http2/h2_task_input.c modules/ssl/ssl_engine_io.c
modules/ssl/ssl_engine_kernel.c
Author: icing
Date: Mon Oct 12 13:13:45 2015
New Revision: 1708107
URL: http://svn.apache.org/viewvc?rev=1708107&view=rev
Log:
mod_ssl: performing protocol switch directly after ALPN selection, mod_http2: connection hook inits network filters to force TLS handshake, reads input only if H2Direct explicitly enabled, changes H2Direct default to off even for cleartext connections
Modified:
httpd/httpd/trunk/docs/manual/mod/mod_http2.xml
httpd/httpd/trunk/modules/http2/h2_config.c
httpd/httpd/trunk/modules/http2/h2_h2.c
httpd/httpd/trunk/modules/http2/h2_task_input.c
httpd/httpd/trunk/modules/ssl/ssl_engine_io.c
httpd/httpd/trunk/modules/ssl/ssl_engine_kernel.c
Modified: httpd/httpd/trunk/docs/manual/mod/mod_http2.xml
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/docs/manual/mod/mod_http2.xml?rev=1708107&r1=1708106&r2=1708107&view=diff
==============================================================================
--- httpd/httpd/trunk/docs/manual/mod/mod_http2.xml (original)
+++ httpd/httpd/trunk/docs/manual/mod/mod_http2.xml Mon Oct 12 13:13:45 2015
@@ -56,7 +56,7 @@
<name>H2Direct</name>
<description>H2 Direct Protocol Switch</description>
<syntax>H2Direct on|off</syntax>
- <default>H2Direct on (for non TLS)</default>
+ <default>H2Direct off</default>
<contextlist>
<context>server config</context>
<context>virtual host</context>
@@ -64,16 +64,23 @@
<usage>
<p>
- This directive toggles the usage of the HTTP/2 Direct Mode. This
+ This directive toggles the usage of the HTTP/2 Direct Mode. For https, this
should be used inside a
<directive module="core" type="section">VirtualHost</directive>
- section to enable direct HTTP/2 communication for that virtual host.
+ section to enable direct HTTP/2 communication for that virtual host. For
+ http, this directive only works in server configurations.
+ </p>
+ <p>
Direct communication means that if the first bytes received by the
server on a connection match the HTTP/2 preamble, the HTTP/2
protocol is switched to immediately without further negotiation.
This mode falls outside the RFC 7540 but has become widely implemented
- as it is very convenient for development and testing.
- By default the direct HTTP/2 mode is enabled.
+ on cleartext ports as it is very convenient for development and testing.
+ </p>
+ <p>
+ Since this detection implies that the client will send data on
+ new connection immediately, direct HTTP/2 mode is disabled by
+ default.
</p>
<example><title>Example</title>
<highlight language="config">
Modified: httpd/httpd/trunk/modules/http2/h2_config.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/http2/h2_config.c?rev=1708107&r1=1708106&r2=1708107&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/http2/h2_config.c (original)
+++ httpd/httpd/trunk/modules/http2/h2_config.c Mon Oct 12 13:13:45 2015
@@ -47,7 +47,7 @@ static h2_config defconf = {
NULL, /* no alt-svcs */
-1, /* alt-svc max age */
0, /* serialize headers */
- -1, /* h2 direct mode */
+ 0, /* h2 direct mode */
-1, /* # session extra files */
};
Modified: httpd/httpd/trunk/modules/http2/h2_h2.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/http2/h2_h2.c?rev=1708107&r1=1708106&r2=1708107&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/http2/h2_h2.c (original)
+++ httpd/httpd/trunk/modules/http2/h2_h2.c Mon Oct 12 13:13:45 2015
@@ -135,7 +135,7 @@ int h2_h2_process_conn(conn_rec* c)
{
h2_ctx *ctx = h2_ctx_get(c);
h2_config *cfg = h2_config_get(c);
- apr_bucket_brigade* temp;
+ apr_bucket_brigade* temp = NULL;
int is_tls = h2_h2_is_tls(c);
ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, c, "h2_h2, process_conn");
@@ -150,11 +150,14 @@ int h2_h2_process_conn(conn_rec* c)
*/
if (!h2_ctx_protocol_get(c)
&& !strcmp(AP_PROTOCOL_HTTP1, ap_get_protocol(c))) {
- apr_status_t status;
+ apr_status_t status = APR_SUCCESS;
- temp = apr_brigade_create(c->pool, c->bucket_alloc);
- status = ap_get_brigade(c->input_filters, temp,
- AP_MODE_SPECULATIVE, APR_BLOCK_READ, 24);
+ if (is_tls) {
+ /* trigger the TLS handshake */
+ temp = apr_brigade_create(c->pool, c->bucket_alloc);
+ status = ap_get_brigade(c->input_filters, temp,
+ AP_MODE_INIT, APR_BLOCK_READ, 0);
+ }
if (status == APR_SUCCESS) {
if (h2_ctx_protocol_get(c)
@@ -166,30 +169,43 @@ int h2_h2_process_conn(conn_rec* c)
* http/1.1. Check the actual bytes read for the H2 Magic
* Token, *if* H2Direct mode is enabled here.
*/
- int direct_mode = h2_config_geti(cfg, H2_CONF_DIRECT);
- if (direct_mode > 0 || (direct_mode < 0 && !is_tls)) {
+ if (h2_config_geti(cfg, H2_CONF_DIRECT) > 0) {
char *s = NULL;
apr_size_t slen;
- apr_brigade_pflatten(temp, &s, &slen, c->pool);
- if ((slen >= 24) && !memcmp(H2_MAGIC_TOKEN, s, 24)) {
- ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, c,
- "h2_h2, direct mode detected");
- h2_ctx_protocol_set(ctx, is_tls? "h2" : "h2c");
+ if (!temp) {
+ temp = apr_brigade_create(c->pool, c->bucket_alloc);
+ }
+ status = ap_get_brigade(c->input_filters, temp,
+ AP_MODE_SPECULATIVE, APR_BLOCK_READ, 24);
+ if (status == APR_SUCCESS) {
+ apr_brigade_pflatten(temp, &s, &slen, c->pool);
+ if ((slen >= 24) && !memcmp(H2_MAGIC_TOKEN, s, 24)) {
+ ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, c,
+ "h2_h2, direct mode detected");
+ h2_ctx_protocol_set(ctx, is_tls? "h2" : "h2c");
+ }
+ else {
+ ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, c,
+ "h2_h2, not detected in %d bytes: %s",
+ (int)slen, s);
+ }
}
else {
- ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, c,
- "h2_h2, not detected in %d bytes: %s",
- (int)slen, s);
+ ap_log_cerror(APLOG_MARK, APLOG_DEBUG, status, c,
+ "h2_h2, error reading 24 bytes speculative");
}
}
}
}
else {
ap_log_cerror(APLOG_MARK, APLOG_DEBUG, status, c,
- "h2_h2, error reading 24 bytes speculative");
+ "h2_h2, failed to init connection");
+ }
+
+ if (temp) {
+ apr_brigade_destroy(temp);
}
- apr_brigade_destroy(temp);
}
/* If "h2" was selected as protocol (by whatever mechanism), take over
Modified: httpd/httpd/trunk/modules/http2/h2_task_input.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/http2/h2_task_input.c?rev=1708107&r1=1708106&r2=1708107&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/http2/h2_task_input.c (original)
+++ httpd/httpd/trunk/modules/http2/h2_task_input.c Mon Oct 12 13:13:45 2015
@@ -116,7 +116,7 @@ apr_status_t h2_task_input_read(h2_task_
}
if (mode == AP_MODE_INIT) {
- return APR_SUCCESS;
+ return ap_get_brigade(f->c->input_filters, bb, mode, block, readbytes);
}
if (input->bb) {
Modified: httpd/httpd/trunk/modules/ssl/ssl_engine_io.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/ssl/ssl_engine_io.c?rev=1708107&r1=1708106&r2=1708107&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/ssl/ssl_engine_io.c (original)
+++ httpd/httpd/trunk/modules/ssl/ssl_engine_io.c Mon Oct 12 13:13:45 2015
@@ -336,9 +336,6 @@ typedef struct {
apr_pool_t *pool;
char buffer[AP_IOBUFSIZE];
ssl_filter_ctx_t *filter_ctx;
-#ifdef HAVE_TLS_ALPN
- int alpn_finished; /* 1 if ALPN has finished, 0 otherwise */
-#endif
} bio_filter_in_ctx_t;
/*
@@ -1493,41 +1490,6 @@ static apr_status_t ssl_io_filter_input(
APR_BRIGADE_INSERT_TAIL(bb, bucket);
}
-#ifdef HAVE_TLS_ALPN
- /* By this point, Application-Layer Protocol Negotiation (ALPN) should be
- * completed (if our version of OpenSSL supports it). If we haven't already,
- * find out which protocol was decided upon and inform other modules
- * by calling running protocol_switch hook.
- */
- if (!inctx->alpn_finished) {
- SSLConnRec *sslconn = myConnConfig(f->c);
- const unsigned char *next_proto = NULL;
- unsigned next_proto_len = 0;
- const char *protocol;
-
- SSL_get0_alpn_selected(inctx->ssl, &next_proto, &next_proto_len);
- if (next_proto && next_proto_len) {
- protocol = apr_pstrmemdup(f->c->pool, (const char *)next_proto,
- next_proto_len);
- ap_log_cerror(APLOG_MARK, APLOG_DEBUG, APR_SUCCESS, f->c,
- APLOGNO(02836) "ALPN selected protocol: '%s'",
- protocol);
-
- if (strcmp(protocol, ap_get_protocol(f->c))) {
- status = ap_switch_protocol(f->c, NULL, sslconn->server,
- protocol);
- if (status != APR_SUCCESS) {
- ap_log_cerror(APLOG_MARK, APLOG_ERR, status, f->c,
- APLOGNO(02908) "protocol switch to '%s' failed",
- protocol);
- return status;
- }
- }
- }
- inctx->alpn_finished = 1;
- }
-#endif
-
return APR_SUCCESS;
}
@@ -2008,9 +1970,6 @@ static void ssl_io_input_add_filter(ssl_
inctx->block = APR_BLOCK_READ;
inctx->pool = c->pool;
inctx->filter_ctx = filter_ctx;
-#ifdef HAVE_TLS_ALPN
- inctx->alpn_finished = 0;
-#endif
}
/* The request_rec pointer is passed in here only to ensure that the
Modified: httpd/httpd/trunk/modules/ssl/ssl_engine_kernel.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/ssl/ssl_engine_kernel.c?rev=1708107&r1=1708106&r2=1708107&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/ssl/ssl_engine_kernel.c (original)
+++ httpd/httpd/trunk/modules/ssl/ssl_engine_kernel.c Mon Oct 12 13:13:45 2015
@@ -2210,14 +2210,30 @@ int ssl_callback_alpn_select(SSL *ssl,
init_vhost(c, ssl);
proposed = ap_select_protocol(c, NULL, sslconn->server, client_protos);
- *out = (const unsigned char *)(proposed? proposed : ap_get_protocol(c));
- len = strlen((const char*)*out);
+ if (!proposed) {
+ proposed = ap_get_protocol(c);
+ }
+
+ len = strlen(proposed);
if (len > 255) {
ap_log_cerror(APLOG_MARK, APLOG_ERR, 0, c, APLOGNO(02840)
"ALPN negotiated protocol name too long");
return SSL_TLSEXT_ERR_ALERT_FATAL;
}
+ *out = (const unsigned char *)proposed;
*outlen = (unsigned char)len;
+
+ if (strcmp(proposed, ap_get_protocol(c))) {
+ apr_status_t status;
+
+ status = ap_switch_protocol(c, NULL, sslconn->server, proposed);
+ if (status != APR_SUCCESS) {
+ ap_log_cerror(APLOG_MARK, APLOG_ERR, status, c,
+ APLOGNO(02908) "protocol switch to '%s' failed",
+ proposed);
+ return SSL_TLSEXT_ERR_ALERT_FATAL;
+ }
+ }
return SSL_TLSEXT_ERR_OK;
}