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/11/04 16:45:25 UTC
svn commit: r1712570 [11/13] - in /httpd/httpd/branches/2.4-http2-alpha: ./
docs/conf/ docs/manual/mod/ include/ modules/cache/ modules/http2/
modules/ssl/ server/
Modified: httpd/httpd/branches/2.4-http2-alpha/include/ap_mmn.h
URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.4-http2-alpha/include/ap_mmn.h?rev=1712570&r1=1712569&r2=1712570&view=diff
==============================================================================
--- httpd/httpd/branches/2.4-http2-alpha/include/ap_mmn.h (original)
+++ httpd/httpd/branches/2.4-http2-alpha/include/ap_mmn.h Wed Nov 4 15:44:24 2015
@@ -456,6 +456,7 @@
* ap_select_protocol(), ap_switch_protocol(),
* ap_get_protocol(). Add HTTP_MISDIRECTED_REQUEST.
* Added ap_parse_token_list_strict() to httpd.h
+ * 20120211.52 (2.4.17-dev) Add master conn_rec* member in conn_rec.
*/
#define MODULE_MAGIC_COOKIE 0x41503234UL /* "AP24" */
@@ -463,7 +464,7 @@
#ifndef MODULE_MAGIC_NUMBER_MAJOR
#define MODULE_MAGIC_NUMBER_MAJOR 20120211
#endif
-#define MODULE_MAGIC_NUMBER_MINOR 51 /* 0...n */
+#define MODULE_MAGIC_NUMBER_MINOR 52 /* 0...n */
/**
* Determine if the server's current MODULE_MAGIC_NUMBER is at least a
Modified: httpd/httpd/branches/2.4-http2-alpha/include/http_core.h
URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.4-http2-alpha/include/http_core.h?rev=1712570&r1=1712569&r2=1712570&view=diff
==============================================================================
--- httpd/httpd/branches/2.4-http2-alpha/include/http_core.h (original)
+++ httpd/httpd/branches/2.4-http2-alpha/include/http_core.h Wed Nov 4 15:44:24 2015
@@ -465,6 +465,17 @@ typedef unsigned long etag_components_t;
/* This is the default value used */
#define ETAG_BACKWARD (ETAG_MTIME | ETAG_SIZE)
+/* Generic ON/OFF/UNSET for unsigned int foo :2 */
+#define AP_CORE_CONFIG_OFF (0)
+#define AP_CORE_CONFIG_ON (1)
+#define AP_CORE_CONFIG_UNSET (2)
+
+/* Generic merge of flag */
+#define AP_CORE_MERGE_FLAG(field, to, base, over) to->field = \
+ over->field != AP_CORE_CONFIG_UNSET \
+ ? over->field \
+ : base->field
+
/**
* @brief Server Signature Enumeration
*/
@@ -630,6 +641,8 @@ typedef struct {
* advice
*/
unsigned int cgi_pass_auth : 2;
+ unsigned int qualify_redirect_url :2;
+
} core_dir_config;
/* macro to implement off by default behaviour */
Modified: httpd/httpd/branches/2.4-http2-alpha/include/http_protocol.h
URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.4-http2-alpha/include/http_protocol.h?rev=1712570&r1=1712569&r2=1712570&view=diff
==============================================================================
--- httpd/httpd/branches/2.4-http2-alpha/include/http_protocol.h (original)
+++ httpd/httpd/branches/2.4-http2-alpha/include/http_protocol.h Wed Nov 4 15:44:24 2015
@@ -782,7 +782,27 @@ AP_DECLARE_HOOK(int,protocol_switch,(con
* @return The identifier of the protocol in place or NULL
*/
AP_DECLARE_HOOK(const char *,protocol_get,(const conn_rec *c))
-
+
+/**
+ * Get the protocols that the connection and optional request may
+ * upgrade to - besides the protocol currently active on the connection. These
+ * values may be used to announce to a client what choices it has.
+ *
+ * If report_all == 0, only protocols more preferable than the one currently
+ * being used, are reported. Otherwise, all available protocols beside the
+ * current one are being reported.
+ *
+ * @param c The current connection
+ * @param r The current request or NULL
+ * @param s The server/virtual host selected or NULL
+ * @param report_all include also protocols less preferred than the current one
+ * @param pupgrades on return, possible protocols to upgrade to in descending order
+ * of preference. Maybe NULL if none are available.
+ */
+AP_DECLARE(apr_status_t) ap_get_protocol_upgrades(conn_rec *c, request_rec *r,
+ server_rec *s, int report_all,
+ const apr_array_header_t **pupgrades);
+
/**
* Select a protocol for the given connection and optional request. Will return
* the protocol identifier selected which may be the protocol already in place
@@ -833,6 +853,23 @@ AP_DECLARE(apr_status_t) ap_switch_proto
*/
AP_DECLARE(const char *) ap_get_protocol(conn_rec *c);
+/**
+ * Check if the given protocol is an allowed choice on the given
+ * combination of connection, request and server.
+ *
+ * When server is NULL, it is taken from request_rec, unless
+ * request_rec is NULL. Then it is taken from the connection base
+ * server.
+ *
+ * @param c The current connection
+ * @param r The current request or NULL
+ * @param s The server/virtual host selected or NULL
+ * @param protocol the protocol to switch to
+ * @return != 0 iff protocol is allowed
+ */
+AP_DECLARE(int) ap_is_allowed_protocol(conn_rec *c, request_rec *r,
+ server_rec *s, const char *protocol);
+
/** @see ap_bucket_type_error */
typedef struct ap_bucket_error ap_bucket_error;
Modified: httpd/httpd/branches/2.4-http2-alpha/include/httpd.h
URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.4-http2-alpha/include/httpd.h?rev=1712570&r1=1712569&r2=1712570&view=diff
==============================================================================
--- httpd/httpd/branches/2.4-http2-alpha/include/httpd.h (original)
+++ httpd/httpd/branches/2.4-http2-alpha/include/httpd.h Wed Nov 4 15:44:24 2015
@@ -1167,6 +1167,9 @@ struct conn_rec {
#if APR_HAS_THREADS
apr_thread_t *current_thread;
#endif
+
+ /** The "real" master connection. NULL if I am the master. */
+ conn_rec *master;
};
/**
Modified: httpd/httpd/branches/2.4-http2-alpha/modules/cache/cache_util.h
URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.4-http2-alpha/modules/cache/cache_util.h?rev=1712570&r1=1712569&r2=1712570&view=diff
==============================================================================
--- httpd/httpd/branches/2.4-http2-alpha/modules/cache/cache_util.h (original)
+++ httpd/httpd/branches/2.4-http2-alpha/modules/cache/cache_util.h Wed Nov 4 15:44:24 2015
@@ -99,7 +99,7 @@ extern "C" {
#define CACHE_LOCKNAME_KEY "mod_cache-lockname"
#define CACHE_LOCKFILE_KEY "mod_cache-lockfile"
#define CACHE_CTX_KEY "mod_cache-ctx"
-#define CACHE_SEPARATOR ", "
+#define CACHE_SEPARATOR ", \t"
/**
* cache_util.c
Modified: httpd/httpd/branches/2.4-http2-alpha/modules/http2/config.m4
URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.4-http2-alpha/modules/http2/config.m4?rev=1712570&r1=1712569&r2=1712570&view=diff
==============================================================================
--- httpd/httpd/branches/2.4-http2-alpha/modules/http2/config.m4 (original)
+++ httpd/httpd/branches/2.4-http2-alpha/modules/http2/config.m4 Wed Nov 4 15:44:24 2015
@@ -20,6 +20,8 @@ dnl # list of module object files
http2_objs="dnl
mod_http2.lo dnl
h2_alt_svc.lo dnl
+h2_bucket_eoc.lo dnl
+h2_bucket_eos.lo dnl
h2_config.lo dnl
h2_conn.lo dnl
h2_conn_io.lo dnl
Modified: httpd/httpd/branches/2.4-http2-alpha/modules/http2/h2_config.c
URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.4-http2-alpha/modules/http2/h2_config.c?rev=1712570&r1=1712569&r2=1712570&view=diff
==============================================================================
--- httpd/httpd/branches/2.4-http2-alpha/modules/http2/h2_config.c (original)
+++ httpd/httpd/branches/2.4-http2-alpha/modules/http2/h2_config.c Wed Nov 4 15:44:24 2015
@@ -49,6 +49,10 @@ static h2_config defconf = {
0, /* serialize headers */
-1, /* h2 direct mode */
-1, /* # session extra files */
+ 1, /* modern TLS only */
+ -1, /* HTTP/1 Upgrade support */
+ 1024*1024, /* TLS warmup size */
+ 1, /* TLS cooldown secs */
};
static int files_per_session = 0;
@@ -100,6 +104,11 @@ static void *h2_config_create(apr_pool_t
conf->serialize_headers = DEF_VAL;
conf->h2_direct = DEF_VAL;
conf->session_extra_files = DEF_VAL;
+ conf->modern_tls_only = DEF_VAL;
+ conf->h2_upgrade = DEF_VAL;
+ conf->tls_warmup_size = DEF_VAL;
+ conf->tls_cooldown_secs = DEF_VAL;
+
return conf;
}
@@ -127,23 +136,32 @@ void *h2_config_merge(apr_pool_t *pool,
strcat(name, "]");
n->name = name;
- n->h2_max_streams = H2_CONFIG_GET(add, base, h2_max_streams);
- n->h2_window_size = H2_CONFIG_GET(add, base, h2_window_size);
- n->min_workers = H2_CONFIG_GET(add, base, min_workers);
- n->max_workers = H2_CONFIG_GET(add, base, max_workers);
+ n->h2_max_streams = H2_CONFIG_GET(add, base, h2_max_streams);
+ n->h2_window_size = H2_CONFIG_GET(add, base, h2_window_size);
+ n->min_workers = H2_CONFIG_GET(add, base, min_workers);
+ n->max_workers = H2_CONFIG_GET(add, base, max_workers);
n->max_worker_idle_secs = H2_CONFIG_GET(add, base, max_worker_idle_secs);
- n->stream_max_mem_size = H2_CONFIG_GET(add, base, stream_max_mem_size);
- n->alt_svcs = add->alt_svcs? add->alt_svcs : base->alt_svcs;
- n->alt_svc_max_age = H2_CONFIG_GET(add, base, alt_svc_max_age);
- n->serialize_headers = H2_CONFIG_GET(add, base, serialize_headers);
- n->h2_direct = H2_CONFIG_GET(add, base, h2_direct);
- n->session_extra_files = H2_CONFIG_GET(add, base, session_extra_files);
+ n->stream_max_mem_size = H2_CONFIG_GET(add, base, stream_max_mem_size);
+ n->alt_svcs = add->alt_svcs? add->alt_svcs : base->alt_svcs;
+ n->alt_svc_max_age = H2_CONFIG_GET(add, base, alt_svc_max_age);
+ n->serialize_headers = H2_CONFIG_GET(add, base, serialize_headers);
+ n->h2_direct = H2_CONFIG_GET(add, base, h2_direct);
+ n->session_extra_files = H2_CONFIG_GET(add, base, session_extra_files);
+ n->modern_tls_only = H2_CONFIG_GET(add, base, modern_tls_only);
+ n->h2_upgrade = H2_CONFIG_GET(add, base, h2_upgrade);
+ n->tls_warmup_size = H2_CONFIG_GET(add, base, tls_warmup_size);
+ n->tls_cooldown_secs = H2_CONFIG_GET(add, base, tls_cooldown_secs);
return n;
}
int h2_config_geti(h2_config *conf, h2_config_var_t var)
{
+ return (int)h2_config_geti64(conf, var);
+}
+
+apr_int64_t h2_config_geti64(h2_config *conf, h2_config_var_t var)
+{
int n;
switch(var) {
case H2_CONF_MAX_STREAMS:
@@ -162,6 +180,10 @@ int h2_config_geti(h2_config *conf, h2_c
return H2_CONFIG_GET(conf, &defconf, alt_svc_max_age);
case H2_CONF_SER_HEADERS:
return H2_CONFIG_GET(conf, &defconf, serialize_headers);
+ case H2_CONF_MODERN_TLS_ONLY:
+ return H2_CONFIG_GET(conf, &defconf, modern_tls_only);
+ case H2_CONF_UPGRADE:
+ return H2_CONFIG_GET(conf, &defconf, h2_upgrade);
case H2_CONF_DIRECT:
return H2_CONFIG_GET(conf, &defconf, h2_direct);
case H2_CONF_SESSION_FILES:
@@ -170,6 +192,10 @@ int h2_config_geti(h2_config *conf, h2_c
n = files_per_session;
}
return n;
+ case H2_CONF_TLS_WARMUP_SIZE:
+ return H2_CONFIG_GET(conf, &defconf, tls_warmup_size);
+ case H2_CONF_TLS_COOLDOWN_SECS:
+ return H2_CONFIG_GET(conf, &defconf, tls_cooldown_secs);
default:
return DEF_VAL;
}
@@ -290,8 +316,8 @@ static const char *h2_conf_set_session_e
{
h2_config *cfg = h2_config_sget(parms->server);
apr_int64_t max = (int)apr_atoi64(value);
- if (max <= 0) {
- return "value must be a positive number";
+ if (max < 0) {
+ return "value must be a non-negative number";
}
cfg->session_extra_files = (int)max;
(void)arg;
@@ -332,8 +358,60 @@ static const char *h2_conf_set_direct(cm
return "value must be On or Off";
}
-#define AP_END_CMD AP_INIT_TAKE1(NULL, NULL, NULL, RSRC_CONF, NULL)
+static const char *h2_conf_set_modern_tls_only(cmd_parms *parms,
+ void *arg, const char *value)
+{
+ h2_config *cfg = h2_config_sget(parms->server);
+ if (!strcasecmp(value, "On")) {
+ cfg->modern_tls_only = 1;
+ return NULL;
+ }
+ else if (!strcasecmp(value, "Off")) {
+ cfg->modern_tls_only = 0;
+ return NULL;
+ }
+
+ (void)arg;
+ return "value must be On or Off";
+}
+static const char *h2_conf_set_upgrade(cmd_parms *parms,
+ void *arg, const char *value)
+{
+ h2_config *cfg = h2_config_sget(parms->server);
+ if (!strcasecmp(value, "On")) {
+ cfg->h2_upgrade = 1;
+ return NULL;
+ }
+ else if (!strcasecmp(value, "Off")) {
+ cfg->h2_upgrade = 0;
+ return NULL;
+ }
+
+ (void)arg;
+ return "value must be On or Off";
+}
+
+static const char *h2_conf_set_tls_warmup_size(cmd_parms *parms,
+ void *arg, const char *value)
+{
+ h2_config *cfg = h2_config_sget(parms->server);
+ cfg->tls_warmup_size = apr_atoi64(value);
+ (void)arg;
+ return NULL;
+}
+
+static const char *h2_conf_set_tls_cooldown_secs(cmd_parms *parms,
+ void *arg, const char *value)
+{
+ h2_config *cfg = h2_config_sget(parms->server);
+ cfg->tls_cooldown_secs = (int)apr_atoi64(value);
+ (void)arg;
+ return NULL;
+}
+
+
+#define AP_END_CMD AP_INIT_TAKE1(NULL, NULL, NULL, RSRC_CONF, NULL)
const command_rec h2_cmds[] = {
AP_INIT_TAKE1("H2MaxSessionStreams", h2_conf_set_max_streams, NULL,
@@ -354,10 +432,18 @@ const command_rec h2_cmds[] = {
RSRC_CONF, "set the maximum age (in seconds) that client can rely on alt-svc information"),
AP_INIT_TAKE1("H2SerializeHeaders", h2_conf_set_serialize_headers, NULL,
RSRC_CONF, "on to enable header serialization for compatibility"),
+ AP_INIT_TAKE1("H2ModernTLSOnly", h2_conf_set_modern_tls_only, NULL,
+ RSRC_CONF, "off to not impose RFC 7540 restrictions on TLS"),
+ AP_INIT_TAKE1("H2Upgrade", h2_conf_set_upgrade, NULL,
+ RSRC_CONF, "on to allow HTTP/1 Upgrades to h2/h2c"),
AP_INIT_TAKE1("H2Direct", h2_conf_set_direct, NULL,
RSRC_CONF, "on to enable direct HTTP/2 mode"),
AP_INIT_TAKE1("H2SessionExtraFiles", h2_conf_set_session_extra_files, NULL,
RSRC_CONF, "number of extra file a session might keep open"),
+ AP_INIT_TAKE1("H2TLSWarmUpSize", h2_conf_set_tls_warmup_size, NULL,
+ RSRC_CONF, "number of bytes on TLS connection before doing max writes"),
+ AP_INIT_TAKE1("H2TLSCoolDownSecs", h2_conf_set_tls_cooldown_secs, NULL,
+ RSRC_CONF, "seconds of idle time on TLS before shrinking writes"),
AP_END_CMD
};
Modified: httpd/httpd/branches/2.4-http2-alpha/modules/http2/h2_config.h
URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.4-http2-alpha/modules/http2/h2_config.h?rev=1712570&r1=1712569&r2=1712570&view=diff
==============================================================================
--- httpd/httpd/branches/2.4-http2-alpha/modules/http2/h2_config.h (original)
+++ httpd/httpd/branches/2.4-http2-alpha/modules/http2/h2_config.h Wed Nov 4 15:44:24 2015
@@ -34,6 +34,10 @@ typedef enum {
H2_CONF_SER_HEADERS,
H2_CONF_DIRECT,
H2_CONF_SESSION_FILES,
+ H2_CONF_MODERN_TLS_ONLY,
+ H2_CONF_UPGRADE,
+ H2_CONF_TLS_WARMUP_SIZE,
+ H2_CONF_TLS_COOLDOWN_SECS,
} h2_config_var_t;
/* Apache httpd module configuration for h2. */
@@ -51,6 +55,10 @@ typedef struct h2_config {
processing, better compatibility */
int h2_direct; /* if mod_h2 is active directly */
int session_extra_files; /* # of extra files a session may keep open */
+ int modern_tls_only; /* Accept only modern TLS in HTTP/2 connections */
+ int h2_upgrade; /* Allow HTTP/1 upgrade to h2/h2c */
+ apr_int64_t tls_warmup_size; /* Amount of TLS data to send before going full write size */
+ int tls_cooldown_secs; /* Seconds of idle time before going back to small TLS records */
} h2_config;
@@ -67,6 +75,7 @@ h2_config *h2_config_sget(server_rec *s)
h2_config *h2_config_rget(request_rec *r);
int h2_config_geti(h2_config *conf, h2_config_var_t var);
+apr_int64_t h2_config_geti64(h2_config *conf, h2_config_var_t var);
void h2_config_init(apr_pool_t *pool);
Modified: httpd/httpd/branches/2.4-http2-alpha/modules/http2/h2_conn.c
URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.4-http2-alpha/modules/http2/h2_conn.c?rev=1712570&r1=1712569&r2=1712570&view=diff
==============================================================================
--- httpd/httpd/branches/2.4-http2-alpha/modules/http2/h2_conn.c (original)
+++ httpd/httpd/branches/2.4-http2-alpha/modules/http2/h2_conn.c Wed Nov 4 15:44:24 2015
@@ -32,6 +32,7 @@
#include "h2_session.h"
#include "h2_stream.h"
#include "h2_stream_set.h"
+#include "h2_h2.h"
#include "h2_task.h"
#include "h2_worker.h"
#include "h2_workers.h"
@@ -43,7 +44,6 @@ static apr_status_t h2_conn_loop(h2_sess
static h2_mpm_type_t mpm_type = H2_MPM_UNKNOWN;
static module *mpm_module;
-static module *ssl_module;
static int checked;
static void check_modules(void)
@@ -64,9 +64,6 @@ static void check_modules(void)
mpm_type = H2_MPM_PREFORK;
mpm_module = m;
}
- else if (!strcmp("mod_ssl.c", m->name)) {
- ssl_module = m;
- }
}
checked = 1;
}
@@ -103,9 +100,6 @@ apr_status_t h2_conn_child_init(apr_pool
mpm_type = H2_MPM_PREFORK;
mpm_module = m;
}
- else if (!strcmp("mod_ssl.c", m->name)) {
- ssl_module = m;
- }
}
if (minw <= 0) {
@@ -177,6 +171,11 @@ apr_status_t h2_conn_main(conn_rec *c)
return APR_EGENERAL;
}
+ if (!h2_is_acceptable_connection(c, 1)) {
+ nghttp2_submit_goaway(session->ngh2, NGHTTP2_FLAG_NONE, 0,
+ NGHTTP2_INADEQUATE_SECURITY, NULL, 0);
+ }
+
status = h2_conn_loop(session);
/* Make sure this connection gets closed properly. */
@@ -241,7 +240,7 @@ static apr_status_t h2_conn_loop(h2_sess
session->c->local_addr->port);
if (status != APR_SUCCESS) {
h2_session_abort(session, status, rv);
- h2_session_destroy(session);
+ h2_session_cleanup(session);
return status;
}
@@ -344,12 +343,9 @@ static apr_status_t h2_conn_loop(h2_sess
ap_log_cerror( APLOG_MARK, APLOG_DEBUG, status, session->c,
"h2_session(%ld): done", session->id);
+ h2_session_close(session);
ap_update_child_status_from_conn(session->c->sbh, SERVER_CLOSING,
session->c);
-
- h2_session_close(session);
- h2_session_destroy(session);
-
return DONE;
}
@@ -412,11 +408,11 @@ conn_rec *h2_conn_create(conn_rec *maste
return c;
}
-apr_status_t h2_conn_setup(h2_task_env *env, struct h2_worker *worker)
+apr_status_t h2_conn_setup(h2_task *task, struct h2_worker *worker)
{
- conn_rec *master = env->mplx->c;
+ conn_rec *master = task->mplx->c;
- ap_log_perror(APLOG_MARK, APLOG_TRACE3, 0, env->pool,
+ ap_log_perror(APLOG_MARK, APLOG_TRACE3, 0, task->pool,
"h2_conn(%ld): created from master", master->id);
/* Ok, we are just about to start processing the connection and
@@ -425,28 +421,18 @@ apr_status_t h2_conn_setup(h2_task_env *
* sub-resources from it, so that we get a nice reuse of
* pools.
*/
- env->c.pool = env->pool;
- env->c.bucket_alloc = h2_worker_get_bucket_alloc(worker);
- env->c.current_thread = h2_worker_get_thread(worker);
+ task->c->pool = task->pool;
+ task->c->bucket_alloc = h2_worker_get_bucket_alloc(worker);
+ task->c->current_thread = h2_worker_get_thread(worker);
- env->c.conn_config = ap_create_conn_config(env->pool);
- env->c.notes = apr_table_make(env->pool, 5);
+ task->c->conn_config = ap_create_conn_config(task->pool);
+ task->c->notes = apr_table_make(task->pool, 5);
- ap_set_module_config(env->c.conn_config, &core_module,
- h2_worker_get_socket(worker));
+ /* In order to do this in 2.4.x, we need to add a member to conn_rec */
+ task->c->master = master;
- /* If we serve http:// requests over a TLS connection, we do
- * not want any mod_ssl vars to be visible.
- */
- if (ssl_module && (!env->scheme || strcmp("http", env->scheme))) {
- /* See #19, there is a range of SSL variables to be gotten from
- * the main connection that should be available in request handlers
- */
- void *sslcfg = ap_get_module_config(master->conn_config, ssl_module);
- if (sslcfg) {
- ap_set_module_config(env->c.conn_config, ssl_module, sslcfg);
- }
- }
+ ap_set_module_config(task->c->conn_config, &core_module,
+ h2_worker_get_socket(worker));
/* This works for mpm_worker so far. Other mpm modules have
* different needs, unfortunately. The most interesting one
@@ -457,7 +443,7 @@ apr_status_t h2_conn_setup(h2_task_env *
/* all fine */
break;
case H2_MPM_EVENT:
- fix_event_conn(&env->c, master);
+ fix_event_conn(task->c, master);
break;
default:
/* fingers crossed */
@@ -469,7 +455,7 @@ apr_status_t h2_conn_setup(h2_task_env *
* 400 Bad Request
* when names do not match. We prefer a predictable 421 status.
*/
- env->c.keepalives = 1;
+ task->c->keepalives = 1;
return APR_SUCCESS;
}
Modified: httpd/httpd/branches/2.4-http2-alpha/modules/http2/h2_conn.h
URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.4-http2-alpha/modules/http2/h2_conn.h?rev=1712570&r1=1712569&r2=1712570&view=diff
==============================================================================
--- httpd/httpd/branches/2.4-http2-alpha/modules/http2/h2_conn.h (original)
+++ httpd/httpd/branches/2.4-http2-alpha/modules/http2/h2_conn.h Wed Nov 4 15:44:24 2015
@@ -17,7 +17,6 @@
#define __mod_h2__h2_conn__
struct h2_task;
-struct h2_task_env;
struct h2_worker;
/* Process the connection that is now starting the HTTP/2
@@ -52,7 +51,7 @@ h2_mpm_type_t h2_conn_mpm_type(void);
conn_rec *h2_conn_create(conn_rec *master, apr_pool_t *stream_pool);
-apr_status_t h2_conn_setup(struct h2_task_env *env, struct h2_worker *worker);
+apr_status_t h2_conn_setup(struct h2_task *task, struct h2_worker *worker);
apr_status_t h2_conn_post(conn_rec *c, struct h2_worker *worker);
apr_status_t h2_conn_process(conn_rec *c, apr_socket_t *socket);
Modified: httpd/httpd/branches/2.4-http2-alpha/modules/http2/h2_conn_io.c
URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.4-http2-alpha/modules/http2/h2_conn_io.c?rev=1712570&r1=1712569&r2=1712570&view=diff
==============================================================================
--- httpd/httpd/branches/2.4-http2-alpha/modules/http2/h2_conn_io.c (original)
+++ httpd/httpd/branches/2.4-http2-alpha/modules/http2/h2_conn_io.c Wed Nov 4 15:44:24 2015
@@ -28,31 +28,33 @@
#include "h2_h2.h"
#include "h2_util.h"
-#define WRITE_BUFFER_SIZE (64*1024)
+#define TLS_DATA_MAX (16*1024)
+
+/* Calculated like this: assuming MTU 1500 bytes
+ * 1500 - 40 (IP) - 20 (TCP) - 40 (TCP options)
+ * - TLS overhead (60-100)
+ * ~= 1300 bytes */
#define WRITE_SIZE_INITIAL 1300
-#define WRITE_SIZE_MAX (16*1024)
-#define WRITE_SIZE_IDLE_USEC (1*APR_USEC_PER_SEC)
-#define WRITE_SIZE_THRESHOLD (1*1024*1024)
+/* Calculated like this: max TLS record size 16*1024
+ * - 40 (IP) - 20 (TCP) - 40 (TCP options)
+ * - TLS overhead (60-100)
+ * which seems to create less TCP packets overall
+ */
+#define WRITE_SIZE_MAX (TLS_DATA_MAX - 100)
+
+#define WRITE_BUFFER_SIZE (8*WRITE_SIZE_MAX)
apr_status_t h2_conn_io_init(h2_conn_io *io, conn_rec *c)
{
- io->connection = c;
- io->input = apr_brigade_create(c->pool, c->bucket_alloc);
- io->output = apr_brigade_create(c->pool, c->bucket_alloc);
- io->buflen = 0;
- /* That is where we start with,
- * see https://issues.apache.org/jira/browse/TS-2503 */
- io->write_size = WRITE_SIZE_INITIAL;
- io->last_write = 0;
- io->buffer_output = h2_h2_is_tls(c);
-
- /* Currently we buffer only for TLS output. The reason this gives
- * improved performance is that buckets send to the mod_ssl network
- * filter will be encrypted in chunks. There is a special filter
- * that tries to aggregate data, but that does not work well when
- * bucket sizes alternate between tiny frame headers and large data
- * chunks.
- */
+ h2_config *cfg = h2_config_get(c);
+
+ io->connection = c;
+ io->input = apr_brigade_create(c->pool, c->bucket_alloc);
+ io->output = apr_brigade_create(c->pool, c->bucket_alloc);
+ io->buflen = 0;
+ io->is_tls = h2_h2_is_tls(c);
+ io->buffer_output = io->is_tls;
+
if (io->buffer_output) {
io->bufsize = WRITE_BUFFER_SIZE;
io->buffer = apr_pcalloc(c->pool, io->bufsize);
@@ -61,13 +63,33 @@ apr_status_t h2_conn_io_init(h2_conn_io
io->bufsize = 0;
}
+ if (io->is_tls) {
+ /* That is where we start with,
+ * see https://issues.apache.org/jira/browse/TS-2503 */
+ io->warmup_size = h2_config_geti64(cfg, H2_CONF_TLS_WARMUP_SIZE);
+ io->cooldown_usecs = (h2_config_geti(cfg, H2_CONF_TLS_COOLDOWN_SECS)
+ * APR_USEC_PER_SEC);
+ io->write_size = WRITE_SIZE_INITIAL;
+ }
+ else {
+ io->warmup_size = 0;
+ io->cooldown_usecs = 0;
+ io->write_size = io->bufsize;
+ }
+
+ if (APLOGctrace1(c)) {
+ ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, io->connection,
+ "h2_conn_io(%ld): init, buffering=%d, warmup_size=%ld, cd_secs=%f",
+ io->connection->id, io->buffer_output, (long)io->warmup_size,
+ ((float)io->cooldown_usecs/APR_USEC_PER_SEC));
+ }
+
return APR_SUCCESS;
}
-void h2_conn_io_destroy(h2_conn_io *io)
+int h2_conn_io_is_buffered(h2_conn_io *io)
{
- io->input = NULL;
- io->output = NULL;
+ return io->bufsize > 0;
}
static apr_status_t h2_conn_io_bucket_read(h2_conn_io *io,
@@ -159,7 +181,7 @@ apr_status_t h2_conn_io_read(h2_conn_io
status = ap_get_brigade(io->connection->input_filters,
io->input, AP_MODE_READBYTES,
- block, 16 * 4096);
+ block, 64 * 4096);
switch (status) {
case APR_SUCCESS:
return h2_conn_io_bucket_read(io, block, on_read_cb, puser, &done);
@@ -174,15 +196,22 @@ apr_status_t h2_conn_io_read(h2_conn_io
return status;
}
-static apr_status_t flush_out(apr_bucket_brigade *bb, void *ctx)
+static apr_status_t pass_out(apr_bucket_brigade *bb, void *ctx)
{
h2_conn_io *io = (h2_conn_io*)ctx;
apr_status_t status;
apr_off_t bblen;
+ if (APR_BRIGADE_EMPTY(bb)) {
+ return APR_SUCCESS;
+ }
+
ap_update_child_status(io->connection->sbh, SERVER_BUSY_WRITE, NULL);
- status = apr_brigade_length(bb, 1, &bblen);
+ status = apr_brigade_length(bb, 0, &bblen);
if (status == APR_SUCCESS) {
+ ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, io->connection,
+ "h2_conn_io(%ld): pass_out brigade %ld bytes",
+ io->connection->id, (long)bblen);
status = ap_pass_brigade(io->connection->output_filters, bb);
if (status == APR_SUCCESS) {
io->bytes_written += (apr_size_t)bblen;
@@ -193,14 +222,18 @@ static apr_status_t flush_out(apr_bucket
return status;
}
+/* Bring the current buffer content into the output brigade, appropriately
+ * chunked.
+ */
static apr_status_t bucketeer_buffer(h2_conn_io *io) {
const char *data = io->buffer;
apr_size_t remaining = io->buflen;
apr_bucket *b;
int bcount, i;
- if (io->write_size > WRITE_SIZE_INITIAL
- && (apr_time_now() - io->last_write) >= WRITE_SIZE_IDLE_USEC) {
+ if (io->write_size > WRITE_SIZE_INITIAL
+ && (io->cooldown_usecs > 0)
+ && (apr_time_now() - io->last_write) >= io->cooldown_usecs) {
/* long time not written, reset write size */
io->write_size = WRITE_SIZE_INITIAL;
io->bytes_written = 0;
@@ -209,7 +242,7 @@ static apr_status_t bucketeer_buffer(h2_
(long)io->connection->id, (long)io->write_size);
}
else if (io->write_size < WRITE_SIZE_MAX
- && io->bytes_written >= WRITE_SIZE_THRESHOLD) {
+ && io->bytes_written >= io->warmup_size) {
/* connection is hot, use max size */
io->write_size = WRITE_SIZE_MAX;
ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, io->connection,
@@ -238,16 +271,22 @@ apr_status_t h2_conn_io_write(h2_conn_io
const char *buf, size_t length)
{
apr_status_t status = APR_SUCCESS;
- io->unflushed = 1;
- if (io->buffer_output) {
+ io->unflushed = 1;
+ if (io->bufsize > 0) {
ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, io->connection,
"h2_conn_io: buffering %ld bytes", (long)length);
+
+ if (!APR_BRIGADE_EMPTY(io->output)) {
+ status = h2_conn_io_flush(io);
+ io->unflushed = 1;
+ }
+
while (length > 0 && (status == APR_SUCCESS)) {
apr_size_t avail = io->bufsize - io->buflen;
if (avail <= 0) {
bucketeer_buffer(io);
- status = flush_out(io->output, io);
+ status = pass_out(io->output, io);
io->buflen = 0;
}
else if (length > avail) {
@@ -266,46 +305,72 @@ apr_status_t h2_conn_io_write(h2_conn_io
}
else {
- status = apr_brigade_write(io->output, flush_out, io, buf, length);
- if (status != APR_SUCCESS) {
- ap_log_cerror(APLOG_MARK, APLOG_DEBUG, status, io->connection,
- "h2_conn_io: write error");
- }
+ ap_log_cerror(APLOG_MARK, APLOG_TRACE2, status, io->connection,
+ "h2_conn_io: writing %ld bytes to brigade", (long)length);
+ status = apr_brigade_write(io->output, pass_out, io, buf, length);
}
return status;
}
+apr_status_t h2_conn_io_writeb(h2_conn_io *io, apr_bucket *b)
+{
+ APR_BRIGADE_INSERT_TAIL(io->output, b);
+ io->unflushed = 1;
+ return APR_SUCCESS;
+}
+
+apr_status_t h2_conn_io_consider_flush(h2_conn_io *io)
+{
+ apr_status_t status = APR_SUCCESS;
+ int flush_now = 0;
+
+ /* The HTTP/1.1 network output buffer/flush behaviour does not
+ * give optimal performance in the HTTP/2 case, as the pattern of
+ * buckets (data/eor/eos) is different.
+ * As long as we do not have found out the "best" way to deal with
+ * this, force a flush at least every WRITE_BUFFER_SIZE amount
+ * of data which seems to work nicely.
+ */
+ if (io->unflushed) {
+ apr_off_t len = 0;
+ if (!APR_BRIGADE_EMPTY(io->output)) {
+ apr_brigade_length(io->output, 0, &len);
+ }
+ len += io->buflen;
+ flush_now = (len >= WRITE_BUFFER_SIZE);
+ }
+
+ if (flush_now) {
+ return h2_conn_io_flush(io);
+ }
+ return status;
+}
apr_status_t h2_conn_io_flush(h2_conn_io *io)
{
if (io->unflushed) {
apr_status_t status;
if (io->buflen > 0) {
+ /* something in the buffer, put it in the output brigade */
ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, io->connection,
"h2_conn_io: flush, flushing %ld bytes", (long)io->buflen);
bucketeer_buffer(io);
io->buflen = 0;
}
- /* Append flush.
- */
+
APR_BRIGADE_INSERT_TAIL(io->output,
apr_bucket_flush_create(io->output->bucket_alloc));
+ /* Send it out */
+ status = pass_out(io->output, io);
- /* Send it out through installed filters (TLS) to the client */
- status = flush_out(io->output, io);
-
- if (status == APR_SUCCESS) {
- /* These are all fine and no reason for concern. Everything else
- * is interesting. */
- io->unflushed = 0;
- }
- else {
+ if (status != APR_SUCCESS) {
ap_log_cerror(APLOG_MARK, APLOG_DEBUG, status, io->connection,
- "h2_conn_io: flush error");
+ "h2_conn_io: flush");
+ return status;
}
-
- return status;
+
+ io->unflushed = 0;
}
return APR_SUCCESS;
}
Modified: httpd/httpd/branches/2.4-http2-alpha/modules/http2/h2_conn_io.h
URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.4-http2-alpha/modules/http2/h2_conn_io.h?rev=1712570&r1=1712569&r2=1712570&view=diff
==============================================================================
--- httpd/httpd/branches/2.4-http2-alpha/modules/http2/h2_conn_io.h (original)
+++ httpd/httpd/branches/2.4-http2-alpha/modules/http2/h2_conn_io.h Wed Nov 4 15:44:24 2015
@@ -26,11 +26,16 @@ typedef struct {
conn_rec *connection;
apr_bucket_brigade *input;
apr_bucket_brigade *output;
- int buffer_output;
+
+ int is_tls;
+ apr_time_t cooldown_usecs;
+ apr_int64_t warmup_size;
+
int write_size;
apr_time_t last_write;
- apr_size_t bytes_written;
+ apr_int64_t bytes_written;
+ int buffer_output;
char *buffer;
apr_size_t buflen;
apr_size_t bufsize;
@@ -38,7 +43,8 @@ typedef struct {
} h2_conn_io;
apr_status_t h2_conn_io_init(h2_conn_io *io, conn_rec *c);
-void h2_conn_io_destroy(h2_conn_io *io);
+
+int h2_conn_io_is_buffered(h2_conn_io *io);
typedef apr_status_t (*h2_conn_io_on_read_cb)(const char *data, apr_size_t len,
apr_size_t *readlen, int *done,
@@ -52,6 +58,10 @@ apr_status_t h2_conn_io_read(h2_conn_io
apr_status_t h2_conn_io_write(h2_conn_io *io,
const char *buf,
size_t length);
+
+apr_status_t h2_conn_io_writeb(h2_conn_io *io, apr_bucket *b);
+
+apr_status_t h2_conn_io_consider_flush(h2_conn_io *io);
apr_status_t h2_conn_io_flush(h2_conn_io *io);
Modified: httpd/httpd/branches/2.4-http2-alpha/modules/http2/h2_ctx.c
URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.4-http2-alpha/modules/http2/h2_ctx.c?rev=1712570&r1=1712569&r2=1712570&view=diff
==============================================================================
--- httpd/httpd/branches/2.4-http2-alpha/modules/http2/h2_ctx.c (original)
+++ httpd/httpd/branches/2.4-http2-alpha/modules/http2/h2_ctx.c Wed Nov 4 15:44:24 2015
@@ -32,11 +32,11 @@ static h2_ctx *h2_ctx_create(const conn_
return ctx;
}
-h2_ctx *h2_ctx_create_for(const conn_rec *c, h2_task_env *env)
+h2_ctx *h2_ctx_create_for(const conn_rec *c, h2_task *task)
{
h2_ctx *ctx = h2_ctx_create(c);
if (ctx) {
- ctx->task_env = env;
+ ctx->task = task;
}
return ctx;
}
@@ -76,7 +76,7 @@ h2_ctx *h2_ctx_server_set(h2_ctx *ctx, s
int h2_ctx_is_task(h2_ctx *ctx)
{
- return ctx && !!ctx->task_env;
+ return ctx && !!ctx->task;
}
int h2_ctx_is_active(h2_ctx *ctx)
@@ -84,7 +84,7 @@ int h2_ctx_is_active(h2_ctx *ctx)
return ctx && ctx->is_h2;
}
-struct h2_task_env *h2_ctx_get_task(h2_ctx *ctx)
+struct h2_task *h2_ctx_get_task(h2_ctx *ctx)
{
- return ctx->task_env;
+ return ctx->task;
}
Modified: httpd/httpd/branches/2.4-http2-alpha/modules/http2/h2_ctx.h
URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.4-http2-alpha/modules/http2/h2_ctx.h?rev=1712570&r1=1712569&r2=1712570&view=diff
==============================================================================
--- httpd/httpd/branches/2.4-http2-alpha/modules/http2/h2_ctx.h (original)
+++ httpd/httpd/branches/2.4-http2-alpha/modules/http2/h2_ctx.h Wed Nov 4 15:44:24 2015
@@ -16,7 +16,7 @@
#ifndef __mod_h2__h2_ctx__
#define __mod_h2__h2_ctx__
-struct h2_task_env;
+struct h2_task;
struct h2_config;
/**
@@ -30,7 +30,7 @@ struct h2_config;
typedef struct h2_ctx {
int is_h2; /* h2 engine is used */
const char *protocol; /* the protocol negotiated */
- struct h2_task_env *task_env; /* the h2_task environment or NULL */
+ struct h2_task *task; /* the h2_task executing or NULL */
const char *hostname; /* hostname negotiated via SNI, optional */
server_rec *server; /* httpd server config selected. */
struct h2_config *config; /* effective config in this context */
@@ -38,7 +38,7 @@ typedef struct h2_ctx {
h2_ctx *h2_ctx_get(const conn_rec *c);
h2_ctx *h2_ctx_rget(const request_rec *r);
-h2_ctx *h2_ctx_create_for(const conn_rec *c, struct h2_task_env *env);
+h2_ctx *h2_ctx_create_for(const conn_rec *c, struct h2_task *task);
/* Set the h2 protocol established on this connection context or
@@ -58,6 +58,6 @@ const char *h2_ctx_protocol_get(const co
int h2_ctx_is_task(h2_ctx *ctx);
int h2_ctx_is_active(h2_ctx *ctx);
-struct h2_task_env *h2_ctx_get_task(h2_ctx *ctx);
+struct h2_task *h2_ctx_get_task(h2_ctx *ctx);
#endif /* defined(__mod_h2__h2_ctx__) */
Modified: httpd/httpd/branches/2.4-http2-alpha/modules/http2/h2_from_h1.c
URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.4-http2-alpha/modules/http2/h2_from_h1.c?rev=1712570&r1=1712569&r2=1712570&view=diff
==============================================================================
--- httpd/httpd/branches/2.4-http2-alpha/modules/http2/h2_from_h1.c (original)
+++ httpd/httpd/branches/2.4-http2-alpha/modules/http2/h2_from_h1.c Wed Nov 4 15:44:24 2015
@@ -78,9 +78,9 @@ h2_response *h2_from_h1_get_response(h2_
static apr_status_t make_h2_headers(h2_from_h1 *from_h1, request_rec *r)
{
- from_h1->response = h2_response_create(from_h1->stream_id,
- from_h1->status, from_h1->hlines,
- from_h1->pool);
+ from_h1->response = h2_response_create(from_h1->stream_id, 0,
+ from_h1->status, from_h1->hlines,
+ from_h1->pool);
if (from_h1->response == NULL) {
ap_log_cerror(APLOG_MARK, APLOG_ERR, APR_EINVAL, r->connection,
APLOGNO(02915)
@@ -492,8 +492,8 @@ static h2_response *create_response(h2_f
apr_status_t h2_response_output_filter(ap_filter_t *f, apr_bucket_brigade *bb)
{
- h2_task_env *env = f->ctx;
- h2_from_h1 *from_h1 = env->output? env->output->from_h1 : NULL;
+ h2_task *task = f->ctx;
+ h2_from_h1 *from_h1 = task->output? task->output->from_h1 : NULL;
request_rec *r = f->r;
apr_bucket *b;
ap_bucket_error *eb = NULL;
@@ -503,7 +503,7 @@ apr_status_t h2_response_output_filter(a
ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, f->c,
"h2_from_h1(%d): output_filter called", from_h1->stream_id);
- if (r->header_only && env->output && from_h1->response) {
+ if (r->header_only && task->output && from_h1->response) {
/* throw away any data after we have compiled the response */
apr_brigade_cleanup(bb);
return OK;
Modified: httpd/httpd/branches/2.4-http2-alpha/modules/http2/h2_h2.c
URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.4-http2-alpha/modules/http2/h2_h2.c?rev=1712570&r1=1712569&r2=1712570&view=diff
==============================================================================
--- httpd/httpd/branches/2.4-http2-alpha/modules/http2/h2_h2.c (original)
+++ httpd/httpd/branches/2.4-http2-alpha/modules/http2/h2_h2.c Wed Nov 4 15:44:24 2015
@@ -54,6 +54,384 @@ APR_DECLARE_OPTIONAL_FN(int, ssl_is_http
static int (*opt_ssl_engine_disable)(conn_rec*);
static int (*opt_ssl_is_https)(conn_rec*);
/*******************************************************************************
+ * SSL var lookup
+ */
+APR_DECLARE_OPTIONAL_FN(char *, ssl_var_lookup,
+ (apr_pool_t *, server_rec *,
+ conn_rec *, request_rec *,
+ char *));
+static char *(*opt_ssl_var_lookup)(apr_pool_t *, server_rec *,
+ conn_rec *, request_rec *,
+ char *);
+
+
+/*******************************************************************************
+ * HTTP/2 error stuff
+ */
+static const char *h2_err_descr[] = {
+ "no error", /* 0x0 */
+ "protocol error",
+ "internal error",
+ "flow control error",
+ "settings timeout",
+ "stream closed", /* 0x5 */
+ "frame size error",
+ "refused stream",
+ "cancel",
+ "compression error",
+ "connect error", /* 0xa */
+ "enhance your calm",
+ "inadequate security",
+ "http/1.1 required",
+};
+
+const char *h2_h2_err_description(int h2_error)
+{
+ if (h2_error >= 0
+ && h2_error < (sizeof(h2_err_descr)/sizeof(h2_err_descr[0]))) {
+ return h2_err_descr[h2_error];
+ }
+ return "unknown http/2 errotr code";
+}
+
+/*******************************************************************************
+ * Check connection security requirements of RFC 7540
+ */
+
+/*
+ * Black Listed Ciphers from RFC 7549 Appendix A
+ *
+ */
+static const char *RFC7540_names[] = {
+ /* ciphers with NULL encrpytion */
+ "NULL-MD5", /* TLS_NULL_WITH_NULL_NULL */
+ /* same */ /* TLS_RSA_WITH_NULL_MD5 */
+ "NULL-SHA", /* TLS_RSA_WITH_NULL_SHA */
+ "NULL-SHA256", /* TLS_RSA_WITH_NULL_SHA256 */
+ "PSK-NULL-SHA", /* TLS_PSK_WITH_NULL_SHA */
+ "DHE-PSK-NULL-SHA", /* TLS_DHE_PSK_WITH_NULL_SHA */
+ "RSA-PSK-NULL-SHA", /* TLS_RSA_PSK_WITH_NULL_SHA */
+ "PSK-NULL-SHA256", /* TLS_PSK_WITH_NULL_SHA256 */
+ "PSK-NULL-SHA384", /* TLS_PSK_WITH_NULL_SHA384 */
+ "DHE-PSK-NULL-SHA256", /* TLS_DHE_PSK_WITH_NULL_SHA256 */
+ "DHE-PSK-NULL-SHA384", /* TLS_DHE_PSK_WITH_NULL_SHA384 */
+ "RSA-PSK-NULL-SHA256", /* TLS_RSA_PSK_WITH_NULL_SHA256 */
+ "RSA-PSK-NULL-SHA384", /* TLS_RSA_PSK_WITH_NULL_SHA384 */
+ "ECDH-ECDSA-NULL-SHA", /* TLS_ECDH_ECDSA_WITH_NULL_SHA */
+ "ECDHE-ECDSA-NULL-SHA", /* TLS_ECDHE_ECDSA_WITH_NULL_SHA */
+ "ECDH-RSA-NULL-SHA", /* TLS_ECDH_RSA_WITH_NULL_SHA */
+ "ECDHE-RSA-NULL-SHA", /* TLS_ECDHE_RSA_WITH_NULL_SHA */
+ "AECDH-NULL-SHA", /* TLS_ECDH_anon_WITH_NULL_SHA */
+ "ECDHE-PSK-NULL-SHA", /* TLS_ECDHE_PSK_WITH_NULL_SHA */
+ "ECDHE-PSK-NULL-SHA256", /* TLS_ECDHE_PSK_WITH_NULL_SHA256 */
+ "ECDHE-PSK-NULL-SHA384", /* TLS_ECDHE_PSK_WITH_NULL_SHA384 */
+
+ /* DES/3DES ciphers */
+ "PSK-3DES-EDE-CBC-SHA", /* TLS_PSK_WITH_3DES_EDE_CBC_SHA */
+ "DHE-PSK-3DES-EDE-CBC-SHA", /* TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA */
+ "RSA-PSK-3DES-EDE-CBC-SHA", /* TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA */
+ "ECDH-ECDSA-DES-CBC3-SHA", /* TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA */
+ "ECDHE-ECDSA-DES-CBC3-SHA", /* TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA */
+ "ECDH-RSA-DES-CBC3-SHA", /* TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA */
+ "ECDHE-RSA-DES-CBC3-SHA", /* TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA */
+ "AECDH-DES-CBC3-SHA", /* TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA */
+ "SRP-3DES-EDE-CBC-SHA", /* TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA */
+ "SRP-RSA-3DES-EDE-CBC-SHA", /* TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA */
+ "SRP-DSS-3DES-EDE-CBC-SHA", /* TLS_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA */
+ "ECDHE-PSK-3DES-EDE-CBC-SHA", /* TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA */
+ "DES-CBC-SHA", /* TLS_RSA_WITH_DES_CBC_SHA */
+ "DES-CBC3-SHA", /* TLS_RSA_WITH_3DES_EDE_CBC_SHA */
+ "DHE-DSS-DES-CBC3-SHA", /* TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA */
+ "DHE-RSA-DES-CBC-SHA", /* TLS_DHE_RSA_WITH_DES_CBC_SHA */
+ "DHE-RSA-DES-CBC3-SHA", /* TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA */
+ "ADH-DES-CBC-SHA", /* TLS_DH_anon_WITH_DES_CBC_SHA */
+ "ADH-DES-CBC3-SHA", /* TLS_DH_anon_WITH_3DES_EDE_CBC_SHA */
+ "EXP-DH-DSS-DES-CBC-SHA", /* TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA */
+ "DH-DSS-DES-CBC-SHA", /* TLS_DH_DSS_WITH_DES_CBC_SHA */
+ "DH-DSS-DES-CBC3-SHA", /* TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA */
+ "EXP-DH-RSA-DES-CBC-SHA", /* TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHA */
+ "DH-RSA-DES-CBC-SHA", /* TLS_DH_RSA_WITH_DES_CBC_SHA */
+ "DH-RSA-DES-CBC3-SHA", /* TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA */
+
+ /* blacklisted EXPORT ciphers */
+ "EXP-RC4-MD5", /* TLS_RSA_EXPORT_WITH_RC4_40_MD5 */
+ "EXP-RC2-CBC-MD5", /* TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5 */
+ "EXP-DES-CBC-SHA", /* TLS_RSA_EXPORT_WITH_DES40_CBC_SHA */
+ "EXP-DHE-DSS-DES-CBC-SHA", /* TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA */
+ "EXP-DHE-RSA-DES-CBC-SHA", /* TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA */
+ "EXP-ADH-DES-CBC-SHA", /* TLS_DH_anon_EXPORT_WITH_DES40_CBC_SHA */
+ "EXP-ADH-RC4-MD5", /* TLS_DH_anon_EXPORT_WITH_RC4_40_MD5 */
+
+ /* blacklisted RC4 encryption */
+ "RC4-MD5", /* TLS_RSA_WITH_RC4_128_MD5 */
+ "RC4-SHA", /* TLS_RSA_WITH_RC4_128_SHA */
+ "ADH-RC4-MD5", /* TLS_DH_anon_WITH_RC4_128_MD5 */
+ "KRB5-RC4-SHA", /* TLS_KRB5_WITH_RC4_128_SHA */
+ "KRB5-RC4-MD5", /* TLS_KRB5_WITH_RC4_128_MD5 */
+ "EXP-KRB5-RC4-SHA", /* TLS_KRB5_EXPORT_WITH_RC4_40_SHA */
+ "EXP-KRB5-RC4-MD5", /* TLS_KRB5_EXPORT_WITH_RC4_40_MD5 */
+ "PSK-RC4-SHA", /* TLS_PSK_WITH_RC4_128_SHA */
+ "DHE-PSK-RC4-SHA", /* TLS_DHE_PSK_WITH_RC4_128_SHA */
+ "RSA-PSK-RC4-SHA", /* TLS_RSA_PSK_WITH_RC4_128_SHA */
+ "ECDH-ECDSA-RC4-SHA", /* TLS_ECDH_ECDSA_WITH_RC4_128_SHA */
+ "ECDHE-ECDSA-RC4-SHA", /* TLS_ECDHE_ECDSA_WITH_RC4_128_SHA */
+ "ECDH-RSA-RC4-SHA", /* TLS_ECDH_RSA_WITH_RC4_128_SHA */
+ "ECDHE-RSA-RC4-SHA", /* TLS_ECDHE_RSA_WITH_RC4_128_SHA */
+ "AECDH-RC4-SHA", /* TLS_ECDH_anon_WITH_RC4_128_SHA */
+ "ECDHE-PSK-RC4-SHA", /* TLS_ECDHE_PSK_WITH_RC4_128_SHA */
+
+ /* blacklisted AES128 encrpytion ciphers */
+ "AES128-SHA256", /* TLS_RSA_WITH_AES_128_CBC_SHA */
+ "DH-DSS-AES128-SHA", /* TLS_DH_DSS_WITH_AES_128_CBC_SHA */
+ "DH-RSA-AES128-SHA", /* TLS_DH_RSA_WITH_AES_128_CBC_SHA */
+ "DHE-DSS-AES128-SHA", /* TLS_DHE_DSS_WITH_AES_128_CBC_SHA */
+ "DHE-RSA-AES128-SHA", /* TLS_DHE_RSA_WITH_AES_128_CBC_SHA */
+ "ADH-AES128-SHA", /* TLS_DH_anon_WITH_AES_128_CBC_SHA */
+ "AES128-SHA256", /* TLS_RSA_WITH_AES_128_CBC_SHA256 */
+ "DH-DSS-AES128-SHA256", /* TLS_DH_DSS_WITH_AES_128_CBC_SHA256 */
+ "DH-RSA-AES128-SHA256", /* TLS_DH_RSA_WITH_AES_128_CBC_SHA256 */
+ "DHE-DSS-AES128-SHA256", /* TLS_DHE_DSS_WITH_AES_128_CBC_SHA256 */
+ "DHE-RSA-AES128-SHA256", /* TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 */
+ "ECDH-ECDSA-AES128-SHA", /* TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA */
+ "ECDHE-ECDSA-AES128-SHA", /* TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA */
+ "ECDH-RSA-AES128-SHA", /* TLS_ECDH_RSA_WITH_AES_128_CBC_SHA */
+ "ECDHE-RSA-AES128-SHA", /* TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA */
+ "AECDH-AES128-SHA", /* TLS_ECDH_anon_WITH_AES_128_CBC_SHA */
+ "ECDHE-ECDSA-AES128-SHA256", /* TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 */
+ "ECDH-ECDSA-AES128-SHA256", /* TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256 */
+ "ECDHE-RSA-AES128-SHA256", /* TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 */
+ "ECDH-RSA-AES128-SHA256", /* TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256 */
+ "ADH-AES128-SHA256", /* TLS_DH_anon_WITH_AES_128_CBC_SHA256 */
+ "PSK-AES128-CBC-SHA", /* TLS_PSK_WITH_AES_128_CBC_SHA */
+ "DHE-PSK-AES128-CBC-SHA", /* TLS_DHE_PSK_WITH_AES_128_CBC_SHA */
+ "RSA-PSK-AES128-CBC-SHA", /* TLS_RSA_PSK_WITH_AES_128_CBC_SHA */
+ "PSK-AES128-CBC-SHA256", /* TLS_PSK_WITH_AES_128_CBC_SHA256 */
+ "DHE-PSK-AES128-CBC-SHA256", /* TLS_DHE_PSK_WITH_AES_128_CBC_SHA256 */
+ "RSA-PSK-AES128-CBC-SHA256", /* TLS_RSA_PSK_WITH_AES_128_CBC_SHA256 */
+ "ECDHE-PSK-AES128-CBC-SHA", /* TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA */
+ "ECDHE-PSK-AES128-CBC-SHA256", /* TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256 */
+ "AES128-CCM", /* TLS_RSA_WITH_AES_128_CCM */
+ "AES128-CCM8", /* TLS_RSA_WITH_AES_128_CCM_8 */
+ "PSK-AES128-CCM", /* TLS_PSK_WITH_AES_128_CCM */
+ "PSK-AES128-CCM8", /* TLS_PSK_WITH_AES_128_CCM_8 */
+ "AES128-GCM-SHA256", /* TLS_RSA_WITH_AES_128_GCM_SHA256 */
+ "DH-RSA-AES128-GCM-SHA256", /* TLS_DH_RSA_WITH_AES_128_GCM_SHA256 */
+ "DH-DSS-AES128-GCM-SHA256", /* TLS_DH_DSS_WITH_AES_128_GCM_SHA256 */
+ "ADH-AES128-GCM-SHA256", /* TLS_DH_anon_WITH_AES_128_GCM_SHA256 */
+ "PSK-AES128-GCM-SHA256", /* TLS_PSK_WITH_AES_128_GCM_SHA256 */
+ "RSA-PSK-AES128-GCM-SHA256", /* TLS_RSA_PSK_WITH_AES_128_GCM_SHA256 */
+ "ECDH-ECDSA-AES128-GCM-SHA256", /* TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 */
+ "ECDH-RSA-AES128-GCM-SHA256", /* TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 */
+ "SRP-AES-128-CBC-SHA", /* TLS_SRP_SHA_WITH_AES_128_CBC_SHA */
+ "SRP-RSA-AES-128-CBC-SHA", /* TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA */
+ "SRP-DSS-AES-128-CBC-SHA", /* TLS_SRP_SHA_DSS_WITH_AES_128_CBC_SHA */
+
+ /* blacklisted AES256 encrpytion ciphers */
+ "AES256-SHA", /* TLS_RSA_WITH_AES_256_CBC_SHA */
+ "DH-DSS-AES256-SHA", /* TLS_DH_DSS_WITH_AES_256_CBC_SHA */
+ "DH-RSA-AES256-SHA", /* TLS_DH_RSA_WITH_AES_256_CBC_SHA */
+ "DHE-DSS-AES256-SHA", /* TLS_DHE_DSS_WITH_AES_256_CBC_SHA */
+ "DHE-RSA-AES256-SHA", /* TLS_DHE_RSA_WITH_AES_256_CBC_SHA */
+ "ADH-AES256-SHA", /* TLS_DH_anon_WITH_AES_256_CBC_SHA */
+ "AES256-SHA256", /* TLS_RSA_WITH_AES_256_CBC_SHA256 */
+ "DH-DSS-AES256-SHA256", /* TLS_DH_DSS_WITH_AES_256_CBC_SHA256 */
+ "DH-RSA-AES256-SHA256", /* TLS_DH_RSA_WITH_AES_256_CBC_SHA256 */
+ "DHE-DSS-AES256-SHA256", /* TLS_DHE_DSS_WITH_AES_256_CBC_SHA256 */
+ "DHE-RSA-AES256-SHA256", /* TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 */
+ "ADH-AES256-SHA256", /* TLS_DH_anon_WITH_AES_256_CBC_SHA256 */
+ "ECDH-ECDSA-AES256-SHA", /* TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA */
+ "ECDHE-ECDSA-AES256-SHA", /* TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA */
+ "ECDH-RSA-AES256-SHA", /* TLS_ECDH_RSA_WITH_AES_256_CBC_SHA */
+ "ECDHE-RSA-AES256-SHA", /* TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA */
+ "AECDH-AES256-SHA", /* TLS_ECDH_anon_WITH_AES_256_CBC_SHA */
+ "ECDHE-ECDSA-AES256-SHA384", /* TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 */
+ "ECDH-ECDSA-AES256-SHA384", /* TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 */
+ "ECDHE-RSA-AES256-SHA384", /* TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 */
+ "ECDH-RSA-AES256-SHA384", /* TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 */
+ "PSK-AES256-CBC-SHA", /* TLS_PSK_WITH_AES_256_CBC_SHA */
+ "DHE-PSK-AES256-CBC-SHA", /* TLS_DHE_PSK_WITH_AES_256_CBC_SHA */
+ "RSA-PSK-AES256-CBC-SHA", /* TLS_RSA_PSK_WITH_AES_256_CBC_SHA */
+ "PSK-AES256-CBC-SHA384", /* TLS_PSK_WITH_AES_256_CBC_SHA384 */
+ "DHE-PSK-AES256-CBC-SHA384", /* TLS_DHE_PSK_WITH_AES_256_CBC_SHA384 */
+ "RSA-PSK-AES256-CBC-SHA384", /* TLS_RSA_PSK_WITH_AES_256_CBC_SHA384 */
+ "ECDHE-PSK-AES256-CBC-SHA", /* TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA */
+ "ECDHE-PSK-AES256-CBC-SHA384", /* TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384 */
+ "SRP-AES-256-CBC-SHA", /* TLS_SRP_SHA_WITH_AES_256_CBC_SHA */
+ "SRP-RSA-AES-256-CBC-SHA", /* TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA */
+ "SRP-DSS-AES-256-CBC-SHA", /* TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHA */
+ "AES256-CCM", /* TLS_RSA_WITH_AES_256_CCM */
+ "AES256-CCM8", /* TLS_RSA_WITH_AES_256_CCM_8 */
+ "PSK-AES256-CCM", /* TLS_PSK_WITH_AES_256_CCM */
+ "PSK-AES256-CCM8", /* TLS_PSK_WITH_AES_256_CCM_8 */
+ "AES256-GCM-SHA384", /* TLS_RSA_WITH_AES_256_GCM_SHA384 */
+ "DH-RSA-AES256-GCM-SHA384", /* TLS_DH_RSA_WITH_AES_256_GCM_SHA384 */
+ "DH-DSS-AES256-GCM-SHA384", /* TLS_DH_DSS_WITH_AES_256_GCM_SHA384 */
+ "ADH-AES256-GCM-SHA384", /* TLS_DH_anon_WITH_AES_256_GCM_SHA384 */
+ "PSK-AES256-GCM-SHA384", /* TLS_PSK_WITH_AES_256_GCM_SHA384 */
+ "RSA-PSK-AES256-GCM-SHA384", /* TLS_RSA_PSK_WITH_AES_256_GCM_SHA384 */
+ "ECDH-ECDSA-AES256-GCM-SHA384", /* TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 */
+ "ECDH-RSA-AES256-GCM-SHA384", /* TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384 */
+
+ /* blacklisted CAMELLIA128 encrpytion ciphers */
+ "CAMELLIA128-SHA", /* TLS_RSA_WITH_CAMELLIA_128_CBC_SHA */
+ "DH-DSS-CAMELLIA128-SHA", /* TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA */
+ "DH-RSA-CAMELLIA128-SHA", /* TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA */
+ "DHE-DSS-CAMELLIA128-SHA", /* TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA */
+ "DHE-RSA-CAMELLIA128-SHA", /* TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA */
+ "ADH-CAMELLIA128-SHA", /* TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA */
+ "ECDHE-ECDSA-CAMELLIA128-SHA256", /* TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 */
+ "ECDH-ECDSA-CAMELLIA128-SHA256", /* TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 */
+ "ECDHE-RSA-CAMELLIA128-SHA256", /* TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 */
+ "ECDH-RSA-CAMELLIA128-SHA256", /* TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256 */
+ "PSK-CAMELLIA128-SHA256", /* TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256 */
+ "DHE-PSK-CAMELLIA128-SHA256", /* TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 */
+ "RSA-PSK-CAMELLIA128-SHA256", /* TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256 */
+ "ECDHE-PSK-CAMELLIA128-SHA256", /* TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 */
+ "CAMELLIA128-GCM-SHA256", /* TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256 */
+ "DH-RSA-CAMELLIA128-GCM-SHA256", /* TLS_DH_RSA_WITH_CAMELLIA_128_GCM_SHA256 */
+ "DH-DSS-CAMELLIA128-GCM-SHA256", /* TLS_DH_DSS_WITH_CAMELLIA_128_GCM_SHA256 */
+ "ADH-CAMELLIA128-GCM-SHA256", /* TLS_DH_anon_WITH_CAMELLIA_128_GCM_SHA256 */
+ "ECDH-ECDSA-CAMELLIA128-GCM-SHA256",/* TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256 */
+ "ECDH-RSA-CAMELLIA128-GCM-SHA256", /* TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256 */
+ "PSK-CAMELLIA128-GCM-SHA256", /* TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256 */
+ "RSA-PSK-CAMELLIA128-GCM-SHA256", /* TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256 */
+ "CAMELLIA128-SHA256", /* TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256 */
+ "DH-DSS-CAMELLIA128-SHA256", /* TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA256 */
+ "DH-RSA-CAMELLIA128-SHA256", /* TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA256 */
+ "DHE-DSS-CAMELLIA128-SHA256", /* TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA256 */
+ "DHE-RSA-CAMELLIA128-SHA256", /* TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 */
+ "ADH-CAMELLIA128-SHA256", /* TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA256 */
+
+ /* blacklisted CAMELLIA256 encrpytion ciphers */
+ "CAMELLIA256-SHA", /* TLS_RSA_WITH_CAMELLIA_256_CBC_SHA */
+ "DH-RSA-CAMELLIA256-SHA", /* TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA */
+ "DH-DSS-CAMELLIA256-SHA", /* TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA */
+ "DHE-DSS-CAMELLIA256-SHA", /* TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA */
+ "DHE-RSA-CAMELLIA256-SHA", /* TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA */
+ "ADH-CAMELLIA256-SHA", /* TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA */
+ "ECDHE-ECDSA-CAMELLIA256-SHA384", /* TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 */
+ "ECDH-ECDSA-CAMELLIA256-SHA384", /* TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 */
+ "ECDHE-RSA-CAMELLIA256-SHA384", /* TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384 */
+ "ECDH-RSA-CAMELLIA256-SHA384", /* TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384 */
+ "PSK-CAMELLIA256-SHA384", /* TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384 */
+ "DHE-PSK-CAMELLIA256-SHA384", /* TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 */
+ "RSA-PSK-CAMELLIA256-SHA384", /* TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384 */
+ "ECDHE-PSK-CAMELLIA256-SHA384", /* TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 */
+ "CAMELLIA256-SHA256", /* TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256 */
+ "DH-DSS-CAMELLIA256-SHA256", /* TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA256 */
+ "DH-RSA-CAMELLIA256-SHA256", /* TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA256 */
+ "DHE-DSS-CAMELLIA256-SHA256", /* TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA256 */
+ "DHE-RSA-CAMELLIA256-SHA256", /* TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256 */
+ "ADH-CAMELLIA256-SHA256", /* TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA256 */
+ "CAMELLIA256-GCM-SHA384", /* TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384 */
+ "DH-RSA-CAMELLIA256-GCM-SHA384", /* TLS_DH_RSA_WITH_CAMELLIA_256_GCM_SHA384 */
+ "DH-DSS-CAMELLIA256-GCM-SHA384", /* TLS_DH_DSS_WITH_CAMELLIA_256_GCM_SHA384 */
+ "ADH-CAMELLIA256-GCM-SHA384", /* TLS_DH_anon_WITH_CAMELLIA_256_GCM_SHA384 */
+ "ECDH-ECDSA-CAMELLIA256-GCM-SHA384",/* TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384 */
+ "ECDH-RSA-CAMELLIA256-GCM-SHA384", /* TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384 */
+ "PSK-CAMELLIA256-GCM-SHA384", /* TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384 */
+ "RSA-PSK-CAMELLIA256-GCM-SHA384", /* TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384 */
+
+ /* The blacklisted ARIA encrpytion ciphers */
+ "ARIA128-SHA256", /* TLS_RSA_WITH_ARIA_128_CBC_SHA256 */
+ "ARIA256-SHA384", /* TLS_RSA_WITH_ARIA_256_CBC_SHA384 */
+ "DH-DSS-ARIA128-SHA256", /* TLS_DH_DSS_WITH_ARIA_128_CBC_SHA256 */
+ "DH-DSS-ARIA256-SHA384", /* TLS_DH_DSS_WITH_ARIA_256_CBC_SHA384 */
+ "DH-RSA-ARIA128-SHA256", /* TLS_DH_RSA_WITH_ARIA_128_CBC_SHA256 */
+ "DH-RSA-ARIA256-SHA384", /* TLS_DH_RSA_WITH_ARIA_256_CBC_SHA384 */
+ "DHE-DSS-ARIA128-SHA256", /* TLS_DHE_DSS_WITH_ARIA_128_CBC_SHA256 */
+ "DHE-DSS-ARIA256-SHA384", /* TLS_DHE_DSS_WITH_ARIA_256_CBC_SHA384 */
+ "DHE-RSA-ARIA128-SHA256", /* TLS_DHE_RSA_WITH_ARIA_128_CBC_SHA256 */
+ "DHE-RSA-ARIA256-SHA384", /* TLS_DHE_RSA_WITH_ARIA_256_CBC_SHA384 */
+ "ADH-ARIA128-SHA256", /* TLS_DH_anon_WITH_ARIA_128_CBC_SHA256 */
+ "ADH-ARIA256-SHA384", /* TLS_DH_anon_WITH_ARIA_256_CBC_SHA384 */
+ "ECDHE-ECDSA-ARIA128-SHA256", /* TLS_ECDHE_ECDSA_WITH_ARIA_128_CBC_SHA256 */
+ "ECDHE-ECDSA-ARIA256-SHA384", /* TLS_ECDHE_ECDSA_WITH_ARIA_256_CBC_SHA384 */
+ "ECDH-ECDSA-ARIA128-SHA256", /* TLS_ECDH_ECDSA_WITH_ARIA_128_CBC_SHA256 */
+ "ECDH-ECDSA-ARIA256-SHA384", /* TLS_ECDH_ECDSA_WITH_ARIA_256_CBC_SHA384 */
+ "ECDHE-RSA-ARIA128-SHA256", /* TLS_ECDHE_RSA_WITH_ARIA_128_CBC_SHA256 */
+ "ECDHE-RSA-ARIA256-SHA384", /* TLS_ECDHE_RSA_WITH_ARIA_256_CBC_SHA384 */
+ "ECDH-RSA-ARIA128-SHA256", /* TLS_ECDH_RSA_WITH_ARIA_128_CBC_SHA256 */
+ "ECDH-RSA-ARIA256-SHA384", /* TLS_ECDH_RSA_WITH_ARIA_256_CBC_SHA384 */
+ "ARIA128-GCM-SHA256", /* TLS_RSA_WITH_ARIA_128_GCM_SHA256 */
+ "ARIA256-GCM-SHA384", /* TLS_RSA_WITH_ARIA_256_GCM_SHA384 */
+ "DH-DSS-ARIA128-GCM-SHA256", /* TLS_DH_DSS_WITH_ARIA_128_GCM_SHA256 */
+ "DH-DSS-ARIA256-GCM-SHA384", /* TLS_DH_DSS_WITH_ARIA_256_GCM_SHA384 */
+ "DH-RSA-ARIA128-GCM-SHA256", /* TLS_DH_RSA_WITH_ARIA_128_GCM_SHA256 */
+ "DH-RSA-ARIA256-GCM-SHA384", /* TLS_DH_RSA_WITH_ARIA_256_GCM_SHA384 */
+ "ADH-ARIA128-GCM-SHA256", /* TLS_DH_anon_WITH_ARIA_128_GCM_SHA256 */
+ "ADH-ARIA256-GCM-SHA384", /* TLS_DH_anon_WITH_ARIA_256_GCM_SHA384 */
+ "ECDH-ECDSA-ARIA128-GCM-SHA256", /* TLS_ECDH_ECDSA_WITH_ARIA_128_GCM_SHA256 */
+ "ECDH-ECDSA-ARIA256-GCM-SHA384", /* TLS_ECDH_ECDSA_WITH_ARIA_256_GCM_SHA384 */
+ "ECDH-RSA-ARIA128-GCM-SHA256", /* TLS_ECDH_RSA_WITH_ARIA_128_GCM_SHA256 */
+ "ECDH-RSA-ARIA256-GCM-SHA384", /* TLS_ECDH_RSA_WITH_ARIA_256_GCM_SHA384 */
+ "PSK-ARIA128-SHA256", /* TLS_PSK_WITH_ARIA_128_CBC_SHA256 */
+ "PSK-ARIA256-SHA384", /* TLS_PSK_WITH_ARIA_256_CBC_SHA384 */
+ "DHE-PSK-ARIA128-SHA256", /* TLS_DHE_PSK_WITH_ARIA_128_CBC_SHA256 */
+ "DHE-PSK-ARIA256-SHA384", /* TLS_DHE_PSK_WITH_ARIA_256_CBC_SHA384 */
+ "RSA-PSK-ARIA128-SHA256", /* TLS_RSA_PSK_WITH_ARIA_128_CBC_SHA256 */
+ "RSA-PSK-ARIA256-SHA384", /* TLS_RSA_PSK_WITH_ARIA_256_CBC_SHA384 */
+ "ARIA128-GCM-SHA256", /* TLS_PSK_WITH_ARIA_128_GCM_SHA256 */
+ "ARIA256-GCM-SHA384", /* TLS_PSK_WITH_ARIA_256_GCM_SHA384 */
+ "RSA-PSK-ARIA128-GCM-SHA256", /* TLS_RSA_PSK_WITH_ARIA_128_GCM_SHA256 */
+ "RSA-PSK-ARIA256-GCM-SHA384", /* TLS_RSA_PSK_WITH_ARIA_256_GCM_SHA384 */
+ "ECDHE-PSK-ARIA128-SHA256", /* TLS_ECDHE_PSK_WITH_ARIA_128_CBC_SHA256 */
+ "ECDHE-PSK-ARIA256-SHA384", /* TLS_ECDHE_PSK_WITH_ARIA_256_CBC_SHA384 */
+
+ /* blacklisted SEED encryptions */
+ "SEED-SHA", /*TLS_RSA_WITH_SEED_CBC_SHA */
+ "DH-DSS-SEED-SHA", /* TLS_DH_DSS_WITH_SEED_CBC_SHA */
+ "DH-RSA-SEED-SHA", /* TLS_DH_RSA_WITH_SEED_CBC_SHA */
+ "DHE-DSS-SEED-SHA", /* TLS_DHE_DSS_WITH_SEED_CBC_SHA */
+ "DHE-RSA-SEED-SHA", /* TLS_DHE_RSA_WITH_SEED_CBC_SHA */
+ "ADH-SEED-SHA", /* TLS_DH_anon_WITH_SEED_CBC_SHA */
+
+ /* blacklisted KRB5 ciphers */
+ "KRB5-DES-CBC-SHA", /* TLS_KRB5_WITH_DES_CBC_SHA */
+ "KRB5-DES-CBC3-SHA", /* TLS_KRB5_WITH_3DES_EDE_CBC_SHA */
+ "KRB5-IDEA-CBC-SHA", /* TLS_KRB5_WITH_IDEA_CBC_SHA */
+ "KRB5-DES-CBC-MD5", /* TLS_KRB5_WITH_DES_CBC_MD5 */
+ "KRB5-DES-CBC3-MD5", /* TLS_KRB5_WITH_3DES_EDE_CBC_MD5 */
+ "KRB5-IDEA-CBC-MD5", /* TLS_KRB5_WITH_IDEA_CBC_MD5 */
+ "EXP-KRB5-DES-CBC-SHA", /* TLS_KRB5_EXPORT_WITH_DES_CBC_40_SHA */
+ "EXP-KRB5-DES-CBC-MD5", /* TLS_KRB5_EXPORT_WITH_DES_CBC_40_MD5 */
+ "EXP-KRB5-RC2-CBC-SHA", /* TLS_KRB5_EXPORT_WITH_RC2_CBC_40_SHA */
+ "EXP-KRB5-RC2-CBC-MD5", /* TLS_KRB5_EXPORT_WITH_RC2_CBC_40_MD5 */
+
+ /* blacklisted exoticas */
+ "DHE-DSS-CBC-SHA", /* TLS_DHE_DSS_WITH_DES_CBC_SHA */
+ "IDEA-CBC-SHA", /* TLS_RSA_WITH_IDEA_CBC_SHA */
+
+ /* not really sure if the following names are correct */
+ "SSL3_CK_SCSV", /* TLS_EMPTY_RENEGOTIATION_INFO_SCSV */
+ "SSL3_CK_FALLBACK_SCSV"
+};
+static size_t RFC7540_names_LEN = sizeof(RFC7540_names)/sizeof(RFC7540_names[0]);
+
+
+static apr_hash_t *BLCNames;
+
+static void cipher_init(apr_pool_t *pool)
+{
+ apr_hash_t *hash = apr_hash_make(pool);
+ const char *source;
+ int i;
+
+ source = "rfc7540";
+ for (i = 0; i < RFC7540_names_LEN; ++i) {
+ apr_hash_set(hash, RFC7540_names[i], APR_HASH_KEY_STRING, source);
+ }
+
+ BLCNames = hash;
+}
+
+static int cipher_is_blacklisted(const char *cipher, const char **psource)
+{
+ *psource = apr_hash_get(BLCNames, cipher, APR_HASH_KEY_STRING);
+ return !!*psource;
+}
+
+/*******************************************************************************
* Hooks for processing incoming connections:
* - pre_conn_before_tls switches SSL off for stream connections
* - process_conn take over connection in case of h2
@@ -72,12 +450,15 @@ apr_status_t h2_h2_init(apr_pool_t *pool
ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, "h2_h2, child_init");
opt_ssl_engine_disable = APR_RETRIEVE_OPTIONAL_FN(ssl_engine_disable);
opt_ssl_is_https = APR_RETRIEVE_OPTIONAL_FN(ssl_is_https);
+ opt_ssl_var_lookup = APR_RETRIEVE_OPTIONAL_FN(ssl_var_lookup);
- if (!opt_ssl_is_https) {
+ if (!opt_ssl_is_https || !opt_ssl_var_lookup) {
ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s,
APLOGNO(02951) "mod_ssl does not seem to be enabled");
}
+ cipher_init(pool);
+
return APR_SUCCESS;
}
@@ -86,19 +467,95 @@ int h2_h2_is_tls(conn_rec *c)
return opt_ssl_is_https && opt_ssl_is_https(c);
}
-int h2_tls_disable(conn_rec *c)
+int h2_is_acceptable_connection(conn_rec *c, int require_all)
+{
+ int is_tls = h2_h2_is_tls(c);
+ h2_config *cfg = h2_config_get(c);
+
+ if (is_tls && h2_config_geti(cfg, H2_CONF_MODERN_TLS_ONLY) > 0) {
+ /* Check TLS connection for modern TLS parameters, as defined in
+ * RFC 7540 and https://wiki.mozilla.org/Security/Server_Side_TLS#Modern_compatibility
+ */
+ apr_pool_t *pool = c->pool;
+ server_rec *s = c->base_server;
+ char *val;
+
+ if (!opt_ssl_var_lookup) {
+ /* unable to check */
+ return 0;
+ }
+
+ /* Need Tlsv1.2 or higher, rfc 7540, ch. 9.2
+ */
+ val = opt_ssl_var_lookup(pool, s, c, NULL, "SSL_PROTOCOL");
+ if (val && *val) {
+ if (strncmp("TLS", val, 3)
+ || !strcmp("TLSv1", val)
+ || !strcmp("TLSv1.1", val)) {
+ ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c,
+ "h2_h2(%ld): tls protocol not suitable: %s",
+ (long)c->id, val);
+ return 0;
+ }
+ }
+ else if (require_all) {
+ ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c,
+ "h2_h2(%ld): tls protocol is indetermined", (long)c->id);
+ return 0;
+ }
+
+ /* Check TLS cipher blacklist
+ */
+ val = opt_ssl_var_lookup(pool, s, c, NULL, "SSL_CIPHER");
+ if (val && *val) {
+ const char *source;
+ if (cipher_is_blacklisted(val, &source)) {
+ ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c,
+ "h2_h2(%ld): tls cipher %s blacklisted by %s",
+ (long)c->id, val, source);
+ return 0;
+ }
+ }
+ else if (require_all) {
+ ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c,
+ "h2_h2(%ld): tls cipher is indetermined", (long)c->id);
+ return 0;
+ }
+ }
+ return 1;
+}
+
+int h2_allows_h2_direct(conn_rec *c)
{
- if (opt_ssl_engine_disable) {
- return opt_ssl_engine_disable(c);
+ h2_config *cfg = h2_config_get(c);
+ int h2_direct = h2_config_geti(cfg, H2_CONF_DIRECT);
+
+ if (h2_direct < 0) {
+ if (h2_h2_is_tls(c)) {
+ /* disabled by default on TLS */
+ h2_direct = 0;
+ }
+ else {
+ /* enabled if "Protocols h2c" is configured */
+ h2_direct = ap_is_allowed_protocol(c, NULL, NULL, "h2c");
+ }
}
- return 0;
+ return !!h2_direct;
}
+int h2_allows_h2_upgrade(conn_rec *c)
+{
+ h2_config *cfg = h2_config_get(c);
+ int h2_upgrade = h2_config_geti(cfg, H2_CONF_UPGRADE);
+
+ return h2_upgrade > 0 || (h2_upgrade < 0 && !h2_h2_is_tls(c));
+}
/*******************************************************************************
* Register various hooks
*/
static const char *const mod_reqtimeout[] = { "reqtimeout.c", NULL};
+static const char* const mod_ssl[] = {"mod_ssl.c", NULL};
void h2_h2_register_hooks(void)
{
@@ -106,7 +563,8 @@ void h2_h2_register_hooks(void)
* take over, if h2* was selected as protocol.
*/
ap_hook_process_connection(h2_h2_process_conn,
- NULL, NULL, APR_HOOK_FIRST);
+ mod_ssl, NULL, APR_HOOK_MIDDLE);
+
/* Perform connection cleanup before the actual processing happens.
*/
ap_hook_process_connection(h2_h2_remove_timeout,
@@ -135,9 +593,6 @@ static int h2_h2_remove_timeout(conn_rec
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;
- int is_tls = h2_h2_is_tls(c);
ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, c, "h2_h2, process_conn");
if (h2_ctx_is_task(ctx)) {
@@ -145,53 +600,50 @@ int h2_h2_process_conn(conn_rec* c)
return DECLINED;
}
- /* If we have not already switched to a h2* protocol and the connection
- * is on "http/1.1"
- * -> sniff for the magic PRIamble. On TLS, this might trigger the ALPN.
- */
- if (!h2_ctx_protocol_get(c)
- && !strcmp(AP_PROTOCOL_HTTP1, ap_get_protocol(c))) {
+ if (h2_ctx_protocol_get(c)) {
+ /* Something has been negotiated */
+ }
+ else if (!strcmp(AP_PROTOCOL_HTTP1, ap_get_protocol(c))
+ && h2_allows_h2_direct(c)
+ && h2_is_acceptable_connection(c, 1)) {
+ /* connection still is on http/1.1 and H2Direct is enabled.
+ * Otherwise connection is in a fully acceptable state.
+ * -> peek at the first 24 incoming bytes
+ */
+ apr_bucket_brigade *temp;
apr_status_t status;
+ char *s = NULL;
+ apr_size_t slen;
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) {
- if (h2_ctx_protocol_get(c)
- || strcmp(AP_PROTOCOL_HTTP1, ap_get_protocol(c))) {
- /* h2 or another protocol has been selected. */
- }
- else {
- /* ALPN might have been triggered, but we're still on
- * 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)) {
- 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");
- }
- else {
- ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, c,
- "h2_h2, not detected in %d bytes: %s",
- (int)slen, s);
- }
- }
- }
- }
- else {
+
+ if (status != APR_SUCCESS) {
ap_log_cerror(APLOG_MARK, APLOG_DEBUG, status, c,
"h2_h2, error reading 24 bytes speculative");
+ apr_brigade_destroy(temp);
+ return DECLINED;
}
+
+ 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, h2_h2_is_tls(c)? "h2" : "h2c");
+ }
+ else {
+ ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, c,
+ "h2_h2, not detected in %d bytes: %s",
+ (int)slen, s);
+ }
+
apr_brigade_destroy(temp);
}
+ else {
+ /* the connection is not HTTP/1.1 or not for us, don't touch it */
+ return DECLINED;
+ }
/* If "h2" was selected as protocol (by whatever mechanism), take over
* the connection.
@@ -210,21 +662,21 @@ int h2_h2_process_conn(conn_rec* c)
static int h2_h2_post_read_req(request_rec *r)
{
h2_ctx *ctx = h2_ctx_rget(r);
- struct h2_task_env *env = h2_ctx_get_task(ctx);
- if (env) {
+ struct h2_task *task = h2_ctx_get_task(ctx);
+ if (task) {
/* h2_task connection for a stream, not for h2c */
ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
"adding h1_to_h2_resp output filter");
- if (env->serialize_headers) {
+ if (task->serialize_headers) {
ap_remove_output_filter_byhandle(r->output_filters, "H1_TO_H2_RESP");
- ap_add_output_filter("H1_TO_H2_RESP", env, r, r->connection);
+ ap_add_output_filter("H1_TO_H2_RESP", task, r, r->connection);
}
else {
/* replace the core http filter that formats response headers
* in HTTP/1 with our own that collects status and headers */
ap_remove_output_filter_byhandle(r->output_filters, "HTTP_HEADER");
ap_remove_output_filter_byhandle(r->output_filters, "H2_RESPONSE");
- ap_add_output_filter("H2_RESPONSE", env, r, r->connection);
+ ap_add_output_filter("H2_RESPONSE", task, r, r->connection);
}
}
return DECLINED;
Modified: httpd/httpd/branches/2.4-http2-alpha/modules/http2/h2_h2.h
URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.4-http2-alpha/modules/http2/h2_h2.h?rev=1712570&r1=1712569&r2=1712570&view=diff
==============================================================================
--- httpd/httpd/branches/2.4-http2-alpha/modules/http2/h2_h2.h (original)
+++ httpd/httpd/branches/2.4-http2-alpha/modules/http2/h2_h2.h Wed Nov 4 15:44:24 2015
@@ -34,6 +34,31 @@ extern const char *h2_tls_protos[];
*/
extern const char *H2_MAGIC_TOKEN;
+#define H2_ERR_NO_ERROR (0x00)
+#define H2_ERR_PROTOCOL_ERROR (0x01)
+#define H2_ERR_INTERNAL_ERROR (0x02)
+#define H2_ERR_FLOW_CONTROL_ERROR (0x03)
+#define H2_ERR_SETTINGS_TIMEOUT (0x04)
+#define H2_ERR_STREAM_CLOSED (0x05)
+#define H2_ERR_FRAME_SIZE_ERROR (0x06)
+#define H2_ERR_REFUSED_STREAM (0x07)
+#define H2_ERR_CANCEL (0x08)
+#define H2_ERR_COMPRESSION_ERROR (0x09)
+#define H2_ERR_CONNECT_ERROR (0x0a)
+#define H2_ERR_ENHANCE_YOUR_CALM (0x0b)
+#define H2_ERR_INADEQUATE_SECURITY (0x0c)
+#define H2_ERR_HTTP_1_1_REQUIRED (0x0d)
+
+/* Maximum number of padding bytes in a frame, rfc7540 */
+#define H2_MAX_PADLEN 256
+
+/**
+ * Provide a user readable description of the HTTP/2 error code-
+ * @param h2_error http/2 error code, as in rfc 7540, ch. 7
+ * @return textual description of code or that it is unknown.
+ */
+const char *h2_h2_err_description(int h2_error);
+
/*
* One time, post config intialization.
*/
@@ -43,15 +68,35 @@ apr_status_t h2_h2_init(apr_pool_t *pool
*/
int h2_h2_is_tls(conn_rec *c);
-/* Disable SSL for this connection, can only be invoked in a pre-
- * connection hook before mod_ssl.
- * @return != 0 iff disable worked
- */
-int h2_tls_disable(conn_rec *c);
-
/* Register apache hooks for h2 protocol
*/
void h2_h2_register_hooks(void);
+/**
+ * Check if the given connection fulfills the requirements as configured.
+ * @param c the connection
+ * @param require_all != 0 iff any missing connection properties make
+ * the test fail. For example, a cipher might not have been selected while
+ * the handshake is still ongoing.
+ * @return != 0 iff connection requirements are met
+ */
+int h2_is_acceptable_connection(conn_rec *c, int require_all);
+
+/**
+ * Check if the "direct" HTTP/2 mode of protocol handling is enabled
+ * for the given connection.
+ * @param c the connection to check
+ * @return != 0 iff direct mode is enabled
+ */
+int h2_allows_h2_direct(conn_rec *c);
+
+/**
+ * Check if the "Upgrade" HTTP/1.1 mode of protocol switching is enabled
+ * for the given connection.
+ * @param c the connection to check
+ * @return != 0 iff Upgrade switching is enabled
+ */
+int h2_allows_h2_upgrade(conn_rec *c);
+
#endif /* defined(__mod_h2__h2_h2__) */
Modified: httpd/httpd/branches/2.4-http2-alpha/modules/http2/h2_io.c
URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.4-http2-alpha/modules/http2/h2_io.c?rev=1712570&r1=1712569&r2=1712570&view=diff
==============================================================================
--- httpd/httpd/branches/2.4-http2-alpha/modules/http2/h2_io.c (original)
+++ httpd/httpd/branches/2.4-http2-alpha/modules/http2/h2_io.c Wed Nov 4 15:44:24 2015
@@ -23,6 +23,7 @@
#include "h2_private.h"
#include "h2_io.h"
#include "h2_response.h"
+#include "h2_task.h"
#include "h2_util.h"
h2_io *h2_io_create(int id, apr_pool_t *pool, apr_bucket_alloc_t *bucket_alloc)
@@ -39,7 +40,10 @@ h2_io *h2_io_create(int id, apr_pool_t *
static void h2_io_cleanup(h2_io *io)
{
- (void)io;
+ if (io->task) {
+ h2_task_destroy(io->task);
+ io->task = NULL;
+ }
}
void h2_io_destroy(h2_io *io)
@@ -47,6 +51,17 @@ void h2_io_destroy(h2_io *io)
h2_io_cleanup(io);
}
+void h2_io_set_response(h2_io *io, h2_response *response)
+{
+ AP_DEBUG_ASSERT(response);
+ AP_DEBUG_ASSERT(!io->response);
+ io->response = h2_response_copy(io->pool, response);
+ if (response->rst_error) {
+ h2_io_rst(io, response->rst_error);
+ }
+}
+
+
void h2_io_rst(h2_io *io, int error)
{
io->rst_error = error;
@@ -90,8 +105,7 @@ apr_status_t h2_io_in_read(h2_io *io, ap
apr_brigade_length(bb, 1, &start_len);
last = APR_BRIGADE_LAST(bb);
- status = h2_util_move(bb, io->bbin, maxlen, 0,
- "h2_io_in_read");
+ status = h2_util_move(bb, io->bbin, maxlen, NULL, "h2_io_in_read");
if (status == APR_SUCCESS) {
apr_bucket *nlast = APR_BRIGADE_LAST(bb);
apr_off_t end_len = 0;
@@ -119,7 +133,7 @@ apr_status_t h2_io_in_write(h2_io *io, a
io->bbin = apr_brigade_create(io->bbout->p,
io->bbout->bucket_alloc);
}
- return h2_util_move(io->bbin, bb, 0, 0, "h2_io_in_write");
+ return h2_util_move(io->bbin, bb, 0, NULL, "h2_io_in_write");
}
return APR_SUCCESS;
}
@@ -168,6 +182,24 @@ apr_status_t h2_io_out_readx(h2_io *io,
return status;
}
+apr_status_t h2_io_out_read_to(h2_io *io, apr_bucket_brigade *bb,
+ apr_size_t *plen, int *peos)
+{
+ if (io->rst_error) {
+ return APR_ECONNABORTED;
+ }
+
+ if (io->eos_out) {
+ *plen = 0;
+ *peos = 1;
+ return APR_SUCCESS;
+ }
+
+
+ io->eos_out = *peos = h2_util_has_eos(io->bbout, *plen);
+ return h2_util_move(bb, io->bbout, *plen, NULL, "h2_io_read_to");
+}
+
apr_status_t h2_io_out_write(h2_io *io, apr_bucket_brigade *bb,
apr_size_t maxlen, int *pfile_handles_allowed)
{
Modified: httpd/httpd/branches/2.4-http2-alpha/modules/http2/h2_io.h
URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.4-http2-alpha/modules/http2/h2_io.h?rev=1712570&r1=1712569&r2=1712570&view=diff
==============================================================================
--- httpd/httpd/branches/2.4-http2-alpha/modules/http2/h2_io.h (original)
+++ httpd/httpd/branches/2.4-http2-alpha/modules/http2/h2_io.h Wed Nov 4 15:44:24 2015
@@ -21,8 +21,9 @@ struct apr_thread_cond_t;
struct h2_task;
-typedef apr_status_t h2_io_data_cb(void *ctx,
- const char *data, apr_size_t len);
+typedef apr_status_t h2_io_data_cb(void *ctx, const char *data, apr_size_t len);
+
+typedef int h2_stream_pri_cmp(int stream_id1, int stream_id2, void *ctx);
typedef struct h2_io h2_io;
@@ -34,7 +35,10 @@ struct h2_io {
int eos_in;
int task_done;
int rst_error;
+ int zombie;
+ struct h2_task *task; /* task created for this io */
+
apr_size_t input_consumed; /* how many bytes have been read */
struct apr_thread_cond_t *input_arrived; /* block on reading */
@@ -61,6 +65,11 @@ h2_io *h2_io_create(int id, apr_pool_t *
void h2_io_destroy(h2_io *io);
/**
+ * Set the response of this stream.
+ */
+void h2_io_set_response(h2_io *io, struct h2_response *response);
+
+/**
* Reset the stream with the given error code.
*/
void h2_io_rst(h2_io *io, int error);
@@ -114,6 +123,10 @@ apr_status_t h2_io_out_readx(h2_io *io,
h2_io_data_cb *cb, void *ctx,
apr_size_t *plen, int *peos);
+apr_status_t h2_io_out_read_to(h2_io *io,
+ apr_bucket_brigade *bb,
+ apr_size_t *plen, int *peos);
+
apr_status_t h2_io_out_write(h2_io *io, apr_bucket_brigade *bb,
apr_size_t maxlen, int *pfile_buckets_allowed);