diff options
author | Vsevolod Stakhov <vsevolod@highsecure.ru> | 2016-08-25 16:46:43 +0100 |
---|---|---|
committer | Vsevolod Stakhov <vsevolod@highsecure.ru> | 2016-08-25 16:46:43 +0100 |
commit | f719af257fbb7add041d993147aae982423c9f1b (patch) | |
tree | 4a4ee49c6f64b82bcb385fcdc21681abea86048c /src/libserver | |
parent | a9ba6158428a812fb6f1b68e08e478b6ee6ccad0 (diff) | |
download | rspamd-f719af257fbb7add041d993147aae982423c9f1b.tar.gz rspamd-f719af257fbb7add041d993147aae982423c9f1b.zip |
[Feature] Add preliminary monitored module
This module is designed to monitor liveness of different resources, DNS
lists, HTTP servers and so on.
Diffstat (limited to 'src/libserver')
-rw-r--r-- | src/libserver/CMakeLists.txt | 1 | ||||
-rw-r--r-- | src/libserver/monitored.c | 256 | ||||
-rw-r--r-- | src/libserver/monitored.h | 91 |
3 files changed, 348 insertions, 0 deletions
diff --git a/src/libserver/CMakeLists.txt b/src/libserver/CMakeLists.txt index 83006e835..49e4e6d25 100644 --- a/src/libserver/CMakeLists.txt +++ b/src/libserver/CMakeLists.txt @@ -10,6 +10,7 @@ SET(LIBRSPAMDSERVERSRC ${CMAKE_CURRENT_SOURCE_DIR}/events.c ${CMAKE_CURRENT_SOURCE_DIR}/fuzzy_backend.c ${CMAKE_CURRENT_SOURCE_DIR}/html.c + ${CMAKE_CURRENT_SOURCE_DIR}/monitored.c ${CMAKE_CURRENT_SOURCE_DIR}/protocol.c ${CMAKE_CURRENT_SOURCE_DIR}/proxy.c ${CMAKE_CURRENT_SOURCE_DIR}/re_cache.c diff --git a/src/libserver/monitored.c b/src/libserver/monitored.c new file mode 100644 index 000000000..14a8c367f --- /dev/null +++ b/src/libserver/monitored.c @@ -0,0 +1,256 @@ +/*- + * Copyright 2016 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 "rdns.h" +#include "mem_pool.h" +#include "cfg_file.h" +#include "monitored.h" +#include "cryptobox.h" +#include "logger.h" + +static const gdouble default_monitoring_interval = 10.0; +static const guint default_max_errors = 3; + +struct rspamd_monitored_methods { + void * (*monitored_config) (struct rspamd_monitored *m, + struct rspamd_monitored_ctx *ctx); + void (*monitored_update) (struct rspamd_monitored *m, + struct rspamd_monitored_ctx *ctx, gpointer ud); + gpointer ud; +}; + +struct rspamd_monitored_ctx { + struct rspamd_config *cfg; + struct rdns_resolver *resolver; + struct event_base *ev_base; + GPtrArray *elts; + gdouble monitoring_interval; + guint max_errors; + gboolean initialized; +}; + +struct rspamd_monitored { + gchar *url; + gdouble monitoring_interval; + guint max_errors; + guint cur_errors; + gboolean alive; + enum rspamd_monitored_type type; + enum rspamd_monitored_flags flags; + struct rspamd_monitored_ctx *ctx; + struct rspamd_monitored_methods proc; + struct event periodic; + gchar tag[MEMPOOL_UID_LEN]; +}; + +#define msg_err_mon(...) rspamd_default_log_function (G_LOG_LEVEL_CRITICAL, \ + "map", m->tag, \ + G_STRFUNC, \ + __VA_ARGS__) +#define msg_warn_mon(...) rspamd_default_log_function (G_LOG_LEVEL_WARNING, \ + "monitored", m->tag, \ + G_STRFUNC, \ + __VA_ARGS__) +#define msg_info_mon(...) rspamd_default_log_function (G_LOG_LEVEL_INFO, \ + "monitored", m->tag, \ + G_STRFUNC, \ + __VA_ARGS__) +#define msg_debug_mon(...) rspamd_default_log_function (G_LOG_LEVEL_DEBUG, \ + "monitored", m->tag, \ + G_STRFUNC, \ + __VA_ARGS__) + +static void +rspamd_monitored_periodic (gint fd, short what, gpointer ud) +{ + struct rspamd_monitored *m = ud; + struct timeval tv; + + double_to_tv (m->monitoring_interval, &tv); + + if (m->proc.monitored_update) { + m->proc.monitored_update (m, m->ctx, m->proc.ud); + } + + event_add (&m->periodic, &tv); +} + +struct rspamd_dns_monitored_conf { + void *unused; +}; + +static void * +rspamd_monitored_dns_conf (struct rspamd_monitored *m, + struct rspamd_monitored_ctx *ctx) +{ + struct rspamd_dns_monitored_conf *conf; + + conf = g_malloc0 (sizeof (*conf)); + + return conf; +} + +void +rspamd_monitored_dns_mon (struct rspamd_monitored *m, + struct rspamd_monitored_ctx *ctx, gpointer ud) +{ + +} + +struct rspamd_monitored_ctx * +rspamd_monitored_ctx_init (void) +{ + struct rspamd_monitored_ctx *ctx; + + ctx = g_slice_alloc0 (sizeof (*ctx)); + ctx->monitoring_interval = default_monitoring_interval; + ctx->max_errors = default_max_errors; + ctx->elts = g_ptr_array_new (); + + return ctx; +} + + +void +rspamd_monitored_ctx_config (struct rspamd_monitored_ctx *ctx, + struct rspamd_config *cfg, + struct event_base *ev_base, + struct rdns_resolver *resolver) +{ + struct rspamd_monitored *m; + guint i; + + g_assert (ctx != NULL); + ctx->ev_base = ev_base; + ctx->resolver = resolver; + ctx->cfg = cfg; + ctx->initialized = TRUE; + + /* Start all events */ + for (i = 0; i < ctx->elts->len; i ++) { + m = g_ptr_array_index (ctx->elts, i); + rspamd_monitored_start (m); + } +} + + +struct rspamd_monitored * +rspamd_monitored_create (struct rspamd_monitored_ctx *ctx, + const gchar *line, + enum rspamd_monitored_type type, + enum rspamd_monitored_flags flags) +{ + struct rspamd_monitored *m; + rspamd_cryptobox_hash_state_t st; + gchar *cksum_encoded, cksum[rspamd_cryptobox_HASHBYTES]; + + g_assert (ctx != NULL); + g_assert (line != NULL); + + m = g_slice_alloc0 (sizeof (*m)); + m->type = type; + m->flags = flags; + m->url = g_strdup (line); + m->ctx = ctx; + m->monitoring_interval = ctx->monitoring_interval; + m->max_errors = ctx->max_errors; + m->alive = TRUE; + + if (type == RSPAMD_MONITORED_DNS) { + m->proc.monitored_update = rspamd_monitored_dns_mon; + m->proc.monitored_config = rspamd_monitored_dns_conf; + m->proc.ud = m->proc.monitored_config (m, ctx); + + if (m->proc.ud == NULL) { + g_slice_free1 (sizeof (*m), m); + + return NULL; + } + } + + /* Create a persistent tag */ + rspamd_cryptobox_hash_init (&st, NULL, 0); + rspamd_cryptobox_hash_update (&st, m->url, strlen (m->url)); + rspamd_cryptobox_hash_final (&st, cksum); + cksum_encoded = rspamd_encode_base32 (cksum, sizeof (cksum)); + rspamd_strlcpy (m->tag, cksum_encoded, sizeof (m->tag)); + g_free (cksum_encoded); + + g_ptr_array_add (ctx->elts, m); + + if (ctx->ev_base) { + rspamd_monitored_start (m); + } + + return m; +} + +gboolean +rspamd_monitored_alive (struct rspamd_monitored *m) +{ + g_assert (m != NULL); + + return m->alive; +} + +void +rspamd_monitored_stop (struct rspamd_monitored *m) +{ + g_assert (m != NULL); + + m->alive = FALSE; + if (event_get_base (&m->periodic)) { + event_del (&m->periodic); + } +} + +void +rspamd_monitored_start (struct rspamd_monitored *m) +{ + struct timeval tv; + + g_assert (m != NULL); + msg_debug_mon ("started monitored object %s", m->url); + double_to_tv (m->monitoring_interval, &tv); + + if (event_get_base (&m->periodic)) { + event_del (&m->periodic); + } + + event_set (&m->periodic, -1, EV_TIMEOUT, rspamd_monitored_periodic, m); + event_base_set (m->ctx->ev_base, &m->periodic); + event_add (&m->periodic, &tv); +} + +void +rspamd_monitored_ctx_destroy (struct rspamd_monitored_ctx *ctx) +{ + struct rspamd_monitored *m; + guint i; + + g_assert (ctx != NULL); + + for (i = 0; i < ctx->elts->len; i ++) { + m = g_ptr_array_index (ctx->elts, i); + rspamd_monitored_stop (m); + g_free (m->url); + g_free (m->proc.ud); + g_slice_free1 (sizeof (*m), m); + } + + g_ptr_array_free (ctx->elts, TRUE); + g_slice_free1 (sizeof (*ctx), ctx); +} diff --git a/src/libserver/monitored.h b/src/libserver/monitored.h new file mode 100644 index 000000000..cfdf31b79 --- /dev/null +++ b/src/libserver/monitored.h @@ -0,0 +1,91 @@ +/*- + * Copyright 2016 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 SRC_LIBSERVER_MONITORED_H_ +#define SRC_LIBSERVER_MONITORED_H_ + +#include "config.h" +#include "rdns.h" + +struct rspamd_monitored; +struct rspamd_monitored_ctx; +struct rspamd_config; + +enum rspamd_monitored_type { + RSPAMD_MONITORED_DNS = 0, +}; + +enum rspamd_monitored_flags { + RSPAMD_MONITORED_DEFAULT = 0, + RSPAMD_MONITORED_RBL = (1 << 0), +}; + +/** + * Initialize new monitored context + * @return opaque context pointer (should be configured) + */ +struct rspamd_monitored_ctx *rspamd_monitored_ctx_init (void); + +/** + * Configure context for monitored objects + * @param ctx context + * @param cfg configuration + * @param ev_base events base + * @param resolver resolver object + */ +void rspamd_monitored_ctx_config (struct rspamd_monitored_ctx *ctx, + struct rspamd_config *cfg, + struct event_base *ev_base, + struct rdns_resolver *resolver); + +/** + * Create monitored object + * @param ctx context + * @param line string definition (e.g. hostname) + * @param type type of monitoring + * @param flags specific flags for monitoring + * @return new monitored object + */ +struct rspamd_monitored *rspamd_monitored_create ( + struct rspamd_monitored_ctx *ctx, + const gchar *line, + enum rspamd_monitored_type type, + enum rspamd_monitored_flags flags); + +/** + * Return TRUE if monitored object is alive + * @param m monitored object + * @return TRUE or FALSE + */ +gboolean rspamd_monitored_alive (struct rspamd_monitored *m); + +/** + * Explicitly disable monitored object + * @param m + */ +void rspamd_monitored_stop (struct rspamd_monitored *m); +/** + * Explicitly enable monitored object + * @param m + */ +void rspamd_monitored_start (struct rspamd_monitored *m); + +/** + * Destroy monitored context and all monitored objects inside + * @param ctx + */ +void rspamd_monitored_ctx_destroy (struct rspamd_monitored_ctx *ctx); + +#endif /* SRC_LIBSERVER_MONITORED_H_ */ |