From: Vsevolod Stakhov Date: Tue, 19 Feb 2019 17:56:19 +0000 (+0000) Subject: [Project] Add preliminary version of the http context concept X-Git-Tag: 1.9.0~116 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=82b8a0d6ba068fcd65c515872a990e39b566e52d;p=thirdparty%2Frspamd.git [Project] Add preliminary version of the http context concept --- diff --git a/src/libutil/http_context.c b/src/libutil/http_context.c new file mode 100644 index 0000000000..0237af1abc --- /dev/null +++ b/src/libutil/http_context.c @@ -0,0 +1,187 @@ +/*- + * Copyright 2019 Vsevolod Stakhov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "http_context.h" +#include "http_private.h" +#include "keypair.h" +#include "keypairs_cache.h" +#include "cfg_file.h" +#include "contrib/libottery/ottery.h" +#include "rspamd.h" + +static struct rspamd_http_context *default_ctx = NULL; + +static void +rspamd_http_context_client_rotate_ev (gint fd, short what, void *arg) +{ + struct timeval rot_tv; + struct rspamd_http_context *ctx = arg; + gpointer kp; + + double_to_tv (ctx->config.client_key_rotate_time, &rot_tv); + rot_tv.tv_sec += ottery_rand_range (rot_tv.tv_sec); + event_del (&ctx->client_rotate_ev); + event_add (&ctx->client_rotate_ev, &rot_tv); + + kp = ctx->client_kp; + ctx->client_kp = rspamd_keypair_new (RSPAMD_KEYPAIR_KEX, + RSPAMD_CRYPTOBOX_MODE_25519); + rspamd_keypair_unref (kp); +} + +static struct rspamd_http_context* +rspamd_http_context_new_default (struct rspamd_config *cfg, + struct event_base *ev_base) +{ + struct rspamd_http_context *ctx; + + static const int default_kp_size = 1024; + static const gdouble default_rotate_time = 120; + + ctx = g_malloc0 (sizeof (*ctx)); + ctx->config.kp_cache_size_client = default_kp_size; + ctx->config.kp_cache_size_server = default_kp_size; + ctx->config.client_key_rotate_time = default_rotate_time; + + if (cfg) { + ctx->ssl_ctx = cfg->libs_ctx->ssl_ctx; + ctx->ssl_ctx_noverify = cfg->libs_ctx->ssl_ctx_noverify; + } + else { + ctx->ssl_ctx = rspamd_init_ssl_ctx (); + ctx->ssl_ctx_noverify = rspamd_init_ssl_ctx_noverify (); + } + + ctx->ev_base = ev_base; + + return ctx; +} + +static void +rspamd_http_context_init (struct rspamd_http_context *ctx) +{ + if (ctx->config.kp_cache_size_client > 0) { + ctx->client_kp_cache = rspamd_keypair_cache_new (ctx->config.kp_cache_size_client); + } + + if (ctx->config.kp_cache_size_client > 0) { + ctx->client_kp_cache = rspamd_keypair_cache_new (ctx->config.kp_cache_size_client); + } + + if (ctx->config.client_key_rotate_time > 0 && ctx->ev_base) { + struct timeval tv; + double jittered = rspamd_time_jitter (ctx->config.client_key_rotate_time, + 0); + + double_to_tv (jittered, &tv); + event_set (&ctx->client_rotate_ev, -1, EV_TIMEOUT, + rspamd_http_context_client_rotate_ev, ctx); + event_base_set (ctx->ev_base, &ctx->client_rotate_ev); + event_add (&ctx->client_rotate_ev, &tv); + } + + default_ctx = ctx; +} + +struct rspamd_http_context* +rspamd_http_context_create (struct rspamd_config *cfg, + struct event_base *ev_base) +{ + struct rspamd_http_context *ctx; + const ucl_object_t *http_obj; + + ctx = rspamd_http_context_new_default (cfg, ev_base); + http_obj = ucl_object_lookup (cfg->rcl_obj, "http"); + + if (http_obj) { + const ucl_object_t *server_obj, *client_obj; + + client_obj = ucl_object_lookup (http_obj, "client"); + + if (client_obj) { + const ucl_object_t *kp_size; + + kp_size = ucl_object_lookup (client_obj, "cache_size"); + + if (kp_size) { + ctx->config.kp_cache_size_client = ucl_object_toint (kp_size); + } + + const ucl_object_t *rotate_time; + + rotate_time = ucl_object_lookup (client_obj, "rotate_time"); + + if (rotate_time) { + ctx->config.client_key_rotate_time = ucl_object_todouble (rotate_time); + } + } + + server_obj = ucl_object_lookup (http_obj, "server"); + + if (server_obj) { + const ucl_object_t *kp_size; + + kp_size = ucl_object_lookup (server_obj, "cache_size"); + + if (kp_size) { + ctx->config.kp_cache_size_server = ucl_object_toint (kp_size); + } + } + } + + rspamd_http_context_init (ctx); + + return ctx; +} + +void +rspamd_http_context_free (struct rspamd_http_context *ctx) +{ + if (ctx == default_ctx) { + default_ctx = NULL; + } + + if (ctx->client_kp_cache) { + rspamd_keypair_cache_destroy (ctx->client_kp_cache); + } + + if (ctx->server_kp_cache) { + rspamd_keypair_cache_destroy (ctx->server_kp_cache); + } + + g_free (ctx); +} + +struct rspamd_http_context* +rspamd_http_context_create_config (struct rspamd_http_context_cfg *cfg, + struct event_base *ev_base) +{ + struct rspamd_http_context *ctx; + + ctx = rspamd_http_context_new_default (NULL, ev_base); + memcpy (&ctx->config, cfg, sizeof (*cfg)); + rspamd_http_context_init (ctx); + + return ctx; +} + +struct rspamd_http_context* +rspamd_http_context_default (void) +{ + g_assert (default_ctx != NULL); + + return default_ctx; +} \ No newline at end of file diff --git a/src/libutil/http_context.h b/src/libutil/http_context.h new file mode 100644 index 0000000000..7d08206879 --- /dev/null +++ b/src/libutil/http_context.h @@ -0,0 +1,56 @@ +/*- + * Copyright 2019 Vsevolod Stakhov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef RSPAMD_HTTP_CONTEXT_H +#define RSPAMD_HTTP_CONTEXT_H + +#include "config.h" +#include "ucl.h" + +#include + +struct rspamd_http_context; +struct rspamd_config; + +struct rspamd_http_context_cfg { + guint kp_cache_size_client; + guint kp_cache_size_server; + guint ssl_cache_size; + gdouble client_key_rotate_time; + const gchar *user_agent; +}; + +/** + * Creates and configures new HTTP context + * @param root_conf configuration object + * @param ev_base event base + * @return new context used for both client and server HTTP connections + */ +struct rspamd_http_context* rspamd_http_context_create (struct rspamd_config *cfg, + struct event_base *ev_base); + +struct rspamd_http_context* rspamd_http_context_create_config ( + struct rspamd_http_context_cfg *cfg, + struct event_base *ev_base); +/** + * Destroys context + * @param ctx + */ +void rspamd_http_context_free (struct rspamd_http_context *ctx); + +struct rspamd_http_context* rspamd_http_context_default (void); + +#endif