aboutsummaryrefslogtreecommitdiffstats
path: root/src/rspamd_proxy.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/rspamd_proxy.c')
-rw-r--r--src/rspamd_proxy.c111
1 files changed, 75 insertions, 36 deletions
diff --git a/src/rspamd_proxy.c b/src/rspamd_proxy.c
index 5728419b9..5edd682e5 100644
--- a/src/rspamd_proxy.c
+++ b/src/rspamd_proxy.c
@@ -846,21 +846,17 @@ proxy_session_dtor (struct rspamd_proxy_session *session)
if (session->master_conn) {
proxy_backend_close_connection (session->master_conn);
}
- else if (session->client_milter_conn) {
- rspamd_milter_session_unref (session->client_milter_conn);
- }
- if (session->map && session->map_len) {
- munmap (session->map, session->map_len);
+ if (session->client_milter_conn) {
+ rspamd_milter_session_unref (session->client_milter_conn);
}
-
- if (session->client_conn) {
+ else if (session->client_conn) {
rspamd_http_connection_reset (session->client_conn);
rspamd_http_connection_unref (session->client_conn);
}
- if (session->client_milter_conn) {
- rspamd_milter_session_unref (session->client_milter_conn);
+ if (session->map && session->map_len) {
+ munmap (session->map, session->map_len);
}
for (i = 0; i < session->mirror_conns->len; i ++) {
@@ -888,12 +884,46 @@ proxy_session_dtor (struct rspamd_proxy_session *session)
g_ptr_array_free (session->mirror_conns, TRUE);
rspamd_http_message_shmem_unref (session->shmem_ref);
rspamd_http_message_unref (session->client_message);
- rspamd_inet_address_free (session->client_addr);
- close (session->client_sock);
- rspamd_mempool_delete (session->pool);
+
+ if (session->client_addr) {
+ rspamd_inet_address_free (session->client_addr);
+ }
+
+ if (session->client_sock != -1) {
+ close (session->client_sock);
+ }
+
+ if (session->pool) {
+ rspamd_mempool_delete (session->pool);
+ }
+
g_slice_free1 (sizeof (*session), session);
}
+static struct rspamd_proxy_session *
+proxy_session_refresh (struct rspamd_proxy_session *session)
+{
+ struct rspamd_proxy_session *nsession;
+
+ nsession = g_slice_alloc0 (sizeof (*nsession));
+ nsession->client_milter_conn = session->client_milter_conn;
+ session->client_milter_conn = NULL;
+ rspamd_milter_update_userdata (nsession->client_milter_conn,
+ nsession);
+ nsession->client_addr = session->client_addr;
+ session->client_addr = NULL;
+ nsession->ctx = session->ctx;
+ nsession->worker = session->worker;
+ nsession->pool = rspamd_mempool_new (rspamd_mempool_suggest_size (), "proxy");
+ nsession->client_sock = session->client_sock;
+ session->client_sock = -1;
+ nsession->mirror_conns = g_ptr_array_sized_new (nsession->ctx->mirrors->len);
+
+ REF_INIT_RETAIN (nsession, proxy_session_dtor);
+
+ return nsession;
+}
+
static gboolean
proxy_check_file (struct rspamd_http_message *msg,
struct rspamd_proxy_session *session)
@@ -1149,6 +1179,7 @@ proxy_client_write_error (struct rspamd_proxy_session *session, gint code,
if (session->client_milter_conn) {
rspamd_milter_send_action (session->client_milter_conn,
RSPAMD_MILTER_TEMPFAIL);
+ REF_RELEASE (session);
}
else {
reply = rspamd_http_new_message (HTTP_RESPONSE);
@@ -1202,7 +1233,7 @@ proxy_backend_master_finish_handler (struct rspamd_http_connection *conn,
struct rspamd_http_message *msg)
{
struct rspamd_proxy_backend_connection *bk_conn = conn->ud;
- struct rspamd_proxy_session *session;
+ struct rspamd_proxy_session *session, *nsession;
rspamd_fstring_t *reply;
session = bk_conn->s;
@@ -1238,8 +1269,10 @@ proxy_backend_master_finish_handler (struct rspamd_http_connection *conn,
/*
* TODO: convert reply to milter reply
*/
- rspamd_milter_send_action (session->client_milter_conn,
+ nsession = proxy_session_refresh (session);
+ rspamd_milter_send_action (nsession->client_milter_conn,
RSPAMD_MILTER_ACCEPT);
+ REF_RELEASE (session);
}
else {
rspamd_http_connection_write_message (session->client_conn,
@@ -1254,7 +1287,7 @@ static void
rspamd_proxy_scan_self_reply (struct rspamd_task *task)
{
struct rspamd_http_message *msg;
- struct rspamd_proxy_session *session = task->fin_arg;
+ struct rspamd_proxy_session *session = task->fin_arg, *nsession;
ucl_object_t *rep;
const char *ctype = "application/json";
@@ -1289,8 +1322,10 @@ rspamd_proxy_scan_self_reply (struct rspamd_task *task)
/*
* TODO: convert reply to milter reply
*/
- rspamd_milter_send_action (session->client_milter_conn,
+ nsession = proxy_session_refresh (session);
+ rspamd_milter_send_action (nsession->client_milter_conn,
RSPAMD_MILTER_ACCEPT);
+ REF_RELEASE (session);
}
else {
rspamd_http_connection_reset (session->client_conn);
@@ -1499,9 +1534,16 @@ retry:
return TRUE;
err:
- rspamd_http_connection_steal_msg (session->client_conn);
- rspamd_http_connection_reset (session->client_conn);
- proxy_client_write_error (session, 404, "Backend not found");
+ if (session->client_milter_conn) {
+ rspamd_milter_send_action (session->client_milter_conn,
+ RSPAMD_MILTER_TEMPFAIL);
+ REF_RELEASE (session);
+ }
+ else {
+ rspamd_http_connection_steal_msg (session->client_conn);
+ rspamd_http_connection_reset (session->client_conn);
+ proxy_client_write_error (session, 404, "Backend not found");
+ }
return FALSE;
}
@@ -1582,29 +1624,26 @@ proxy_milter_finish_handler (gint fd,
struct rspamd_proxy_session *session = ud;
struct rspamd_http_message *msg;
- if (!session->master_conn) {
+ if (rms->message == NULL || rms->message->len == 0) {
+ msg_info_session ("finished milter connection");
+ proxy_backend_close_connection (session->master_conn);
+ REF_RELEASE (session);
+ }
+ else {
+ if (!session->master_conn) {
+ session->master_conn = rspamd_mempool_alloc0 (session->pool,
+ sizeof (*session->master_conn));
+ }
+
session->client_milter_conn = rms;
msg = rspamd_milter_to_http (rms);
- session->master_conn = rspamd_mempool_alloc0 (session->pool,
- sizeof (*session->master_conn));
+
session->master_conn->s = session;
session->master_conn->name = "master";
session->client_message = msg;
- if (msg->body_buf.len == 0) {
- msg_info_session ("incomplete master connection");
- proxy_backend_close_connection (session->master_conn);
- REF_RELEASE (session);
- }
- else {
- proxy_open_mirror_connections (session);
- proxy_send_master_message (session);
- }
- }
- else {
- msg_info_session ("finished master connection");
- proxy_backend_close_connection (session->master_conn);
- REF_RELEASE (session);
+ proxy_open_mirror_connections (session);
+ proxy_send_master_message (session);
}
}