From e629bf1721232d76b5f64f809e44f3b69a0309d7 Mon Sep 17 00:00:00 2001 From: Vsevolod Stakhov Date: Fri, 28 Apr 2017 18:01:14 +0100 Subject: [PATCH] [Minor] Add destructor for milter session --- src/libserver/milter.c | 108 +++++++++++++++++++++++++++++++- src/libserver/milter_internal.h | 1 - 2 files changed, 105 insertions(+), 4 deletions(-) diff --git a/src/libserver/milter.c b/src/libserver/milter.c index 5c1e27def..08a700a27 100644 --- a/src/libserver/milter.c +++ b/src/libserver/milter.c @@ -51,6 +51,43 @@ rspamd_milter_quark (void) return g_quark_from_static_string ("milter"); } +static void +rspamd_milter_obuf_free (struct rspamd_milter_outbuf *obuf) +{ + if (obuf) { + if (obuf->buf) { + rspamd_fstring_free (obuf->buf); + } + + g_free (obuf->buf); + } +} + +static void +rspamd_milter_session_dtor (struct rspamd_milter_session *session) +{ + struct rspamd_milter_outbuf *obuf, *obuf_tmp; + struct rspamd_milter_private *priv; + + if (session) { + priv = session->priv; + + if (event_get_base (&priv->ev)) { + event_del (&priv->ev); + } + + DL_FOREACH_SAFE (priv->out_chain, obuf, obuf_tmp) { + rspamd_milter_obuf_free (obuf); + } + + if (priv->parser.buf) { + rspamd_fstring_free (priv->parser.buf); + } + + priv->out_chain = NULL; + } +} + static void rspamd_milter_io_handler (gint fd, gshort what, void *ud) { @@ -225,7 +262,8 @@ static gboolean rspamd_milter_handle_session (struct rspamd_milter_session *session, struct rspamd_milter_private *priv) { - gssize r; + struct rspamd_milter_outbuf *obuf, *obuf_tmp; + gssize r, to_write; GError *err; g_assert (session != NULL); @@ -247,7 +285,7 @@ rspamd_milter_handle_session (struct rspamd_milter_session *session, else { /* Fatal IO error */ err = g_error_new (rspamd_milter_quark (), errno, - "IO error: %s", strerror (errno)); + "IO read error: %s", strerror (errno)); REF_RETAIN (session); priv->err_cb (priv->fd, session, priv->ud, err); REF_RELEASE (session); @@ -267,7 +305,70 @@ rspamd_milter_handle_session (struct rspamd_milter_session *session, return rspamd_milter_consume_input (session, priv); } + case RSPAMD_MILTER_WRITE_REPLY: + if (priv->out_chain == NULL) { + /* We have written everything, so we can read something */ + priv->state = RSPAMD_MILTER_READ_MORE; + rspamd_milter_plan_io (session, priv, EV_READ); + } + else { + DL_FOREACH_SAFE (priv->out_chain, obuf, obuf_tmp) { + to_write = obuf->buf->len - obuf->pos; + + g_assert (to_write > 0); + + r = write (priv->fd, obuf->buf->str + obuf->pos, to_write); + + if (r == -1) { + if (errno == EAGAIN || errno == EINTR) { + rspamd_milter_plan_io (session, priv, EV_WRITE); + } + else { + /* Fatal IO error */ + err = g_error_new (rspamd_milter_quark (), errno, + "IO write error: %s", strerror (errno)); + REF_RETAIN (session); + priv->err_cb (priv->fd, session, priv->ud, err); + REF_RELEASE (session); + g_error_free (err); + } + } + else if (r == 0) { + err = g_error_new (rspamd_milter_quark (), ECONNRESET, + "Unexpected EOF"); + REF_RETAIN (session); + priv->err_cb (priv->fd, session, priv->ud, err); + REF_RELEASE (session); + g_error_free (err); + } + else { + if (r == to_write) { + /* We have done with this buf */ + DL_DELETE (priv->out_chain, obuf); + rspamd_milter_obuf_free (obuf); + } + else { + /* We need to plan another write */ + obuf->pos += r; + rspamd_milter_plan_io (session, priv, EV_WRITE); + + return TRUE; + } + } + } + + /* Here we have written everything, so we can plan reading */ + priv->state = RSPAMD_MILTER_READ_MORE; + rspamd_milter_plan_io (session, priv, EV_READ); + } + break; + case RSPAMD_MILTER_WANNA_DIE: + /* We are here after processing everything, so release session */ + REF_RELEASE (session); + break; } + + return TRUE; } @@ -307,6 +408,7 @@ rspamd_milter_handle_socket (gint fd, const struct timeval *tv, } session->priv = priv; + REF_INIT_RETAIN (session, rspamd_milter_session_dtor); return rspamd_milter_handle_session (session, priv); } @@ -418,7 +520,7 @@ rspamd_milter_send_action (struct rspamd_milter_session *session, if (reply) { obuf = g_malloc (sizeof (*obuf)); obuf->buf = reply; - obuf->pos = NULL; + obuf->pos = 0; DL_APPEND (priv->out_chain, obuf); priv->state = RSPAMD_MILTER_WRITE_REPLY; rspamd_milter_plan_io (session, priv, EV_WRITE); diff --git a/src/libserver/milter_internal.h b/src/libserver/milter_internal.h index a580c950a..9d3b05c00 100644 --- a/src/libserver/milter_internal.h +++ b/src/libserver/milter_internal.h @@ -45,7 +45,6 @@ struct rspamd_milter_outbuf { enum rspamd_milter_io_state { RSPAMD_MILTER_READ_MORE, - RSPAMD_MILTER_PROCESS_DATA, RSPAMD_MILTER_WRITE_REPLY, RSPAMD_MILTER_WANNA_DIE }; -- 2.39.5