aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMiecio Za <miecio@miecio.net>2019-03-18 20:53:02 +0100
committerMiecio Za <miecio@miecio.net>2019-03-18 20:53:02 +0100
commitcd50acbfc30ddba123ee85b7d9c2ee7ca9d0c20b (patch)
treea61807a7b85369201a47cdcfd04a6638776a4749 /src
parent925b1b072360e12f68a0992d3bdcb360c35f7663 (diff)
parent723e9e963380dfa12d5b9e0f7b999535e4917e48 (diff)
downloadrspamd-cd50acbfc30ddba123ee85b7d9c2ee7ca9d0c20b.tar.gz
rspamd-cd50acbfc30ddba123ee85b7d9c2ee7ca9d0c20b.zip
Merge branch 'master' into lua_string_utils
Diffstat (limited to 'src')
-rw-r--r--src/CMakeLists.txt2
-rw-r--r--src/client/rspamc.c35
-rw-r--r--src/client/rspamdclient.c5
-rw-r--r--src/client/rspamdclient.h4
-rw-r--r--src/controller.c3
-rw-r--r--src/fuzzy_storage.c14
-rw-r--r--src/libmime/archives.c5
-rw-r--r--src/libserver/dkim.c2
-rw-r--r--src/libserver/milter.c6
-rw-r--r--src/libserver/milter.h4
-rw-r--r--src/libserver/rspamd_control.c5
-rw-r--r--src/libserver/rspamd_symcache.c1
-rw-r--r--src/libserver/task.c2
-rw-r--r--src/libutil/http_connection.c248
-rw-r--r--src/libutil/http_connection.h62
-rw-r--r--src/libutil/http_context.c86
-rw-r--r--src/libutil/http_context.h7
-rw-r--r--src/libutil/http_message.c4
-rw-r--r--src/libutil/http_private.h5
-rw-r--r--src/libutil/http_router.c5
-rw-r--r--src/libutil/logger.c2
-rw-r--r--src/libutil/map.c170
-rw-r--r--src/libutil/map_private.h1
-rw-r--r--src/libutil/mem_pool.c18
-rw-r--r--src/libutil/multipattern.c1
-rw-r--r--src/libutil/rrd.c13
-rw-r--r--src/libutil/shingles.c4
-rw-r--r--src/libutil/upstream.c52
-rw-r--r--src/libutil/upstream.h4
-rw-r--r--src/lua/lua_common.c4
-rw-r--r--src/lua/lua_config.c6
-rw-r--r--src/lua/lua_html.c3
-rw-r--r--src/lua/lua_http.c27
-rw-r--r--src/lua/lua_task.c49
-rw-r--r--src/lua/lua_thread_pool.c2
-rw-r--r--src/lua/lua_udp.c2
-rw-r--r--src/lua/lua_util.c4
-rw-r--r--src/plugins/fuzzy_check.c7
-rw-r--r--src/plugins/lua/greylist.lua23
-rw-r--r--src/plugins/lua/neural.lua2
-rw-r--r--src/plugins/lua/replies.lua69
-rw-r--r--src/plugins/surbl.c38
-rw-r--r--src/rspamadm/control.c14
-rw-r--r--src/rspamadm/rspamadm.c3
-rw-r--r--src/rspamd.c2
-rw-r--r--src/rspamd_proxy.c18
-rw-r--r--src/worker.c8
47 files changed, 667 insertions, 384 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 256feb522..22d28e770 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -222,4 +222,4 @@ ENDIF(NOT DEBIAN_BUILD)
TARGET_LINK_LIBRARIES(rspamd rspamd-server)
INSTALL(TARGETS rspamd RUNTIME DESTINATION bin)
-INSTALL(TARGETS rspamd-server LIBRARY DESTINATION ${RSPAMD_LIBDIR})
+INSTALL(TARGETS rspamd-server LIBRARY DESTINATION ${RSPAMD_LIBDIR}) \ No newline at end of file
diff --git a/src/client/rspamc.c b/src/client/rspamc.c
index 0568692b4..2f572c449 100644
--- a/src/client/rspamc.c
+++ b/src/client/rspamc.c
@@ -74,8 +74,8 @@ static gint retcode = EXIT_SUCCESS;
#define ADD_CLIENT_HEADER(o, n, v) do { \
struct rspamd_http_client_header *nh; \
nh = g_malloc (sizeof (*nh)); \
- nh->name = (n); \
- nh->value = (v); \
+ nh->name = g_strdup (n); \
+ nh->value = g_strdup (v); \
g_queue_push_tail ((o), nh); \
} while (0)
@@ -645,6 +645,7 @@ add_options (GQueue *opts)
numbuf = g_string_sized_new (8);
rspamd_printf_gstring (numbuf, "%d", weight);
ADD_CLIENT_HEADER (opts, "Weight", numbuf->str);
+ g_string_free (numbuf, TRUE);
}
if (fuzzy_symbol != NULL) {
@@ -655,6 +656,7 @@ add_options (GQueue *opts)
numbuf = g_string_sized_new (8);
rspamd_printf_gstring (numbuf, "%d", flag);
ADD_CLIENT_HEADER (opts, "Flag", numbuf->str);
+ g_string_free (numbuf, TRUE);
}
if (extended_urls) {
@@ -680,15 +682,15 @@ add_options (GQueue *opts)
if (kv == NULL || kv[1] == NULL) {
ADD_CLIENT_HEADER (opts, *hdr, "");
-
- if (kv) {
- g_strfreev (kv);
- }
}
else {
ADD_CLIENT_HEADER (opts, kv[0], kv[1]);
}
+ if (kv) {
+ g_strfreev (kv);
+ }
+
hdr ++;
}
}
@@ -1006,9 +1008,9 @@ rspamc_counters_sort (const ucl_object_t **o1, const ucl_object_t **o2)
order2 = ucl_object_toint (elt2);
}
}
-
- g_strfreev (args);
}
+
+ g_strfreev (args);
}
return (inverse ? (order2 - order1) : (order1 - order2));
@@ -1841,6 +1843,17 @@ rspamc_process_dir (struct event_base *ev_base, struct rspamc_command *cmd,
event_base_loop (ev_base, 0);
}
+
+static void
+rspamc_kwattr_free (gpointer p)
+{
+ struct rspamd_http_client_header *h = (struct rspamd_http_client_header *)p;
+
+ g_free (h->value);
+ g_free (h->name);
+ g_free (h);
+}
+
gint
main (gint argc, gchar **argv, gchar **env)
{
@@ -1898,7 +1911,7 @@ main (gint argc, gchar **argv, gchar **env)
http_config.kp_cache_size_server = 0;
http_config.user_agent = user_agent;
http_ctx = rspamd_http_context_create_config (&http_config,
- ev_base);
+ ev_base, NULL);
/* Ignore sigpipe */
sigemptyset (&sigpipe_act.sa_mask);
@@ -2005,10 +2018,10 @@ main (gint argc, gchar **argv, gchar **env)
event_base_loop (ev_base, 0);
- g_queue_free_full (kwattrs, g_free);
+ g_queue_free_full (kwattrs, rspamc_kwattr_free);
/* Wait for children processes */
- cur = g_list_first (children);
+ cur = children ? g_list_first (children) : NULL;
ret = 0;
while (cur) {
diff --git a/src/client/rspamdclient.c b/src/client/rspamdclient.c
index a2ff85458..5f831ee64 100644
--- a/src/client/rspamdclient.c
+++ b/src/client/rspamdclient.c
@@ -255,13 +255,12 @@ rspamd_client_init (struct rspamd_http_context *http_ctx,
conn->ev_base = ev_base;
conn->fd = fd;
conn->req_sent = FALSE;
- conn->http_conn = rspamd_http_connection_new (http_ctx,
- fd,
+ conn->http_conn = rspamd_http_connection_new_client_socket (http_ctx,
rspamd_client_body_handler,
rspamd_client_error_handler,
rspamd_client_finish_handler,
0,
- RSPAMD_HTTP_CLIENT);
+ fd);
conn->server_name = g_string_new (name);
if (port != 0) {
diff --git a/src/client/rspamdclient.h b/src/client/rspamdclient.h
index c2a3c1886..8a5b3de35 100644
--- a/src/client/rspamdclient.h
+++ b/src/client/rspamdclient.h
@@ -24,8 +24,8 @@ struct rspamd_client_connection;
struct rspamd_http_message;
struct rspamd_http_client_header {
- const gchar *name;
- const gchar *value;
+ gchar *name;
+ gchar *value;
};
/**
diff --git a/src/controller.c b/src/controller.c
index ac1acae81..7b48462ee 100644
--- a/src/controller.c
+++ b/src/controller.c
@@ -3776,7 +3776,8 @@ start_controller_worker (struct rspamd_worker *worker)
"password");
/* Accept event */
- ctx->http_ctx = rspamd_http_context_create (ctx->cfg, ctx->ev_base);
+ ctx->http_ctx = rspamd_http_context_create (ctx->cfg, ctx->ev_base,
+ ctx->cfg->ups_ctx);
ctx->http = rspamd_http_router_new (rspamd_controller_error_handler,
rspamd_controller_finish_handler, &ctx->io_tv,
ctx->static_files_dir, ctx->http_ctx);
diff --git a/src/fuzzy_storage.c b/src/fuzzy_storage.c
index 7fdce82ae..e82e9062a 100644
--- a/src/fuzzy_storage.c
+++ b/src/fuzzy_storage.c
@@ -599,6 +599,7 @@ rspamd_fuzzy_send_update_mirror (struct rspamd_fuzzy_storage_ctx *ctx,
conn->mirror = m;
if (conn->up == NULL) {
+ g_free (conn);
msg_err ("cannot select upstream for %s", m->name);
return;
}
@@ -608,6 +609,7 @@ rspamd_fuzzy_send_update_mirror (struct rspamd_fuzzy_storage_ctx *ctx,
SOCK_STREAM, TRUE);
if (conn->sock == -1) {
+ g_free (conn);
msg_err ("cannot connect upstream for %s", m->name);
rspamd_upstream_fail (conn->up, TRUE);
return;
@@ -616,14 +618,13 @@ rspamd_fuzzy_send_update_mirror (struct rspamd_fuzzy_storage_ctx *ctx,
msg = rspamd_http_new_message (HTTP_REQUEST);
rspamd_printf_fstring (&msg->url, "/update_v1/%s", m->name);
- conn->http_conn = rspamd_http_connection_new (
+ conn->http_conn = rspamd_http_connection_new_client_socket (
ctx->http_ctx,
- conn->sock,
NULL,
fuzzy_mirror_error_handler,
fuzzy_mirror_finish_handler,
RSPAMD_HTTP_CLIENT_SIMPLE,
- RSPAMD_HTTP_CLIENT);
+ conn->sock);
rspamd_http_connection_set_key (conn->http_conn,
ctx->sync_keypair);
@@ -1990,14 +1991,13 @@ accept_fuzzy_mirror_socket (gint fd, short what, void *arg)
session->name = rspamd_inet_address_to_string (addr);
rspamd_random_hex (session->uid, sizeof (session->uid) - 1);
session->uid[sizeof (session->uid) - 1] = '\0';
- http_conn = rspamd_http_connection_new (
+ http_conn = rspamd_http_connection_new_server (
ctx->http_ctx,
nfd,
NULL,
rspamd_fuzzy_mirror_error_handler,
rspamd_fuzzy_mirror_finish_handler,
- 0,
- RSPAMD_HTTP_SERVER);
+ 0);
rspamd_http_connection_set_key (http_conn, ctx->sync_keypair);
session->ctx = ctx;
@@ -2999,7 +2999,7 @@ start_fuzzy (struct rspamd_worker *worker)
ctx->keypair_cache = rspamd_keypair_cache_new (ctx->keypair_cache_size);
}
- ctx->http_ctx = rspamd_http_context_create (cfg, ctx->ev_base);
+ ctx->http_ctx = rspamd_http_context_create (cfg, ctx->ev_base, ctx->cfg->ups_ctx);
if (!ctx->collection_mode) {
/*
diff --git a/src/libmime/archives.c b/src/libmime/archives.c
index f546570a9..b84670761 100644
--- a/src/libmime/archives.c
+++ b/src/libmime/archives.c
@@ -1146,12 +1146,14 @@ rspamd_7zip_read_coders_info (struct rspamd_task *task,
return NULL;
}
- folder_nstreams = g_alloca (sizeof (int) * num_folders);
+ folder_nstreams = g_malloc (sizeof (int) * num_folders);
for (i = 0; i < num_folders && p != NULL && p < end; i++) {
p = rspamd_7zip_read_folder (task, p, end, arch,
&folder_nstreams[i], &num_digests);
}
+
+ g_free (folder_nstreams);
}
break;
case kCodersUnPackSize:
@@ -1499,6 +1501,7 @@ rspamd_7zip_read_files_info (struct rspamd_task *task,
if (fend == NULL || fend - p == 0) {
/* Crap instead of fname */
msg_debug_archive ("bad 7zip name; %s", G_STRLOC);
+ goto end;
}
res = rspamd_7zip_ucs2_to_utf8 (task, p, fend);
diff --git a/src/libserver/dkim.c b/src/libserver/dkim.c
index 9692d1b93..8100f8ee3 100644
--- a/src/libserver/dkim.c
+++ b/src/libserver/dkim.c
@@ -2664,6 +2664,7 @@ rspamd_dkim_sign_key_load (const gchar *key, gsize len,
if (stat (key, &st) != 0) {
g_set_error (err, dkim_error_quark (), DKIM_SIGERROR_KEYFAIL,
"cannot stat key file: '%s' %s", key, strerror (errno));
+ g_free (nkey);
return NULL;
}
@@ -2674,6 +2675,7 @@ rspamd_dkim_sign_key_load (const gchar *key, gsize len,
if (map == NULL) {
g_set_error (err, dkim_error_quark (), DKIM_SIGERROR_KEYFAIL,
"cannot map key file: '%s' %s", key, strerror (errno));
+ g_free (nkey);
return NULL;
}
diff --git a/src/libserver/milter.c b/src/libserver/milter.c
index 236a4bf75..188ff42d9 100644
--- a/src/libserver/milter.c
+++ b/src/libserver/milter.c
@@ -1138,15 +1138,15 @@ rspamd_milter_handle_socket (gint fd, const struct timeval *tv,
gboolean
rspamd_milter_set_reply (struct rspamd_milter_session *session,
- rspamd_fstring_t *xcode,
rspamd_fstring_t *rcode,
+ rspamd_fstring_t *xcode,
rspamd_fstring_t *reply)
{
GString *buf;
gboolean ret;
buf = g_string_sized_new (xcode->len + rcode->len + reply->len + 2);
- rspamd_printf_gstring (buf, "%V %V %V", xcode, rcode, reply);
+ rspamd_printf_gstring (buf, "%V %V %V", rcode, xcode, reply);
ret = rspamd_milter_send_action (session, RSPAMD_MILTER_REPLYCODE,
buf);
g_string_free (buf, TRUE);
@@ -1301,7 +1301,7 @@ rspamd_milter_del_header (struct rspamd_milter_session *session,
value.len = 0;
return rspamd_milter_send_action (session, RSPAMD_MILTER_CHGHEADER,
- idx, name, value);
+ idx, name, &value);
}
void
diff --git a/src/libserver/milter.h b/src/libserver/milter.h
index 7f375b018..10bf34d52 100644
--- a/src/libserver/milter.h
+++ b/src/libserver/milter.h
@@ -98,14 +98,14 @@ void * rspamd_milter_update_userdata (struct rspamd_milter_session *session,
/**
* Sets SMTP reply string
* @param session
- * @param xcode
* @param rcode
+ * @param xcode
* @param reply
* @return
*/
gboolean rspamd_milter_set_reply (struct rspamd_milter_session *session,
- rspamd_fstring_t *xcode,
rspamd_fstring_t *rcode,
+ rspamd_fstring_t *xcode,
rspamd_fstring_t *reply);
/**
diff --git a/src/libserver/rspamd_control.c b/src/libserver/rspamd_control.c
index 149ad4245..12d37cdbc 100644
--- a/src/libserver/rspamd_control.c
+++ b/src/libserver/rspamd_control.c
@@ -518,13 +518,12 @@ rspamd_control_process_client_socket (struct rspamd_main *rspamd_main,
session = g_malloc0 (sizeof (*session));
session->fd = fd;
- session->conn = rspamd_http_connection_new (rspamd_main->http_ctx,
+ session->conn = rspamd_http_connection_new_server (rspamd_main->http_ctx,
fd,
NULL,
rspamd_control_error_handler,
rspamd_control_finish_handler,
- 0,
- RSPAMD_HTTP_SERVER);
+ 0);
session->rspamd_main = rspamd_main;
session->addr = addr;
rspamd_http_connection_read_message (session->conn, session,
diff --git a/src/libserver/rspamd_symcache.c b/src/libserver/rspamd_symcache.c
index 3cfb15408..64e451f7a 100644
--- a/src/libserver/rspamd_symcache.c
+++ b/src/libserver/rspamd_symcache.c
@@ -1580,7 +1580,6 @@ rspamd_symcache_make_checkpoint (struct rspamd_task *task,
checkpoint->pass = RSPAMD_CACHE_PASS_INIT;
task->checkpoint = checkpoint;
- task->result = task->result;
return checkpoint;
}
diff --git a/src/libserver/task.c b/src/libserver/task.c
index 30bccb81b..c4e69c974 100644
--- a/src/libserver/task.c
+++ b/src/libserver/task.c
@@ -1231,7 +1231,7 @@ rspamd_task_write_ialist (struct rspamd_task *task,
struct rspamd_email_address *addr;
gint i, nchars = 0, cur_chars;
- if (lim <= 0) {
+ if (addrs && lim <= 0) {
lim = addrs->len;
}
diff --git a/src/libutil/http_connection.c b/src/libutil/http_connection.c
index dc3bfa9c0..b82f3c98f 100644
--- a/src/libutil/http_connection.c
+++ b/src/libutil/http_connection.c
@@ -49,6 +49,9 @@ enum rspamd_http_priv_flags {
RSPAMD_HTTP_CONN_FLAG_RESETED = 1 << 2,
RSPAMD_HTTP_CONN_FLAG_TOO_LARGE = 1 << 3,
RSPAMD_HTTP_CONN_FLAG_ENCRYPTION_NEEDED = 1 << 4,
+ RSPAMD_HTTP_CONN_FLAG_PROXY = 1 << 5,
+ RSPAMD_HTTP_CONN_FLAG_PROXY_REQUEST = 1 << 6,
+ RSPAMD_HTTP_CONN_OWN_SOCKET = 1 << 7,
};
#define IS_CONN_ENCRYPTED(c) ((c)->flags & RSPAMD_HTTP_CONN_FLAG_ENCRYPTED)
@@ -717,15 +720,20 @@ rspamd_http_simple_client_helper (struct rspamd_http_connection *conn)
struct rspamd_http_connection_private *priv;
gpointer ssl;
gint request_method;
- rspamd_fstring_t *prev_host;
+ GString *prev_host = NULL;
priv = conn->priv;
ssl = priv->ssl;
priv->ssl = NULL;
- request_method = priv->msg->method;
- /* Preserve host for keepalive */
- prev_host = priv->msg->host;
- priv->msg->host = NULL;
+
+ /* Preserve data */
+ if (priv->msg) {
+ request_method = priv->msg->method;
+ /* Preserve host for keepalive */
+ prev_host = priv->msg->host;
+ priv->msg->host = NULL;
+ }
+
rspamd_http_connection_reset (conn);
priv->ssl = ssl;
@@ -746,7 +754,7 @@ rspamd_http_simple_client_helper (struct rspamd_http_connection *conn)
}
else {
if (prev_host) {
- rspamd_fstring_free (prev_host);
+ g_string_free (prev_host, TRUE);
}
}
}
@@ -1071,21 +1079,24 @@ rspamd_http_parser_reset (struct rspamd_http_connection *conn)
priv->parser_cb.on_message_complete = rspamd_http_on_message_complete;
}
-struct rspamd_http_connection *
-rspamd_http_connection_new (
- struct rspamd_http_context *ctx,
- gint fd,
- rspamd_http_body_handler_t body_handler,
- rspamd_http_error_handler_t error_handler,
- rspamd_http_finish_handler_t finish_handler,
- unsigned opts,
- enum rspamd_http_connection_type type)
+static struct rspamd_http_connection *
+rspamd_http_connection_new_common (struct rspamd_http_context *ctx,
+ gint fd,
+ rspamd_http_body_handler_t body_handler,
+ rspamd_http_error_handler_t error_handler,
+ rspamd_http_finish_handler_t finish_handler,
+ unsigned opts,
+ enum rspamd_http_connection_type type,
+ enum rspamd_http_priv_flags priv_flags,
+ struct upstream *proxy_upstream)
{
struct rspamd_http_connection *conn;
struct rspamd_http_connection_private *priv;
- if (error_handler == NULL || finish_handler == NULL) {
- return NULL;
+ g_assert (error_handler != NULL && finish_handler != NULL);
+
+ if (ctx == NULL) {
+ ctx = rspamd_http_context_default ();
}
conn = g_malloc0 (sizeof (struct rspamd_http_connection));
@@ -1099,23 +1110,20 @@ rspamd_http_connection_new (
conn->finished = FALSE;
/* Init priv */
- if (ctx == NULL) {
- ctx = rspamd_http_context_default ();
- }
-
priv = g_malloc0 (sizeof (struct rspamd_http_connection_private));
conn->priv = priv;
priv->ctx = ctx;
+ priv->flags = priv_flags;
- if (conn->type == RSPAMD_HTTP_CLIENT) {
+ if (type == RSPAMD_HTTP_SERVER) {
+ priv->cache = ctx->server_kp_cache;
+ }
+ else {
priv->cache = ctx->client_kp_cache;
if (ctx->client_kp) {
priv->local_key = rspamd_keypair_ref (ctx->client_kp);
}
}
- else {
- priv->cache = ctx->server_kp_cache;
- }
rspamd_http_parser_reset (conn);
priv->parser.data = conn;
@@ -1124,42 +1132,111 @@ rspamd_http_connection_new (
}
struct rspamd_http_connection *
-rspamd_http_connection_new_keepalive (struct rspamd_http_context *ctx,
- rspamd_http_body_handler_t body_handler,
- rspamd_http_error_handler_t error_handler,
- rspamd_http_finish_handler_t finish_handler,
- rspamd_inet_addr_t *addr,
- const gchar *host)
+rspamd_http_connection_new_server (struct rspamd_http_context *ctx,
+ gint fd,
+ rspamd_http_body_handler_t body_handler,
+ rspamd_http_error_handler_t error_handler,
+ rspamd_http_finish_handler_t finish_handler,
+ unsigned opts)
{
- struct rspamd_http_connection *conn;
- gint fd;
+ return rspamd_http_connection_new_common (ctx, fd, body_handler,
+ error_handler, finish_handler, opts, RSPAMD_HTTP_SERVER, 0, NULL);
+}
- if (error_handler == NULL || finish_handler == NULL) {
- return NULL;
- }
+struct rspamd_http_connection *
+rspamd_http_connection_new_client_socket (struct rspamd_http_context *ctx,
+ rspamd_http_body_handler_t body_handler,
+ rspamd_http_error_handler_t error_handler,
+ rspamd_http_finish_handler_t finish_handler,
+ unsigned opts,
+ gint fd)
+{
+ return rspamd_http_connection_new_common (ctx, fd, body_handler,
+ error_handler, finish_handler, opts, RSPAMD_HTTP_CLIENT, 0, NULL);
+}
+
+struct rspamd_http_connection *
+rspamd_http_connection_new_client (struct rspamd_http_context *ctx,
+ rspamd_http_body_handler_t body_handler,
+ rspamd_http_error_handler_t error_handler,
+ rspamd_http_finish_handler_t finish_handler,
+ unsigned opts,
+ rspamd_inet_addr_t *addr)
+{
+ gint fd;
if (ctx == NULL) {
ctx = rspamd_http_context_default ();
}
- conn = rspamd_http_context_check_keepalive (ctx, addr, host);
+ if (ctx->http_proxies) {
+ struct upstream *up = rspamd_upstream_get (ctx->http_proxies,
+ RSPAMD_UPSTREAM_ROUND_ROBIN, NULL, 0);
- if (conn) {
- return conn;
+ if (up) {
+ rspamd_inet_addr_t *proxy_addr = rspamd_upstream_addr_next (up);
+
+ fd = rspamd_inet_address_connect (proxy_addr, SOCK_STREAM, TRUE);
+
+ if (fd == -1) {
+ msg_info ("cannot connect to http proxy %s: %s",
+ rspamd_inet_address_to_string (proxy_addr),
+ strerror (errno));
+ rspamd_upstream_fail (up, TRUE);
+
+ return NULL;
+ }
+
+ return rspamd_http_connection_new_common (ctx, fd, body_handler,
+ error_handler, finish_handler, opts,
+ RSPAMD_HTTP_CLIENT,
+ RSPAMD_HTTP_CONN_OWN_SOCKET|RSPAMD_HTTP_CONN_FLAG_PROXY,
+ up);
+ }
}
+ /* Unproxied version */
fd = rspamd_inet_address_connect (addr, SOCK_STREAM, TRUE);
if (fd == -1) {
- msg_info ("cannot connect to %s: %s", rspamd_inet_address_to_string (addr),
- host);
+ msg_info ("cannot connect to proxy %s: %s",
+ rspamd_inet_address_to_string (addr),
+ strerror (errno));
+
return NULL;
}
- conn = rspamd_http_connection_new (ctx, fd, body_handler, error_handler,
- finish_handler,
+ return rspamd_http_connection_new_common (ctx, fd, body_handler,
+ error_handler, finish_handler, opts,
+ RSPAMD_HTTP_CLIENT,
+ RSPAMD_HTTP_CONN_OWN_SOCKET,
+ NULL);
+}
+
+struct rspamd_http_connection *
+rspamd_http_connection_new_keepalive (struct rspamd_http_context *ctx,
+ rspamd_http_body_handler_t body_handler,
+ rspamd_http_error_handler_t error_handler,
+ rspamd_http_finish_handler_t finish_handler,
+ rspamd_inet_addr_t *addr,
+ const gchar *host)
+{
+ struct rspamd_http_connection *conn;
+
+ if (ctx == NULL) {
+ ctx = rspamd_http_context_default ();
+ }
+
+ conn = rspamd_http_context_check_keepalive (ctx, addr, host);
+
+ if (conn) {
+ return conn;
+ }
+
+ conn = rspamd_http_connection_new_client (ctx,
+ body_handler, error_handler, finish_handler,
RSPAMD_HTTP_CLIENT_SIMPLE|RSPAMD_HTTP_CLIENT_KEEP_ALIVE,
- RSPAMD_HTTP_CLIENT);
+ addr);
if (conn) {
rspamd_http_context_prepare_keepalive (ctx, conn, addr, host);
@@ -1324,8 +1401,7 @@ rspamd_http_connection_copy_msg (struct rspamd_http_message *msg, GError **err)
}
if (msg->host) {
- new_msg->host = rspamd_fstring_new_init (msg->host->str,
- msg->host->len);
+ new_msg->host = g_string_new_len (msg->host->str, msg->host->len);
}
new_msg->method = msg->method;
@@ -1379,12 +1455,12 @@ rspamd_http_connection_free (struct rspamd_http_connection *conn)
rspamd_pubkey_unref (priv->peer_key);
}
- g_free (priv);
- }
+ if (priv->flags & RSPAMD_HTTP_CONN_OWN_SOCKET) {
+ /* Fd is owned by a connection */
+ close (conn->fd);
+ }
- if (conn->opts & RSPAMD_HTTP_CLIENT_KEEP_ALIVE) {
- /* Fd is owned by a connection */
- close (conn->fd);
+ g_free (priv);
}
g_free (conn);
@@ -1710,12 +1786,15 @@ rspamd_http_message_write_header (const gchar* mime_type, gboolean encrypted,
}
}
else {
+
+ /* Client request */
if (conn->opts & RSPAMD_HTTP_CLIENT_KEEP_ALIVE) {
conn_type = "keep-alive";
}
/* Format request */
- enclen += msg->url->len + strlen (http_method_str (msg->method)) + 1;
+ enclen += RSPAMD_FSTRING_LEN (msg->url) +
+ strlen (http_method_str (msg->method)) + 1;
if (host == NULL && msg->host == NULL) {
/* Fallback to HTTP/1.0 */
@@ -1752,42 +1831,36 @@ rspamd_http_message_write_header (const gchar* mime_type, gboolean encrypted,
}
}
else {
+ /* Normal HTTP/1.1 with Host */
+ if (host == NULL) {
+ host = msg->host->str;
+ }
+
if (encrypted) {
- if (host != NULL) {
- rspamd_printf_fstring (buf,
- "%s %s HTTP/1.1\r\n"
- "Connection: %s\r\n"
- "Host: %s\r\n"
- "Content-Length: %z\r\n"
- "Content-Type: application/octet-stream\r\n",
- "POST",
- "/post",
- conn_type,
- host,
- enclen);
- }
- else {
- rspamd_printf_fstring (buf,
- "%s %s HTTP/1.1\r\n"
- "Connection: %s\r\n"
- "Host: %V\r\n"
- "Content-Length: %z\r\n"
- "Content-Type: application/octet-stream\r\n",
- "POST",
- "/post",
- conn_type,
- msg->host,
- enclen);
- }
+ /* TODO: Add proxy support to HTTPCrypt */
+ rspamd_printf_fstring (buf,
+ "%s %s HTTP/1.1\r\n"
+ "Connection: %s\r\n"
+ "Host: %s\r\n"
+ "Content-Length: %z\r\n"
+ "Content-Type: application/octet-stream\r\n",
+ "POST",
+ "/post",
+ conn_type,
+ host,
+ enclen);
}
else {
- if (host != NULL) {
+ if (conn->priv->flags & RSPAMD_HTTP_CONN_FLAG_PROXY) {
rspamd_printf_fstring (buf,
- "%s %V HTTP/1.1\r\n"
+ "%s %s://%s:%d/%V HTTP/1.1\r\n"
"Connection: %s\r\n"
"Host: %s\r\n"
"Content-Length: %z\r\n",
http_method_str (msg->method),
+ (msg->flags & RSPAMD_HTTP_FLAG_SSL) ? "https" : "http",
+ host,
+ msg->port,
msg->url,
conn_type,
host,
@@ -1797,12 +1870,12 @@ rspamd_http_message_write_header (const gchar* mime_type, gboolean encrypted,
rspamd_printf_fstring (buf,
"%s %V HTTP/1.1\r\n"
"Connection: %s\r\n"
- "Host: %V\r\n"
+ "Host: %s\r\n"
"Content-Length: %z\r\n",
http_method_str (msg->method),
msg->url,
conn_type,
- msg->host,
+ host,
bodylen);
}
@@ -1988,12 +2061,6 @@ rspamd_http_connection_write_message_common (struct rspamd_http_connection *conn
""
"\r\n", ENCRYPTED_VERSION, bodylen);
}
-
- preludelen = rspamd_snprintf (repbuf, sizeof (repbuf), "%s\r\n"
- "Content-Length: %z\r\n"
- "Content-Type: %s\r\n"
- "\r\n", ENCRYPTED_VERSION, bodylen,
- mime_type);
}
else {
preludelen = rspamd_snprintf (repbuf, sizeof (repbuf),
@@ -2152,6 +2219,11 @@ rspamd_http_connection_write_message_common (struct rspamd_http_connection *conn
priv->flags &= ~RSPAMD_HTTP_CONN_FLAG_RESETED;
+ if (priv->flags & RSPAMD_HTTP_CONN_FLAG_PROXY) {
+ /* We need to disable SSL flag! */
+ msg->flags &=~ RSPAMD_HTTP_FLAG_SSL;
+ }
+
if (rspamd_event_pending (&priv->ev, EV_TIMEOUT|EV_WRITE|EV_READ)) {
event_del (&priv->ev);
}
diff --git a/src/libutil/http_connection.h b/src/libutil/http_connection.h
index a327eec0d..6240772da 100644
--- a/src/libutil/http_connection.h
+++ b/src/libutil/http_connection.h
@@ -118,20 +118,33 @@ struct rspamd_http_connection {
};
/**
- * Create new http connection
- * @param handler_t handler_t for body
- * @param opts options
- * @return new connection structure
+ * Creates a new HTTP server connection from an opened FD returned by accept function
+ * @param ctx
+ * @param fd
+ * @param body_handler
+ * @param error_handler
+ * @param finish_handler
+ * @param opts
+ * @return
*/
-struct rspamd_http_connection *rspamd_http_connection_new (
+struct rspamd_http_connection *rspamd_http_connection_new_server (
struct rspamd_http_context *ctx,
gint fd,
rspamd_http_body_handler_t body_handler,
rspamd_http_error_handler_t error_handler,
rspamd_http_finish_handler_t finish_handler,
- unsigned opts,
- enum rspamd_http_connection_type type);
+ unsigned opts);
+/**
+ * Creates or reuses a new keepalive client connection identified by hostname and inet_addr
+ * @param ctx
+ * @param body_handler
+ * @param error_handler
+ * @param finish_handler
+ * @param addr
+ * @param host
+ * @return
+ */
struct rspamd_http_connection *rspamd_http_connection_new_keepalive (
struct rspamd_http_context *ctx,
rspamd_http_body_handler_t body_handler,
@@ -140,6 +153,41 @@ struct rspamd_http_connection *rspamd_http_connection_new_keepalive (
rspamd_inet_addr_t *addr,
const gchar *host);
+/**
+ * Creates an ordinary connection using the address specified (if proxy is not set)
+ * @param ctx
+ * @param body_handler
+ * @param error_handler
+ * @param finish_handler
+ * @param opts
+ * @param addr
+ * @return
+ */
+struct rspamd_http_connection *rspamd_http_connection_new_client (
+ struct rspamd_http_context *ctx,
+ rspamd_http_body_handler_t body_handler,
+ rspamd_http_error_handler_t error_handler,
+ rspamd_http_finish_handler_t finish_handler,
+ unsigned opts,
+ rspamd_inet_addr_t *addr);
+
+/**
+ * Creates an ordinary client connection using ready file descriptor (ignores proxy)
+ * @param ctx
+ * @param body_handler
+ * @param error_handler
+ * @param finish_handler
+ * @param opts
+ * @param addr
+ * @return
+ */
+struct rspamd_http_connection *rspamd_http_connection_new_client_socket (
+ struct rspamd_http_context *ctx,
+ rspamd_http_body_handler_t body_handler,
+ rspamd_http_error_handler_t error_handler,
+ rspamd_http_finish_handler_t finish_handler,
+ unsigned opts,
+ gint fd);
/**
* Set key pointed by an opaque pointer
diff --git a/src/libutil/http_context.c b/src/libutil/http_context.c
index 9182285a3..b3a308891 100644
--- a/src/libutil/http_context.c
+++ b/src/libutil/http_context.c
@@ -14,12 +14,14 @@
* limitations under the License.
*/
+#include <contrib/http-parser/http_parser.h>
#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 "contrib/http-parser/http_parser.h"
#include "rspamd.h"
INIT_LOG_MODULE(http_context)
@@ -85,7 +87,8 @@ rspamd_http_context_client_rotate_ev (gint fd, short what, void *arg)
static struct rspamd_http_context*
rspamd_http_context_new_default (struct rspamd_config *cfg,
- struct event_base *ev_base)
+ struct event_base *ev_base,
+ struct upstream_ctx *ups_ctx)
{
struct rspamd_http_context *ctx;
@@ -100,6 +103,7 @@ rspamd_http_context_new_default (struct rspamd_config *cfg,
ctx->config.client_key_rotate_time = default_rotate_time;
ctx->config.user_agent = default_user_agent;
ctx->config.keepalive_interval = default_keepalive_interval;
+ ctx->ups_ctx = ups_ctx;
if (cfg) {
ctx->ssl_ctx = cfg->libs_ctx->ssl_ctx;
@@ -118,8 +122,62 @@ rspamd_http_context_new_default (struct rspamd_config *cfg,
}
static void
+rspamd_http_context_parse_proxy (struct rspamd_http_context *ctx,
+ const gchar *name,
+ struct upstream_list **pls)
+{
+ struct http_parser_url u;
+ struct upstream_list *uls;
+
+ if (!ctx->ups_ctx) {
+ msg_err ("cannot parse http_proxy %s - upstreams context is udefined", name);
+ return;
+ }
+
+ memset (&u, 0, sizeof (u));
+
+ if (http_parser_parse_url (name, strlen (name), 1, &u) == 0) {
+ if (!(u.field_set & (1u << UF_HOST)) || u.port == 0) {
+ msg_err ("cannot parse http(s) proxy %s - invalid host or port", name);
+
+ return;
+ }
+
+ uls = rspamd_upstreams_create (ctx->ups_ctx);
+
+ if (!rspamd_upstreams_parse_line_len (uls,
+ name + u.field_data[UF_HOST].off,
+ u.field_data[UF_HOST].len, u.port, NULL)) {
+ msg_err ("cannot parse http(s) proxy %s - invalid data", name);
+
+ rspamd_upstreams_destroy (uls);
+ }
+ else {
+ *pls = uls;
+ msg_info ("set http(s) proxy to %s", name);
+ }
+ }
+ else {
+ uls = rspamd_upstreams_create (ctx->ups_ctx);
+
+ if (!rspamd_upstreams_parse_line (uls,
+ name, 3128, NULL)) {
+ msg_err ("cannot parse http(s) proxy %s - invalid data", name);
+
+ rspamd_upstreams_destroy (uls);
+ }
+ else {
+ *pls = uls;
+ msg_info ("set http(s) proxy to %s", name);
+ }
+ }
+}
+
+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);
}
@@ -140,17 +198,23 @@ rspamd_http_context_init (struct rspamd_http_context *ctx)
event_add (&ctx->client_rotate_ev, &tv);
}
+ if (ctx->config.http_proxy) {
+ rspamd_http_context_parse_proxy (ctx, ctx->config.http_proxy,
+ &ctx->http_proxies);
+ }
+
default_ctx = ctx;
}
struct rspamd_http_context*
rspamd_http_context_create (struct rspamd_config *cfg,
- struct event_base *ev_base)
+ struct event_base *ev_base,
+ struct upstream_ctx *ups_ctx)
{
struct rspamd_http_context *ctx;
const ucl_object_t *http_obj;
- ctx = rspamd_http_context_new_default (cfg, ev_base);
+ ctx = rspamd_http_context_new_default (cfg, ev_base, ups_ctx);
http_obj = ucl_object_lookup (cfg->rcl_obj, "http");
if (http_obj) {
@@ -194,6 +258,13 @@ rspamd_http_context_create (struct rspamd_config *cfg,
if (keepalive_interval) {
ctx->config.keepalive_interval = ucl_object_todouble (keepalive_interval);
}
+
+ const ucl_object_t *http_proxy;
+ http_proxy = ucl_object_lookup (client_obj, "http_proxy");
+
+ if (http_proxy) {
+ ctx->config.http_proxy = ucl_object_tostring (http_proxy);
+ }
}
server_obj = ucl_object_lookup (http_obj, "server");
@@ -257,16 +328,21 @@ rspamd_http_context_free (struct rspamd_http_context *ctx)
kh_destroy (rspamd_keep_alive_hash, ctx->keep_alive_hash);
+ if (ctx->http_proxies) {
+ rspamd_upstreams_destroy (ctx->http_proxies);
+ }
+
g_free (ctx);
}
struct rspamd_http_context*
rspamd_http_context_create_config (struct rspamd_http_context_cfg *cfg,
- struct event_base *ev_base)
+ struct event_base *ev_base,
+ struct upstream_ctx *ups_ctx)
{
struct rspamd_http_context *ctx;
- ctx = rspamd_http_context_new_default (NULL, ev_base);
+ ctx = rspamd_http_context_new_default (NULL, ev_base, ups_ctx);
memcpy (&ctx->config, cfg, sizeof (*cfg));
rspamd_http_context_init (ctx);
diff --git a/src/libutil/http_context.h b/src/libutil/http_context.h
index 74e5c69a6..4cf07fb48 100644
--- a/src/libutil/http_context.h
+++ b/src/libutil/http_context.h
@@ -26,6 +26,7 @@
struct rspamd_http_context;
struct rspamd_config;
struct rspamd_http_message;
+struct upstream_ctx;
struct rspamd_http_context_cfg {
guint kp_cache_size_client;
@@ -34,6 +35,7 @@ struct rspamd_http_context_cfg {
gdouble keepalive_interval;
gdouble client_key_rotate_time;
const gchar *user_agent;
+ const gchar *http_proxy;
};
/**
@@ -43,11 +45,12 @@ struct rspamd_http_context_cfg {
* @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 event_base *ev_base, struct upstream_ctx *ctx);
struct rspamd_http_context* rspamd_http_context_create_config (
struct rspamd_http_context_cfg *cfg,
- struct event_base *ev_base);
+ struct event_base *ev_base,
+ struct upstream_ctx *ctx);
/**
* Destroys context
* @param ctx
diff --git a/src/libutil/http_message.c b/src/libutil/http_message.c
index 0720dc416..13241034c 100644
--- a/src/libutil/http_message.c
+++ b/src/libutil/http_message.c
@@ -104,7 +104,7 @@ rspamd_http_message_from_url (const gchar *url)
}
}
- msg->host = rspamd_fstring_new_init (host, pu.field_data[UF_HOST].len);
+ msg->host = g_string_new_len (host, pu.field_data[UF_HOST].len);
msg->url = rspamd_fstring_append (msg->url, path, pathlen);
REF_INIT_RETAIN (msg, rspamd_http_message_free);
@@ -489,7 +489,7 @@ rspamd_http_message_free (struct rspamd_http_message *msg)
rspamd_fstring_free (msg->status);
}
if (msg->host != NULL) {
- rspamd_fstring_free (msg->host);
+ g_string_free (msg->host, TRUE);
}
if (msg->peer_key != NULL) {
rspamd_pubkey_unref (msg->peer_key);
diff --git a/src/libutil/http_private.h b/src/libutil/http_private.h
index dd3d0c6a9..368715891 100644
--- a/src/libutil/http_private.h
+++ b/src/libutil/http_private.h
@@ -22,6 +22,7 @@
#include "keypair.h"
#include "keypairs_cache.h"
#include "ref.h"
+#include "upstream.h"
#include "khash.h"
#define HASH_CASELESS
#include "uthash_strcase.h"
@@ -42,7 +43,7 @@ struct rspamd_http_header {
*/
struct rspamd_http_message {
rspamd_fstring_t *url;
- rspamd_fstring_t *host;
+ GString *host;
rspamd_fstring_t *status;
struct rspamd_http_header *headers;
@@ -95,6 +96,8 @@ struct rspamd_http_context {
struct rspamd_keypair_cache *client_kp_cache;
struct rspamd_cryptobox_keypair *client_kp;
struct rspamd_keypair_cache *server_kp_cache;
+ struct upstream_ctx *ups_ctx;
+ struct upstream_list *http_proxies;
gpointer ssl_ctx;
gpointer ssl_ctx_noverify;
struct event_base *ev_base;
diff --git a/src/libutil/http_router.c b/src/libutil/http_router.c
index 570d3d5c6..ec0eeb7b4 100644
--- a/src/libutil/http_router.c
+++ b/src/libutil/http_router.c
@@ -506,13 +506,12 @@ rspamd_http_router_handle_socket (struct rspamd_http_connection_router *router,
conn->ud = ud;
conn->is_reply = FALSE;
- conn->conn = rspamd_http_connection_new (router->ctx,
+ conn->conn = rspamd_http_connection_new_server (router->ctx,
fd,
NULL,
rspamd_http_router_error_handler,
rspamd_http_router_finish_handler,
- 0,
- RSPAMD_HTTP_SERVER);
+ 0);
if (router->key) {
rspamd_http_connection_set_key (conn->conn, router->key);
diff --git a/src/libutil/logger.c b/src/libutil/logger.c
index 45e99f8ae..7eb00f3fa 100644
--- a/src/libutil/logger.c
+++ b/src/libutil/logger.c
@@ -925,7 +925,7 @@ file_log_function (const gchar *module, const gchar *id,
gchar *m;
gdouble now;
- struct iovec iov[5];
+ struct iovec iov[6];
gulong r = 0, mr = 0;
guint64 cksum;
size_t mlen, mremain;
diff --git a/src/libutil/map.c b/src/libutil/map.c
index d4687e433..fc414ab00 100644
--- a/src/libutil/map.c
+++ b/src/libutil/map.c
@@ -75,76 +75,62 @@ write_http_request (struct http_callback_data *cbd)
struct rspamd_map *map;
map = cbd->map;
+ msg = rspamd_http_new_message (HTTP_REQUEST);
- if (cbd->fd != -1) {
- close (cbd->fd);
+ if (cbd->bk->protocol == MAP_PROTO_HTTPS) {
+ msg->flags |= RSPAMD_HTTP_FLAG_SSL;
}
- cbd->fd = rspamd_inet_address_connect (cbd->addr, SOCK_STREAM, TRUE);
-
- if (cbd->fd != -1) {
- msg = rspamd_http_new_message (HTTP_REQUEST);
-
- if (cbd->bk->protocol == MAP_PROTO_HTTPS) {
- msg->flags |= RSPAMD_HTTP_FLAG_SSL;
- }
+ if (cbd->check) {
+ msg->method = HTTP_HEAD;
+ }
- if (cbd->check) {
- msg->method = HTTP_HEAD;
- }
+ if (cbd->stage == map_load_file) {
+ msg->url = rspamd_fstring_append (msg->url,
+ cbd->data->path, strlen (cbd->data->path));
- if (cbd->stage == map_load_file) {
- msg->url = rspamd_fstring_append (msg->url,
- cbd->data->path, strlen (cbd->data->path));
-
- if (cbd->check && cbd->stage == map_load_file) {
- if (cbd->data->last_modified != 0) {
- rspamd_http_date_format (datebuf, sizeof (datebuf),
- cbd->data->last_modified);
- rspamd_http_message_add_header (msg, "If-Modified-Since",
- datebuf);
- }
- if (cbd->data->etag) {
- rspamd_http_message_add_header_len (msg, "If-None-Match",
- cbd->data->etag->str, cbd->data->etag->len);
- }
+ if (cbd->check && cbd->stage == map_load_file) {
+ if (cbd->data->last_modified != 0) {
+ rspamd_http_date_format (datebuf, sizeof (datebuf),
+ cbd->data->last_modified);
+ rspamd_http_message_add_header (msg, "If-Modified-Since",
+ datebuf);
+ }
+ if (cbd->data->etag) {
+ rspamd_http_message_add_header_len (msg, "If-None-Match",
+ cbd->data->etag->str, cbd->data->etag->len);
}
}
- else if (cbd->stage == map_load_pubkey) {
- msg->url = rspamd_fstring_append (msg->url,
- cbd->data->path, strlen (cbd->data->path));
- msg->url = rspamd_fstring_append (msg->url, ".pub", 4);
- }
- else if (cbd->stage == map_load_signature) {
- msg->url = rspamd_fstring_append (msg->url,
- cbd->data->path, strlen (cbd->data->path));
- msg->url = rspamd_fstring_append (msg->url, ".sig", 4);
- }
- else {
- g_assert_not_reached ();
- }
-
- msg->url = rspamd_fstring_append (msg->url, cbd->data->rest,
- strlen (cbd->data->rest));
-
- if (cbd->data->userinfo) {
- rspamd_http_message_add_header (msg, "Authorization",
- cbd->data->userinfo);
- }
-
- MAP_RETAIN (cbd, "http_callback_data");
- rspamd_http_connection_write_message (cbd->conn,
- msg,
- cbd->data->host,
- NULL,
- cbd,
- &cbd->tv);
+ }
+ else if (cbd->stage == map_load_pubkey) {
+ msg->url = rspamd_fstring_append (msg->url,
+ cbd->data->path, strlen (cbd->data->path));
+ msg->url = rspamd_fstring_append (msg->url, ".pub", 4);
+ }
+ else if (cbd->stage == map_load_signature) {
+ msg->url = rspamd_fstring_append (msg->url,
+ cbd->data->path, strlen (cbd->data->path));
+ msg->url = rspamd_fstring_append (msg->url, ".sig", 4);
}
else {
- msg_err_map ("cannot connect to %s: %s", cbd->data->host,
- strerror (errno));
- cbd->periodic->errored = TRUE;
+ g_assert_not_reached ();
+ }
+
+ msg->url = rspamd_fstring_append (msg->url, cbd->data->rest,
+ strlen (cbd->data->rest));
+
+ if (cbd->data->userinfo) {
+ rspamd_http_message_add_header (msg, "Authorization",
+ cbd->data->userinfo);
}
+
+ MAP_RETAIN (cbd, "http_callback_data");
+ rspamd_http_connection_write_message (cbd->conn,
+ msg,
+ cbd->data->host,
+ NULL,
+ cbd,
+ &cbd->tv);
}
static gboolean
@@ -282,10 +268,6 @@ free_http_cbdata_common (struct http_callback_data *cbd, gboolean plan_new)
cbd->conn = NULL;
}
- if (cbd->fd != -1) {
- close (cbd->fd);
- }
-
if (cbd->addr) {
rspamd_inet_address_free (cbd->addr);
}
@@ -517,7 +499,13 @@ http_map_finish (struct rspamd_http_connection *conn,
}
}
- rspamd_http_connection_reset (cbd->conn);
+ rspamd_http_connection_unref (cbd->conn);
+ cbd->conn = rspamd_http_connection_new_client (NULL,
+ NULL,
+ http_map_error,
+ http_map_finish,
+ RSPAMD_HTTP_CLIENT_SIMPLE|RSPAMD_HTTP_CLIENT_SHARED,
+ cbd->addr);
write_http_request (cbd);
MAP_RELEASE (cbd, "http_callback_data");
@@ -563,7 +551,13 @@ http_map_finish (struct rspamd_http_connection *conn,
}
cbd->stage = map_load_signature;
- rspamd_http_connection_reset (cbd->conn);
+ rspamd_http_connection_unref (cbd->conn);
+ cbd->conn = rspamd_http_connection_new_client (NULL,
+ NULL,
+ http_map_error,
+ http_map_finish,
+ RSPAMD_HTTP_CLIENT_SIMPLE|RSPAMD_HTTP_CLIENT_SHARED,
+ cbd->addr);
write_http_request (cbd);
MAP_RELEASE (cbd, "http_callback_data");
@@ -1264,20 +1258,15 @@ rspamd_map_dns_callback (struct rdns_reply *reply, void *arg)
if (cbd->addr != NULL) {
rspamd_inet_address_set_port (cbd->addr, cbd->data->port);
- /* Try to open a socket */
- cbd->fd = rspamd_inet_address_connect (cbd->addr, SOCK_STREAM,
- TRUE);
-
- if (cbd->fd != -1) {
+ cbd->conn = rspamd_http_connection_new_client (NULL,
+ NULL,
+ http_map_error,
+ http_map_finish,
+ flags,
+ cbd->addr);
+
+ if (cbd->conn != NULL) {
cbd->stage = map_load_file;
- cbd->conn = rspamd_http_connection_new (NULL,
- cbd->fd,
- NULL,
- http_map_error,
- http_map_finish,
- flags,
- RSPAMD_HTTP_CLIENT);
-
write_http_request (cbd);
}
else {
@@ -1623,7 +1612,6 @@ check:
cbd->ev_base = map->ev_base;
cbd->map = map;
cbd->data = data;
- cbd->fd = -1;
cbd->check = check;
cbd->periodic = periodic;
MAP_RETAIN (periodic, "periodic");
@@ -1638,20 +1626,16 @@ check:
/* Send both A and AAAA requests */
if (rspamd_parse_inet_address (&cbd->addr, data->host, strlen (data->host))) {
rspamd_inet_address_set_port (cbd->addr, cbd->data->port);
- cbd->fd = rspamd_inet_address_connect (cbd->addr, SOCK_STREAM,
- TRUE);
+ cbd->conn = rspamd_http_connection_new_client (
+ NULL,
+ NULL,
+ http_map_error,
+ http_map_finish,
+ flags,
+ cbd->addr);
- if (cbd->fd != -1) {
+ if (cbd->conn != NULL) {
cbd->stage = map_load_file;
- cbd->conn = rspamd_http_connection_new (
- NULL,
- cbd->fd,
- NULL,
- http_map_error,
- http_map_finish,
- flags,
- RSPAMD_HTTP_CLIENT);
-
write_http_request (cbd);
MAP_RELEASE (cbd, "http_callback_data");
}
@@ -2685,7 +2669,7 @@ rspamd_map_add_from_ucl (struct rspamd_config *cfg,
}
}
- if (map->backends->len == 0) {
+ if (!map->backends || map->backends->len == 0) {
msg_err_config ("map has no urls to be loaded: no valid backends");
goto err;
}
diff --git a/src/libutil/map_private.h b/src/libutil/map_private.h
index 68415d0e0..b32f0e390 100644
--- a/src/libutil/map_private.h
+++ b/src/libutil/map_private.h
@@ -200,7 +200,6 @@ struct http_callback_data {
gsize pubkey_len;
enum rspamd_map_http_stage stage;
- gint fd;
struct timeval tv;
ref_entry_t ref;
diff --git a/src/libutil/mem_pool.c b/src/libutil/mem_pool.c
index 2f39a116d..a519013d1 100644
--- a/src/libutil/mem_pool.c
+++ b/src/libutil/mem_pool.c
@@ -490,9 +490,9 @@ void *
rspamd_mempool_alloc0 (rspamd_mempool_t * pool, gsize size)
{
void *pointer = rspamd_mempool_alloc (pool, size);
- if (pointer) {
- memset (pointer, 0, size);
- }
+
+ memset (pointer, 0, size);
+
return pointer;
}
@@ -500,9 +500,9 @@ void *
rspamd_mempool_alloc0_tmp (rspamd_mempool_t * pool, gsize size)
{
void *pointer = rspamd_mempool_alloc_tmp (pool, size);
- if (pointer) {
- memset (pointer, 0, size);
- }
+
+ memset (pointer, 0, size);
+
return pointer;
}
@@ -510,9 +510,8 @@ void *
rspamd_mempool_alloc0_shared (rspamd_mempool_t * pool, gsize size)
{
void *pointer = rspamd_mempool_alloc_shared (pool, size);
- if (pointer) {
- memset (pointer, 0, size);
- }
+
+ memset (pointer, 0, size);
return pointer;
}
@@ -800,7 +799,6 @@ rspamd_mempool_stat (rspamd_mempool_stat_t * st)
st->shared_chunks_allocated = mem_pool_stat->shared_chunks_allocated;
st->bytes_allocated = mem_pool_stat->bytes_allocated;
st->chunks_allocated = mem_pool_stat->chunks_allocated;
- st->shared_chunks_allocated = mem_pool_stat->shared_chunks_allocated;
st->chunks_freed = mem_pool_stat->chunks_freed;
st->oversized_chunks = mem_pool_stat->oversized_chunks;
}
diff --git a/src/libutil/multipattern.c b/src/libutil/multipattern.c
index 268170512..5f5724a0c 100644
--- a/src/libutil/multipattern.c
+++ b/src/libutil/multipattern.c
@@ -209,7 +209,6 @@ rspamd_multipattern_pattern_filter (const gchar *pattern, gsize len,
g_free (tmp);
}
else if (flags & RSPAMD_MULTIPATTERN_RE) {
- ret = malloc (len + 1);
ret = rspamd_str_regexp_escape (pattern, len, dst_len, gl_flags |
RSPAMD_REGEXP_ESCAPE_RE);
}
diff --git a/src/libutil/rrd.c b/src/libutil/rrd.c
index 95d78c7f5..d17e823e6 100644
--- a/src/libutil/rrd.c
+++ b/src/libutil/rrd.c
@@ -228,12 +228,6 @@ rspamd_rrd_check_file (const gchar *filename, gboolean need_data, GError **err)
close (fd);
return FALSE;
}
- if (memcmp (head.version, RRD_VERSION, sizeof (head.version)) != 0) {
- g_set_error (err,
- rrd_error_quark (), EINVAL, "rrd head error: invalid version");
- close (fd);
- return FALSE;
- }
if (head.float_cookie != RRD_FLOAT_COOKIE) {
g_set_error (err,
rrd_error_quark (), EINVAL, "rrd head error: another architecture "
@@ -409,16 +403,12 @@ rspamd_rrd_open_common (const gchar *filename, gboolean completed, GError **err)
file = g_malloc0 (sizeof (struct rspamd_rrd_file));
- if (file == NULL) {
- g_set_error (err, rrd_error_quark (), ENOMEM, "not enough memory");
- return NULL;
- }
-
/* Open file */
fd = rspamd_rrd_open_exclusive (filename);
if (fd == -1) {
g_set_error (err,
rrd_error_quark (), errno, "rrd open error: %s", strerror (errno));
+ g_free (file);
return FALSE;
}
@@ -426,6 +416,7 @@ rspamd_rrd_open_common (const gchar *filename, gboolean completed, GError **err)
g_set_error (err,
rrd_error_quark (), errno, "rrd stat error: %s", strerror (errno));
rspamd_file_unlock (fd, FALSE);
+ g_free (file);
close (fd);
return FALSE;
}
diff --git a/src/libutil/shingles.c b/src/libutil/shingles.c
index 70aa5fe78..4affb16c3 100644
--- a/src/libutil/shingles.c
+++ b/src/libutil/shingles.c
@@ -184,6 +184,10 @@ rspamd_shingles_from_text (GArray *input,
g_free (hashes);
+ if (pool != NULL) {
+ g_free (res);
+ }
+
return NULL;
}
diff --git a/src/libutil/upstream.c b/src/libutil/upstream.c
index 64d5291fa..3a2b803b4 100644
--- a/src/libutil/upstream.c
+++ b/src/libutil/upstream.c
@@ -788,51 +788,45 @@ rspamd_upstream_add_addr (struct upstream *up, rspamd_inet_addr_t *addr)
return TRUE;
}
+#define LEN_CHECK_STARTS_WITH(s, len, lit) \
+ ((len) >= sizeof(lit) - 1 && g_ascii_strncasecmp ((s), (lit), sizeof(lit) - 1) == 0)
gboolean
-rspamd_upstreams_parse_line (struct upstream_list *ups,
- const gchar *str, guint16 def_port, void *data)
+rspamd_upstreams_parse_line_len (struct upstream_list *ups,
+ const gchar *str, gsize len, guint16 def_port, void *data)
{
- const gchar *end = str + strlen (str), *p = str;
+ const gchar *end = str + len, *p = str;
const gchar *separators = ";, \n\r\t";
gchar *tmp;
- guint len;
+ guint span_len;
gboolean ret = FALSE;
- if (g_ascii_strncasecmp (p, "random:", sizeof ("random:") - 1) == 0) {
+ if (LEN_CHECK_STARTS_WITH(p, len, "random:")) {
ups->rot_alg = RSPAMD_UPSTREAM_RANDOM;
p += sizeof ("random:") - 1;
}
- else if (g_ascii_strncasecmp (p,
- "master-slave:",
- sizeof ("master-slave:") - 1) == 0) {
+ else if (LEN_CHECK_STARTS_WITH(p, len, "master-slave:")) {
ups->rot_alg = RSPAMD_UPSTREAM_MASTER_SLAVE;
p += sizeof ("master-slave:") - 1;
}
- else if (g_ascii_strncasecmp (p,
- "round-robin:",
- sizeof ("round-robin:") - 1) == 0) {
+ else if (LEN_CHECK_STARTS_WITH(p, len, "round-robin:")) {
ups->rot_alg = RSPAMD_UPSTREAM_ROUND_ROBIN;
p += sizeof ("round-robin:") - 1;
}
- else if (g_ascii_strncasecmp (p,
- "hash:",
- sizeof ("hash:") - 1) == 0) {
+ else if (LEN_CHECK_STARTS_WITH(p, len, "hash:")) {
ups->rot_alg = RSPAMD_UPSTREAM_HASHED;
p += sizeof ("hash:") - 1;
}
- else if (g_ascii_strncasecmp (p,
- "sequential:",
- sizeof ("sequential:") - 1) == 0) {
+ else if (LEN_CHECK_STARTS_WITH(p, len, "sequential:")) {
ups->rot_alg = RSPAMD_UPSTREAM_SEQUENTIAL;
p += sizeof ("sequential:") - 1;
}
while (p < end) {
- len = strcspn (p, separators);
+ span_len = rspamd_memcspn (p, separators, end - p);
- if (len > 0) {
- tmp = g_malloc (len + 1);
- rspamd_strlcpy (tmp, p, len + 1);
+ if (span_len > 0) {
+ tmp = g_malloc (span_len + 1);
+ rspamd_strlcpy (tmp, p, span_len + 1);
if (rspamd_upstreams_add_upstream (ups, tmp, def_port,
RSPAMD_UPSTREAM_PARSE_DEFAULT,
@@ -843,14 +837,26 @@ rspamd_upstreams_parse_line (struct upstream_list *ups,
g_free (tmp);
}
- p += len;
+ p += span_len;
/* Skip separators */
- p += strspn (p, separators);
+ if (p < end) {
+ p += rspamd_memspn (p, separators, end - p);
+ }
}
return ret;
}
+#undef LEN_CHECK_STARTS_WITH
+
+gboolean
+rspamd_upstreams_parse_line (struct upstream_list *ups,
+ const gchar *str, guint16 def_port, void *data)
+{
+ return rspamd_upstreams_parse_line_len (ups, str, strlen (str),
+ def_port, data);
+}
+
gboolean
rspamd_upstreams_from_ucl (struct upstream_list *ups,
const ucl_object_t *in, guint16 def_port, void *data)
diff --git a/src/libutil/upstream.h b/src/libutil/upstream.h
index 4db962765..75d840ce2 100644
--- a/src/libutil/upstream.h
+++ b/src/libutil/upstream.h
@@ -157,6 +157,10 @@ gboolean rspamd_upstreams_parse_line (struct upstream_list *ups,
const gchar *str, guint16 def_port, void *data);
+gboolean rspamd_upstreams_parse_line_len (struct upstream_list *ups,
+ const gchar *str, gsize len,
+ guint16 def_port,
+ void *data);
/**
* Parse upstreams list from the UCL object
* @param ups
diff --git a/src/lua/lua_common.c b/src/lua/lua_common.c
index 737455a3c..cff684aad 100644
--- a/src/lua/lua_common.c
+++ b/src/lua/lua_common.c
@@ -1940,7 +1940,6 @@ rspamd_lua_execute_lua_subprocess (lua_State *L,
msg_err ("call to subprocess failed: %v", tb);
/* Indicate error */
wlen = (1ULL << 63) + tb->len;
- g_string_free (tb, TRUE);
r = write (cbdata->sp[1], &wlen, sizeof (wlen));
if (r == -1) {
@@ -1951,6 +1950,7 @@ rspamd_lua_execute_lua_subprocess (lua_State *L,
if (r == -1) {
msg_err ("write failed: %s", strerror (errno));
}
+ g_string_free (tb, TRUE);
lua_pop (L, 1);
}
@@ -2205,9 +2205,9 @@ lua_worker_spawn_process (lua_State *L)
if (rspamd_socketpair (cbdata->sp, TRUE) == -1) {
msg_err ("cannot spawn socketpair: %s", strerror (errno));
- g_free (cbdata);
luaL_unref (L, LUA_REGISTRYINDEX, cbdata->func_cbref);
luaL_unref (L, LUA_REGISTRYINDEX, cbdata->cb_cbref);
+ g_free (cbdata);
return 0;
}
diff --git a/src/lua/lua_config.c b/src/lua/lua_config.c
index e846fd4d7..91c648e6f 100644
--- a/src/lua/lua_config.c
+++ b/src/lua/lua_config.c
@@ -3900,13 +3900,19 @@ lua_config_init_subsystem (lua_State *L)
cfg);
}
else {
+ g_strfreev (parts);
+
return luaL_error (L, "no event base specified");
}
}
else {
+ g_strfreev (parts);
+
return luaL_error (L, "invalid param: %s", parts[i]);
}
}
+
+ g_strfreev (parts);
}
else {
return luaL_error (L, "invalid arguments");
diff --git a/src/lua/lua_html.c b/src/lua/lua_html.c
index 63839c286..1b5828564 100644
--- a/src/lua/lua_html.c
+++ b/src/lua/lua_html.c
@@ -249,9 +249,6 @@ lua_html_has_property (lua_State *L)
else if (strcmp (propname, "unbalanced") == 0) {
ret = hc->flags & RSPAMD_HTML_FLAG_UNBALANCED;
}
- else if (strcmp (propname, "unbalanced") == 0) {
- ret = hc->flags & RSPAMD_HTML_FLAG_UNBALANCED;
- }
else if (strcmp (propname, "data_urls") == 0) {
ret = hc->flags & RSPAMD_HTML_FLAG_HAS_DATA_URLS;
}
diff --git a/src/lua/lua_http.c b/src/lua/lua_http.c
index 4378aea89..a7b8c0a89 100644
--- a/src/lua/lua_http.c
+++ b/src/lua/lua_http.c
@@ -127,10 +127,6 @@ lua_http_fin (gpointer arg)
g_free (cbd->mime_type);
}
- if (cbd->host) {
- g_free (cbd->host);
- }
-
if (cbd->auth) {
g_free (cbd->auth);
}
@@ -368,8 +364,6 @@ lua_http_resume_handler (struct rspamd_http_connection *conn,
static gboolean
lua_http_make_connection (struct lua_http_cbdata *cbd)
{
- int fd;
-
rspamd_inet_address_set_port (cbd->addr, cbd->msg->port);
if (cbd->flags & RSPAMD_LUA_HTTP_FLAG_KEEP_ALIVE) {
@@ -384,22 +378,14 @@ lua_http_make_connection (struct lua_http_cbdata *cbd)
cbd->host);
}
else {
- fd = rspamd_inet_address_connect (cbd->addr, SOCK_STREAM, TRUE);
-
- if (fd == -1) {
- msg_info ("cannot connect to %V", cbd->msg->host);
- return FALSE;
- }
-
- cbd->fd = fd;
- cbd->conn = rspamd_http_connection_new (
+ cbd->fd = -1;
+ cbd->conn = rspamd_http_connection_new_client (
NULL, /* Default context */
- fd,
NULL,
lua_http_error_handler,
lua_http_finish_handler,
RSPAMD_HTTP_CLIENT_SIMPLE,
- RSPAMD_HTTP_CLIENT);
+ cbd->addr);
}
if (cbd->conn) {
@@ -536,6 +522,7 @@ lua_http_push_headers (lua_State *L, struct rspamd_http_message *msg)
* @param {resolver} resolver to perform DNS-requests. Usually got from either `task` or `config`
* @param {boolean} gzip if true, body of the requests will be compressed
* @param {boolean} no_ssl_verify disable SSL peer checks
+ * @param {boolean} keepalive enable keep-alive pool
* @param {string} user for HTTP authentication
* @param {string} password for HTTP authentication, only if "user" present
* @return {boolean} `true`, in **async** mode, if a request has been successfully scheduled. If this value is `false` then some error occurred, the callback thus will not be called.
@@ -751,6 +738,10 @@ lua_http_request (lua_State *L)
rspamd_fstring_free (body);
}
+ if (mime_type) {
+ g_free (mime_type);
+ }
+
return luaL_error (L, "invalid body argument: %s",
lua_typename (L, lua_type (L, -1)));
}
@@ -940,7 +931,7 @@ lua_http_request (lua_State *L)
}
if (msg->host) {
- cbd->host = rspamd_fstring_cstr (msg->host);
+ cbd->host = msg->host->str;
}
if (body) {
diff --git a/src/lua/lua_task.c b/src/lua/lua_task.c
index 8e1a851b4..b5ed7dd19 100644
--- a/src/lua/lua_task.c
+++ b/src/lua/lua_task.c
@@ -424,6 +424,16 @@ LUA_FUNCTION_DEF (task, get_recipients);
* @return {string} principal recipient
*/
LUA_FUNCTION_DEF (task, get_principal_recipient);
+/***
+ * @method task:get_reply_sender()
+ * Returns a single string with address that should be used to reply on a message
+ *
+ * - reply-to header
+ * - from header
+ * - smtp from as a last resort
+ * @return {address} email address
+ */
+LUA_FUNCTION_DEF (task, get_reply_sender);
/***
* @method task:set_recipients([type], {rcpt1, rcpt2...})
@@ -1039,6 +1049,7 @@ static const struct luaL_reg tasklib_m[] = {
LUA_INTERFACE_DEF (task, get_recipients),
LUA_INTERFACE_DEF (task, set_recipients),
LUA_INTERFACE_DEF (task, get_principal_recipient),
+ LUA_INTERFACE_DEF (task, get_reply_sender),
LUA_INTERFACE_DEF (task, has_from),
LUA_INTERFACE_DEF (task, get_from),
LUA_INTERFACE_DEF (task, set_from),
@@ -3275,6 +3286,44 @@ lua_task_get_principal_recipient (lua_State *L)
}
static gint
+lua_task_get_reply_sender (lua_State *L)
+{
+ LUA_TRACE_POINT;
+ struct rspamd_task *task = lua_check_task (L, 1);
+ struct rspamd_mime_header *rh;
+
+ if (task) {
+ GPtrArray *ar;
+
+ ar = rspamd_message_get_header_array (task, "Reply-To", false);
+
+ if (ar && ar->len == 1) {
+ rh = (struct rspamd_mime_header *)g_ptr_array_index (ar, 0);
+ lua_pushstring (L, rh->decoded);
+ }
+ else if (task->from_mime && task->from_mime->len == 1) {
+ struct rspamd_email_address *addr;
+
+ addr = (struct rspamd_email_address *)g_ptr_array_index (task->from_mime, 0);
+
+ lua_pushlstring (L, addr->addr, addr->addr_len);
+ }
+ else if (task->from_envelope) {
+ lua_pushlstring (L, task->from_envelope->addr,
+ task->from_envelope->addr_len);
+ }
+ else {
+ lua_pushnil (L);
+ }
+ }
+ else {
+ return luaL_error (L, "invalid arguments");
+ }
+
+ return 1;
+}
+
+static gint
lua_task_get_user (lua_State *L)
{
LUA_TRACE_POINT;
diff --git a/src/lua/lua_thread_pool.c b/src/lua/lua_thread_pool.c
index ec9bfbe6f..d10f64579 100644
--- a/src/lua/lua_thread_pool.c
+++ b/src/lua/lua_thread_pool.c
@@ -305,7 +305,7 @@ lua_resume_thread_internal_full (struct thread_entry *thread_entry,
}
else {
tb = rspamd_lua_get_traceback_string (thread_entry->lua_state);
- if (thread_entry->error_callback) {
+ if (tb && thread_entry->error_callback) {
thread_entry->error_callback (thread_entry, ret, tb->str);
}
else if (thread_entry->task) {
diff --git a/src/lua/lua_udp.c b/src/lua/lua_udp.c
index aac22695f..8a862f16a 100644
--- a/src/lua/lua_udp.c
+++ b/src/lua/lua_udp.c
@@ -35,7 +35,7 @@ rspamd_config.SYM = function(task)
udp.sento{
host = addr, -- must be ip address object (e.g. received by upstream module)
port = 500,
- data = {'str1, 'str2'}, -- can be table, string or rspamd_text
+ data = {'str1', 'str2'}, -- can be table, string or rspamd_text
timeout = 0.5, -- default = 1s
task = task, -- if has task
session = session, -- optional
diff --git a/src/lua/lua_util.c b/src/lua/lua_util.c
index 0a1fc2010..1a37eaef6 100644
--- a/src/lua/lua_util.c
+++ b/src/lua/lua_util.c
@@ -1197,7 +1197,7 @@ lua_util_tokenize_text (lua_State *L)
{
LUA_TRACE_POINT;
const gchar *in = NULL;
- gsize len, pos, ex_len, i;
+ gsize len = 0, pos, ex_len, i;
GList *exceptions = NULL, *cur;
struct rspamd_lua_text *t;
struct rspamd_process_exception *ex;
@@ -2263,6 +2263,8 @@ lua_util_gzip_decompress (lua_State *L)
return luaL_error (L, "invalid arguments");
}
+ sz = t->len;
+
memset (&strm, 0, sizeof (strm));
/* windowBits +16 to decode gzip, zlib 1.2.0.4+ */
rc = inflateInit2 (&strm, MAX_WBITS + 16);
diff --git a/src/plugins/fuzzy_check.c b/src/plugins/fuzzy_check.c
index 672a6dc63..a0e4df012 100644
--- a/src/plugins/fuzzy_check.c
+++ b/src/plugins/fuzzy_check.c
@@ -1875,6 +1875,8 @@ fuzzy_insert_result (struct fuzzy_client_session *session,
struct fuzzy_client_result *res;
gboolean is_fuzzy = FALSE;
gchar hexbuf[rspamd_cryptobox_HASHBYTES * 2 + 1];
+ /* Discriminate scores for small images */
+ static const guint short_image_limit = 32 * 1024;
/* Get mapping by flag */
if ((map =
@@ -1902,7 +1904,10 @@ fuzzy_insert_result (struct fuzzy_client_session *session,
nval = fuzzy_normalize (rep->v1.value, weight);
if (io && (io->flags & FUZZY_CMD_FLAG_IMAGE)) {
- nval *= rspamd_normalize_probability (rep->v1.prob, 0.5);
+ if (!io->part || io->part->parsed_data.len <= short_image_limit) {
+ nval *= rspamd_normalize_probability (rep->v1.prob, 0.5);
+ }
+
type = "img";
res->type = FUZZY_RESULT_IMG;
}
diff --git a/src/plugins/lua/greylist.lua b/src/plugins/lua/greylist.lua
index 5a1f6c0f9..1ba80dd80 100644
--- a/src/plugins/lua/greylist.lua
+++ b/src/plugins/lua/greylist.lua
@@ -44,7 +44,7 @@ end
local redis_params
local whitelisted_ip
local whitelist_domains_map
-local toint =math.ifloor or math.floor
+local toint = math.ifloor or math.floor
local settings = {
expire = 86400, -- 1 day by default
timeout = 300, -- 5 minutes by default
@@ -53,6 +53,7 @@ local settings = {
message = 'Try again later', -- default greylisted message
symbol = 'GREYLIST',
action = 'soft reject', -- default greylisted action
+ whitelist_symbols = {}, -- whitelist when specific symbols have been found
ipv4_mask = 19, -- Mask bits for ipv4
ipv6_mask = 64, -- Mask bits for ipv6
report_time = false, -- Tell when greylisting is epired (appended to `message`)
@@ -65,6 +66,7 @@ local rspamd_util = require "rspamd_util"
local fun = require "fun"
local hash = require "rspamd_cryptobox_hash"
local rspamd_lua_utils = require "lua_util"
+local lua_map = require "lua_map"
local N = "greylist"
local function data_key(task)
@@ -276,6 +278,19 @@ local function greylist_set(task)
-- Don't do anything if pre-result has been already set
if task:has_pre_result() then return end
+ -- Check whitelist_symbols
+ for _,sym in ipairs(settings.whitelist_symbols) do
+ if task:has_symbol(sym) then
+ rspamd_logger.infox(task, 'skip greylisting as we have found symbol %s', sym)
+ if action == 'greylist' then
+ -- We are going to accept message
+ rspamd_logger.infox(task, 'downgrading metric action from "greylist" to "no action"')
+ task:disable_action('greylist')
+ end
+ return
+ end
+ end
+
if settings.greylist_min_score then
local score = task:get_metric_score('default')[1]
if score < settings.greylist_min_score then
@@ -438,12 +453,12 @@ if opts then
end
end
- whitelisted_ip = rspamd_map_add('greylist', 'whitelisted_ip', 'radix',
+ whitelisted_ip = lua_map.rspamd_map_add(N, 'whitelisted_ip', 'radix',
'Greylist whitelist ip map')
- whitelist_domains_map = rspamd_map_add('greylist', 'whitelist_domains_url',
+ whitelist_domains_map = lua_map.rspamd_map_add(N, 'whitelist_domains_url',
'map', 'Greylist whitelist domains map')
- redis_params = rspamd_parse_redis_server('greylist')
+ redis_params = rspamd_parse_redis_server(N)
if not redis_params then
rspamd_logger.infox(rspamd_config, 'no servers are specified, disabling module')
rspamd_lua_utils.disable_module(N, "redis")
diff --git a/src/plugins/lua/neural.lua b/src/plugins/lua/neural.lua
index 43d7bb127..4e268962c 100644
--- a/src/plugins/lua/neural.lua
+++ b/src/plugins/lua/neural.lua
@@ -680,6 +680,8 @@ local function train_ann(rule, _, ev_base, elt, worker)
return st
end
+ rule.learning_spawned = true
+
worker:spawn_process{
func = train_torch,
on_complete = ann_trained_torch,
diff --git a/src/plugins/lua/replies.lua b/src/plugins/lua/replies.lua
index 234a41ca3..48c760eed 100644
--- a/src/plugins/lua/replies.lua
+++ b/src/plugins/lua/replies.lua
@@ -32,6 +32,7 @@ local settings = {
action = nil,
expire = 86400, -- 1 day by default
key_prefix = 'rr',
+ key_size = 20,
message = 'Message is reply to one we originated',
symbol = 'REPLY',
score = -4, -- Default score
@@ -45,21 +46,49 @@ local settings = {
local N = "replies"
-local function make_key(goop)
+local function make_key(goop, sz, prefix)
local h = hash.create()
h:update(goop)
- local key = h:base32():sub(1, 20)
- key = settings['key_prefix'] .. key
+ local key
+ if sz then
+ key = h:base32():sub(1, sz)
+ else
+ key = h:base32()
+ end
+
+ if prefix then
+ key = prefix .. key
+ end
+
return key
end
local function replies_check(task)
+ local function check_recipient(stored_rcpt)
+ local real_rcpt = task:get_principal_recipient()
+
+ if real_rcpt then
+ local real_rcpt_h = make_key(real_rcpt:lower(), 8)
+ if real_rcpt_h == stored_rcpt then
+ return true
+ end
+
+ rspamd_logger.infox(task, 'ignoring reply as recipient %s is not matching hash %s',
+ real_rcpt, stored_rcpt)
+ else
+ rspamd_logger.infox(task, 'ignoring reply as recipient cannot be detected for hash %s',
+ stored_rcpt)
+ end
+
+ return false
+ end
+
local function redis_get_cb(err, data)
if err ~= nil then
rspamd_logger.errx(task, 'redis_get_cb received error: %1', err)
return
end
- if data == '1' then
+ if data and check_recipient(data) then
-- Hash was found
task:insert_result(settings['symbol'], 1.0)
if settings['action'] ~= nil then
@@ -80,7 +109,7 @@ local function replies_check(task)
return
end
-- Create hash of in-reply-to and query redis
- local key = make_key(irt)
+ local key = make_key(irt, settings.key_size, settings.key_prefix)
local ret = lua_redis.redis_make_request(task,
redis_params, -- connect params
@@ -117,18 +146,26 @@ local function replies_set(task)
return
end
-- Create hash of message-id and store to redis
- local key = make_key(msg_id)
+ local key = make_key(msg_id, settings.key_size, settings.key_prefix)
lua_util.debugm(N, task, 'storing message-id for replies check')
- local ret = lua_redis.redis_make_request(task,
- redis_params, -- connect params
- key, -- hash key
- true, -- is write
- redis_set_cb, --callback
- 'SETEX', -- command
- {key, tostring(settings['expire']), "1"} -- arguments
- )
- if not ret then
- rspamd_logger.errx(task, "redis request wasn't scheduled")
+
+ local value = task:get_reply_sender()
+
+ if value then
+ value = make_key(value:lower(), 8)
+ local ret = lua_redis.redis_make_request(task,
+ redis_params, -- connect params
+ key, -- hash key
+ true, -- is write
+ redis_set_cb, --callback
+ 'SETEX', -- command
+ {key, tostring(settings['expire']), value:lower()} -- arguments
+ )
+ if not ret then
+ rspamd_logger.errx(task, "redis request wasn't scheduled")
+ end
+ else
+ rspamd_logger.infox(task, "cannot find reply sender address")
end
end
diff --git a/src/plugins/surbl.c b/src/plugins/surbl.c
index e5080b864..11d3e35d9 100644
--- a/src/plugins/surbl.c
+++ b/src/plugins/surbl.c
@@ -125,7 +125,6 @@ struct redirector_param {
GHashTable *tree;
struct suffix_item *suffix;
struct rspamd_symcache_item *item;
- gint sock;
guint redirector_requests;
};
@@ -1362,10 +1361,8 @@ format_surbl_request (rspamd_mempool_t * pool,
}
}
- if (url->surbl == NULL) {
- url->surbl = result;
- url->surbllen = r;
- }
+ url->surbl = result;
+ url->surbllen = r;
if (!forced &&
rspamd_match_hash_map (surbl_module_ctx->whitelist, result) != NULL) {
@@ -1691,7 +1688,6 @@ free_redirector_session (void *ud)
}
rspamd_http_connection_unref (param->conn);
- close (param->sock);
}
static void
@@ -1782,7 +1778,6 @@ static void
register_redirector_call (struct rspamd_url *url, struct rspamd_task *task,
const gchar *rule)
{
- gint s = -1;
struct redirector_param *param;
struct timeval *timeout;
struct upstream *selected;
@@ -1793,13 +1788,19 @@ register_redirector_call (struct rspamd_url *url, struct rspamd_task *task,
selected = rspamd_upstream_get (surbl_module_ctx->redirectors,
RSPAMD_UPSTREAM_ROUND_ROBIN, url->host, url->hostlen);
+ param = rspamd_mempool_alloc0 (task->task_pool,
+ sizeof (struct redirector_param));
if (selected) {
- s = rspamd_inet_address_connect (rspamd_upstream_addr_next (selected),
- SOCK_STREAM, TRUE);
+ param->conn = rspamd_http_connection_new_client (NULL,
+ NULL,
+ surbl_redirector_error,
+ surbl_redirector_finish,
+ RSPAMD_HTTP_CLIENT_SIMPLE,
+ rspamd_upstream_addr_next (selected));
}
- if (s == -1) {
+ if (param->conn == NULL) {
msg_info_surbl ("<%s> cannot create tcp socket failed: %s",
task->message_id,
strerror (errno));
@@ -1807,22 +1808,12 @@ register_redirector_call (struct rspamd_url *url, struct rspamd_task *task,
return;
}
- param =
- rspamd_mempool_alloc (task->task_pool,
- sizeof (struct redirector_param));
+
param->url = url;
param->task = task;
- param->conn = rspamd_http_connection_new (NULL,
- s,
- NULL,
- surbl_redirector_error,
- surbl_redirector_finish,
- RSPAMD_HTTP_CLIENT_SIMPLE,
- RSPAMD_HTTP_CLIENT);
param->ctx = surbl_module_ctx;
msg = rspamd_http_new_message (HTTP_REQUEST);
msg->url = rspamd_fstring_assign (msg->url, url->string, url->urllen);
- param->sock = s;
param->redirector = selected;
timeout = rspamd_mempool_alloc (task->task_pool, sizeof (struct timeval));
double_to_tv (surbl_module_ctx->read_timeout, timeout);
@@ -1866,9 +1857,6 @@ surbl_test_tags (struct rspamd_task *task, struct redirector_param *param,
tld.len = url->tldlen;
ftld = rspamd_mempool_ftokdup (task->task_pool, &tld);
- }
-
- if (tag) {
/* We know results for this URL */
DL_FOREACH (tag, cur) {
@@ -2199,9 +2187,9 @@ surbl_is_redirector_handler (lua_State *L)
task = lua_check_task (L, 1);
url = luaL_checklstring (L, 2, &len);
- surbl_module_ctx = surbl_get_context (task->cfg);
if (task && url) {
+ surbl_module_ctx = surbl_get_context (task->cfg);
url_cpy = rspamd_mempool_alloc (task->task_pool, len);
memcpy (url_cpy, url, len);
diff --git a/src/rspamadm/control.c b/src/rspamadm/control.c
index 0a242e943..1311622c3 100644
--- a/src/rspamadm/control.c
+++ b/src/rspamadm/control.c
@@ -175,7 +175,6 @@ rspamadm_control (gint argc, gchar **argv, const struct rspamadm_command *_cmd)
rspamd_inet_addr_t *addr;
struct timeval tv;
static struct rspamadm_control_cbdata cbdata;
- gint sock;
context = g_option_context_new (
"control - manage rspamd main control interface");
@@ -230,22 +229,14 @@ rspamadm_control (gint argc, gchar **argv, const struct rspamadm_command *_cmd)
exit (1);
}
- sock = rspamd_inet_address_connect (addr, SOCK_STREAM, TRUE);
- if (sock == -1) {
- rspamd_fprintf (stderr, "cannot connect to: %s\n", control_path);
- rspamd_inet_address_free (addr);
- exit (1);
- }
-
- conn = rspamd_http_connection_new (
+ conn = rspamd_http_connection_new_client (
rspamd_main->http_ctx, /* Default context */
- sock,
NULL,
rspamd_control_error_handler,
rspamd_control_finish_handler,
RSPAMD_HTTP_CLIENT_SIMPLE,
- RSPAMD_HTTP_CLIENT);
+ addr);
msg = rspamd_http_new_message (HTTP_REQUEST);
msg->url = rspamd_fstring_new_init (path, strlen (path));
double_to_tv (timeout, &tv);
@@ -261,5 +252,4 @@ rspamadm_control (gint argc, gchar **argv, const struct rspamadm_command *_cmd)
rspamd_http_connection_unref (conn);
rspamd_inet_address_free (addr);
- close (sock);
}
diff --git a/src/rspamadm/rspamadm.c b/src/rspamadm/rspamadm.c
index c0bb4bc72..c49853ef7 100644
--- a/src/rspamadm/rspamadm.c
+++ b/src/rspamadm/rspamadm.c
@@ -436,7 +436,8 @@ main (gint argc, gchar **argv, gchar **env)
(void) dns_resolver_init (rspamd_main->logger,
rspamd_main->ev_base,
cfg);
- rspamd_main->http_ctx = rspamd_http_context_create (cfg, rspamd_main->ev_base);
+ rspamd_main->http_ctx = rspamd_http_context_create (cfg, rspamd_main->ev_base,
+ NULL);
g_log_set_default_handler (rspamd_glib_log_function, rspamd_main->logger);
g_set_printerr_handler (rspamd_glib_printerr_function);
diff --git a/src/rspamd.c b/src/rspamd.c
index 27ba5e032..142915df9 100644
--- a/src/rspamd.c
+++ b/src/rspamd.c
@@ -1490,7 +1490,7 @@ main (gint argc, gchar **argv, gchar **env)
rspamd_mempool_unlock_mutex (rspamd_main->start_mtx);
rspamd_main->http_ctx = rspamd_http_context_create (rspamd_main->cfg,
- ev_base);
+ ev_base, rspamd_main->cfg->ups_ctx);
if (control_fd != -1) {
msg_info_main ("listening for control commands on %s",
diff --git a/src/rspamd_proxy.c b/src/rspamd_proxy.c
index b6ede29b9..446552b81 100644
--- a/src/rspamd_proxy.c
+++ b/src/rspamd_proxy.c
@@ -1404,14 +1404,13 @@ proxy_open_mirror_connections (struct rspamd_proxy_session *session)
rspamd_http_message_add_header (msg, "Settings-ID", m->settings_id);
}
- bk_conn->backend_conn = rspamd_http_connection_new (
+ bk_conn->backend_conn = rspamd_http_connection_new_client_socket (
session->ctx->http_ctx,
- bk_conn->backend_sock,
NULL,
proxy_backend_mirror_error_handler,
proxy_backend_mirror_finish_handler,
RSPAMD_HTTP_CLIENT_SIMPLE,
- RSPAMD_HTTP_CLIENT);
+ bk_conn->backend_sock);
if (m->key) {
msg->peer_key = rspamd_pubkey_ref (m->key);
@@ -1831,14 +1830,13 @@ retry:
goto err; /* No fallback here */
}
- session->master_conn->backend_conn = rspamd_http_connection_new (
+ session->master_conn->backend_conn = rspamd_http_connection_new_client_socket (
session->ctx->http_ctx,
- session->master_conn->backend_sock,
NULL,
proxy_backend_master_error_handler,
proxy_backend_master_finish_handler,
RSPAMD_HTTP_CLIENT_SIMPLE,
- RSPAMD_HTTP_CLIENT);
+ session->master_conn->backend_sock);
session->master_conn->flags &= ~RSPAMD_BACKEND_CLOSED;
session->master_conn->parser_from_ref = backend->parser_from_ref;
session->master_conn->parser_to_ref = backend->parser_to_ref;
@@ -2082,14 +2080,13 @@ proxy_accept_socket (gint fd, short what, void *arg)
}
if (!ctx->milter) {
- session->client_conn = rspamd_http_connection_new (
+ session->client_conn = rspamd_http_connection_new_server (
ctx->http_ctx,
nfd,
NULL,
proxy_client_error_handler,
proxy_client_finish_handler,
- 0,
- RSPAMD_HTTP_SERVER);
+ 0);
if (ctx->key) {
rspamd_http_connection_set_key (session->client_conn, ctx->key);
@@ -2180,7 +2177,8 @@ start_rspamd_proxy (struct rspamd_worker *worker)
rspamd_upstreams_library_config (worker->srv->cfg, ctx->cfg->ups_ctx,
ctx->ev_base, ctx->resolver->r);
- ctx->http_ctx = rspamd_http_context_create (ctx->cfg, ctx->ev_base);
+ ctx->http_ctx = rspamd_http_context_create (ctx->cfg, ctx->ev_base,
+ ctx->cfg->ups_ctx);
if (ctx->has_self_scan) {
/* Additional initialisation needed */
diff --git a/src/worker.c b/src/worker.c
index d81be54a1..40e3d07f9 100644
--- a/src/worker.c
+++ b/src/worker.c
@@ -412,14 +412,13 @@ accept_socket (gint fd, short what, void *arg)
http_opts = RSPAMD_HTTP_REQUIRE_ENCRYPTION;
}
- task->http_conn = rspamd_http_connection_new (
+ task->http_conn = rspamd_http_connection_new_server (
ctx->http_ctx,
nfd,
rspamd_worker_body_handler,
rspamd_worker_error_handler,
rspamd_worker_finish_handler,
- http_opts,
- RSPAMD_HTTP_SERVER);
+ http_opts);
rspamd_http_connection_set_max_size (task->http_conn, task->cfg->max_message);
worker->nconns++;
rspamd_mempool_add_destructor (task->task_pool,
@@ -693,7 +692,8 @@ start_worker (struct rspamd_worker *worker)
rspamd_upstreams_library_config (worker->srv->cfg, ctx->cfg->ups_ctx,
ctx->ev_base, ctx->resolver->r);
- ctx->http_ctx = rspamd_http_context_create (ctx->cfg, ctx->ev_base);
+ ctx->http_ctx = rspamd_http_context_create (ctx->cfg, ctx->ev_base,
+ ctx->cfg->ups_ctx);
rspamd_worker_init_scanner (worker, ctx->ev_base, ctx->resolver,
&ctx->lang_det);
rspamd_lua_run_postloads (ctx->cfg->lua_state, ctx->cfg, ctx->ev_base,