From d11a273a35ecc861e8f3aeda3c616125a0e5fbe4 Mon Sep 17 00:00:00 2001 From: Sergey Poznyakoff Date: Tue, 24 Aug 2021 21:49:59 +0300 Subject: Intermediate streams: propagate _MU_STR_EVENT_CLRFLAG to the underlying transport * libmailutils/stream/fltstream.c: Propagate mu_stream_clearerr to the transport stream. * libmailutils/stream/iostream.c: Likewise. * libmu_auth/tls.c: Likewise. * libmu_auth/tlsiostr.c: Likewise. * libmu_auth/tlsfdstr.c (_tlsfd_read, _tlsfd_write): Translate GNUTLS_E_TIMEDOUT to MU_ERR_TIMEOUT. * imap4d/bye.c (imap4d_bye_command): Clear stream error on ERR_TIMEOUT. --- --- imap4d/bye.c | 1 + libmailutils/stream/fltstream.c | 13 +++++++++++++ libmailutils/stream/iostream.c | 18 +++++++++++++++++- libmu_auth/tls.c | 18 +++++++++++++++++- libmu_auth/tlsfdstr.c | 4 ++++ libmu_auth/tlsiostr.c | 16 +++++++++++++++- 6 files changed, 67 insertions(+), 3 deletions(-) diff --git a/imap4d/bye.c b/imap4d/bye.c index 831d06b67..0b05e6c9a 100644 --- a/imap4d/bye.c +++ b/imap4d/bye.c @@ -84,6 +84,7 @@ imap4d_bye_command (int reason, struct imap4d_command *command) case ERR_TIMEOUT: status = EX_TEMPFAIL; + mu_stream_clearerr (iostream); io_untagged_response (RESP_BYE, "Session timed out"); if (state == STATE_NONAUTH) mu_diag_output (MU_DIAG_INFO, _("session timed out for no user")); diff --git a/libmailutils/stream/fltstream.c b/libmailutils/stream/fltstream.c index 08ed59c63..4986982f2 100644 --- a/libmailutils/stream/fltstream.c +++ b/libmailutils/stream/fltstream.c @@ -648,6 +648,17 @@ filter_wait (struct _mu_stream *stream, int *pflags, struct timeval *tvp) return mu_stream_wait (fs->transport, pflags, tvp); } +static void +filter_event (struct _mu_stream *str, int code, + unsigned long lval, void *pval) +{ + struct _mu_filter_stream *fs = (struct _mu_filter_stream *)str; + if (code == _MU_STR_EVENT_CLRFLAG && lval == _MU_STR_ERR) + { + mu_stream_clearerr (fs->transport); + } +} + int mu_filter_stream_create (mu_stream_t *pflt, @@ -705,6 +716,8 @@ mu_filter_stream_create (mu_stream_t *pflt, fs->stream.ctl = filter_ctl; fs->stream.wait = filter_wait; fs->stream.error_string = filter_error_string; + fs->stream.event_cb = filter_event; + fs->stream.event_mask = _MU_STR_EVMASK (_MU_STR_EVENT_CLRFLAG); fs->stream.flags = flags; mu_stream_ref (str); diff --git a/libmailutils/stream/iostream.c b/libmailutils/stream/iostream.c index 793c2e9ea..7b9eb50ed 100644 --- a/libmailutils/stream/iostream.c +++ b/libmailutils/stream/iostream.c @@ -364,6 +364,20 @@ _iostream_error_string (struct _mu_stream *str, int rc) return mu_strerror (rc); } +static void +_iostream_event (struct _mu_stream *str, int code, + unsigned long lval, void *pval) +{ + struct _mu_iostream *sp = (struct _mu_iostream *)str; + if (code == _MU_STR_EVENT_CLRFLAG && lval == _MU_STR_ERR) + { + if (sp->transport[_MU_STREAM_INPUT]) + mu_stream_clearerr (sp->transport[_MU_STREAM_INPUT]); + if (sp->transport[_MU_STREAM_OUTPUT]) + mu_stream_clearerr (sp->transport[_MU_STREAM_OUTPUT]); + } +} + int mu_iostream_create (mu_stream_t *pref, mu_stream_t in, mu_stream_t out) { @@ -386,7 +400,9 @@ mu_iostream_create (mu_stream_t *pref, mu_stream_t in, mu_stream_t out) sp->stream.wait = _iostream_wait; sp->stream.shutdown = _iostream_shutdown; sp->stream.error_string = _iostream_error_string; - + sp->stream.event_cb = _iostream_event; + sp->stream.event_mask = _MU_STR_EVMASK (_MU_STR_EVENT_CLRFLAG); + mu_stream_ref (in); sp->transport[_MU_STREAM_INPUT] = in; mu_stream_ref (out); diff --git a/libmu_auth/tls.c b/libmu_auth/tls.c index 1deb46128..aff46257e 100644 --- a/libmu_auth/tls.c +++ b/libmu_auth/tls.c @@ -518,6 +518,20 @@ _tls_error_string (struct _mu_stream *stream, int rc) return mu_strerror (rc); } +static void +_tls_event (struct _mu_stream *str, int code, + unsigned long lval, void *pval) +{ + struct _mu_tls_stream *sp = (struct _mu_tls_stream *)str; + if (code == _MU_STR_EVENT_CLRFLAG && lval == _MU_STR_ERR) + { + if (sp->transport[MU_TRANSPORT_INPUT]) + mu_stream_clearerr (sp->transport[MU_TRANSPORT_INPUT]); + if (sp->transport[MU_TRANSPORT_OUTPUT]) + mu_stream_clearerr (sp->transport[MU_TRANSPORT_OUTPUT]); + } +} + static void free_conf (struct mu_tls_config *conf) { @@ -638,7 +652,9 @@ mu_tls_stream_create (mu_stream_t *pstream, sp->stream.ctl = _tls_ioctl; sp->stream.wait = _tls_wait; sp->stream.error_string = _tls_error_string; - + sp->stream.event_cb = _tls_event; + sp->stream.event_mask = _MU_STR_EVMASK (_MU_STR_EVENT_CLRFLAG); + mu_stream_set_buffer (strin, mu_buffer_none, 0); mu_stream_set_buffer (strout, mu_buffer_none, 0); diff --git a/libmu_auth/tlsfdstr.c b/libmu_auth/tlsfdstr.c index 7db56a67e..be369a3e9 100644 --- a/libmu_auth/tlsfdstr.c +++ b/libmu_auth/tlsfdstr.c @@ -307,6 +307,8 @@ _tlsfd_read (struct _mu_stream *stream, char *buf, size_t bufsize, return 0; } sp->tls_err = rc; + if (sp->tls_err == GNUTLS_E_TIMEDOUT) + return MU_ERR_TIMEOUT; return MU_ERR_TLS; } @@ -330,6 +332,8 @@ _tlsfd_write (struct _mu_stream *stream, const char *buf, size_t bufsize, return 0; } sp->tls_err = rc; + if (sp->tls_err == GNUTLS_E_TIMEDOUT) + return MU_ERR_TIMEOUT; return MU_ERR_TLS; } diff --git a/libmu_auth/tlsiostr.c b/libmu_auth/tlsiostr.c index 4db65d3de..445a5f35b 100644 --- a/libmu_auth/tlsiostr.c +++ b/libmu_auth/tlsiostr.c @@ -206,6 +206,18 @@ _tls_io_ioctl (struct _mu_stream *stream, int code, int opcode, void *arg) return 0; } +static void +_tls_io_event (struct _mu_stream *str, int code, + unsigned long lval, void *pval) +{ + struct _mu_tls_io_stream *sp = (struct _mu_tls_io_stream *)str; + if (code == _MU_STR_EVENT_CLRFLAG && lval == _MU_STR_ERR) + { + if (sp->transport) + mu_stream_clearerr (sp->transport); + } +} + int mu_tls_io_stream_create (mu_stream_t *pstream, mu_stream_t transport, int flags, @@ -234,7 +246,9 @@ mu_tls_io_stream_create (mu_stream_t *pstream, sp->stream.close = _tls_io_close; sp->stream.done = _tls_io_done; sp->stream.ctl = _tls_io_ioctl; - + sp->stream.event_cb = _tls_io_event; + sp->stream.event_mask = _MU_STR_EVMASK (_MU_STR_EVENT_CLRFLAG); + mu_stream_ref (transport); sp->transport = transport; sp->up = master; -- cgit v1.2.1