aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVsevolod Stakhov <vsevolod@highsecure.ru>2017-04-28 18:01:14 +0100
committerVsevolod Stakhov <vsevolod@highsecure.ru>2017-04-28 18:07:24 +0100
commite629bf1721232d76b5f64f809e44f3b69a0309d7 (patch)
treef3fe9a5399950f980bbc05e14767a9e2175cd871
parent79860abb33932cce7563d75191091ad4bf1b4f37 (diff)
downloadrspamd-e629bf1721232d76b5f64f809e44f3b69a0309d7.tar.gz
rspamd-e629bf1721232d76b5f64f809e44f3b69a0309d7.zip
[Minor] Add destructor for milter session
-rw-r--r--src/libserver/milter.c108
-rw-r--r--src/libserver/milter_internal.h1
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
@@ -52,6 +52,43 @@ rspamd_milter_quark (void)
}
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)
{
struct rspamd_milter_session *session = 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
};