diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2007-10-21 11:20:33 +0000 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2007-10-21 11:20:33 +0000 |
commit | 44e921546471416e57574f9c00a8014864b60276 (patch) | |
tree | 0d7a87b42dba95fbbf7b491ea883dc2f1bd7edb6 | |
parent | 53cdaa581361a885bd7ab087b691b5c68cdc837c (diff) | |
download | mailfromd-44e921546471416e57574f9c00a8014864b60276.tar.gz mailfromd-44e921546471416e57574f9c00a8014864b60276.tar.bz2 |
* src/engine.c: Fix timeout calculations
(struct timeout_ctl): New data type
(UPDATE_TTW,smtp_stream_wait,smtp_wait): Operate on struct timeout_ctl.
All callers updated.
(init_timeout_ctl): New function.
git-svn-id: file:///svnroot/mailfromd/trunk@1517 7a8a7f39-df28-0410-adc6-e0d955640f24
-rw-r--r-- | ChangeLog | 8 | ||||
-rw-r--r-- | src/engine.c | 79 |
2 files changed, 54 insertions, 33 deletions
@@ -1,12 +1,20 @@ +2007-10-21 Sergey Poznyakoff <gray@gnu.org.ua> + + * src/engine.c: Fix timeout calculations + (struct timeout_ctl): New data type + (UPDATE_TTW,smtp_stream_wait,smtp_wait): Operate on struct timeout_ctl. + All callers updated. + (init_timeout_ctl): New function. + 2007-10-12 Sergey Poznyakoff <gray@gnu.org.ua> * src/mtasim.c (_def_read): Return 0 if zero bytes were read (get_input_line): Fix counting of input bytes. (smtp): Fix checking for returns from process_data_reply. * gacopyz/server.c (srv_format_macros): Do not add trailing zero to the packet. 2007-10-10 Sergey Poznyakoff <gray@gnu.org.ua> * src/mailfromd.h [!ENABLE_NLS] (bindtextdomain): Fix definition. * src/cache.c (cache_get2): Fix misplaced variable definition. diff --git a/src/engine.c b/src/engine.c index 1801fdec..bb3fa18c 100644 --- a/src/engine.c +++ b/src/engine.c @@ -296,99 +296,112 @@ void smtp_io_data_destroy(struct smtp_io_data *dat) { if (dat) { mu_stream_close (dat->stream); mu_stream_destroy(&dat->stream, mu_stream_get_owner(dat->stream)); obstack_free(&dat->stk, NULL); if (dat->ctx) priv_set_io(dat->ctx, NULL); } } -#define UPDATE_TTW(t,start) do { \ - time_t delta = time(NULL) - start; \ - if (t > delta) \ - t -= delta; \ +struct timeout_ctl { + time_t start; + time_t timeout; +}; + +static void +init_timeout_ctl(struct timeout_ctl *tctl, time_t timeout) +{ + tctl->start = time(NULL); + tctl->timeout = timeout; +} + +#define UPDATE_TTW(t) do { \ + time_t now = time(NULL); \ + time_t delta = now - (t).start; \ + if ((t).timeout > delta) \ + (t).timeout -= delta; \ else \ - t = 0; \ + (t).timeout = 0; \ + (t).start = now; \ } while (0) int -smtp_stream_wait(mu_stream_t stream, int flags, time_t *timeout) +smtp_stream_wait(mu_stream_t stream, int flags, struct timeout_ctl *tctl) { int rc; int oflags = flags; struct timeval tv; - time_t start = time(NULL); - while (*timeout) { - tv.tv_sec = *timeout; + while (tctl->timeout) { + tv.tv_sec = tctl->timeout; tv.tv_usec = 0; rc = mu_stream_wait(stream, &oflags, &tv); /* Correct the timeout */ - UPDATE_TTW(*timeout, start); + UPDATE_TTW(*tctl); switch (rc) { case 0: if (flags & oflags) return 0; /* FALLTHROUGH */ case EAGAIN: case EINPROGRESS: continue; default: return rc; } } return ETIMEDOUT; } int -smtp_wait(struct smtp_io_data *dat, int flags, time_t *timeout) +smtp_wait(struct smtp_io_data *dat, int flags, struct timeout_ctl *tctl) { - return smtp_stream_wait(dat->stream, flags, timeout); + return smtp_stream_wait(dat->stream, flags, tctl); } int smtp_send(struct smtp_io_data *dat, char *command) { size_t len = strlen(command); - time_t timeout = io_timeout; - time_t start = time(NULL); + struct timeout_ctl tctl; + + init_timeout_ctl (&tctl, io_timeout); dat->reply = NULL; /* Clear reply for logging purposes */ transcript(dat, "SEND:", command); do { size_t nb; int rc; - UPDATE_TTW(timeout, start); + UPDATE_TTW(tctl); rc = mu_stream_write(dat->stream, command, len, dat->send_off, &nb); if (rc == 0) { if (nb == 0) { mu_error(_("stream_write: wrote 0 bytes")); return -1; } dat->send_off += nb; len -= nb; command += nb; } else if (rc == EAGAIN) { - rc = smtp_wait(dat, MU_STREAM_READY_WR, - &timeout); + rc = smtp_wait(dat, MU_STREAM_READY_WR, &tctl); if (rc) { mu_error(_("smtp_wait failed: %s"), mu_strerror(rc)); return -1; } continue; } else { mu_error("mu_stream_write: %s", mu_strerror (rc)); return -1; } } while (len > 0); @@ -415,45 +428,44 @@ smtp_send3(struct smtp_io_data *dat, char *command, char *arg1, char *arg2) obstack_grow(&dat->stk, arg1, strlen(arg1)); obstack_grow(&dat->stk, arg2, strlen(arg2)); obstack_grow(&dat->stk, "\r\n", 2); obstack_1grow(&dat->stk, 0); dat->command = obstack_finish(&dat->stk); return smtp_send(dat, dat->command); } int smtp_recvline(struct smtp_io_data *dat, time_t timeout) { - time_t start = time(NULL); - + struct timeout_ctl tctl; + init_timeout_ctl(&tctl, timeout); for (;;) { char *p; - UPDATE_TTW(timeout, start); - + UPDATE_TTW(tctl); + if (dat->level == 0) { int rc = mu_stream_read(dat->stream, dat->buf, sizeof dat->buf, dat->recv_off, &dat->level); if (rc == 0) { if (dat->level == 0) { mu_error(_("stream_read: read 0 bytes")); return -1; } dat->recv_off += dat->level; } else if (rc == EAGAIN) { rc = smtp_wait(dat, - MU_STREAM_READY_RD, - &timeout); + MU_STREAM_READY_RD, &tctl); if (rc) { mu_error(_("smtp_wait failed: %s"), mu_strerror(rc)); return -1; } continue; } else { mu_error("mu_stream_read: %s", mu_strerror (rc)); return -1; } } @@ -554,48 +566,48 @@ reset(struct smtp_io_data *io) /* Verify whether EMAIL address is served by host CLIENT_ADDR. */ mf_status check_on_host(eval_environ_t env, char *email, char *client_addr, char *ehlo, char *mailfrom) { int rc; mu_stream_t stream; struct smtp_io_data io; mf_status status = mf_success; int count = 0; SMFICTX *ctx = env_get_context(env); - time_t timeout, start = time(NULL); + struct timeout_ctl tctl; debug2(10, "email = %s, client_addr = %s", email, client_addr); set_last_poll_result(env, client_addr, "", ""); rc = mu_tcp_stream_create_with_source_ip (&stream, client_addr, 25, source_address, MU_STREAM_NONBLOCK); if (rc) { mu_error(_("%sCannot connect to `%s': %s"), mailfromd_msgid(ctx), client_addr, mu_strerror (rc)); return mf_temp_failure; } - - timeout = connect_timeout; + + init_timeout_ctl(&tctl, connect_timeout); while ((rc = mu_stream_open(stream))) { if ((rc == EAGAIN || rc == EINPROGRESS) - && timeout) { + && tctl.timeout) { rc = smtp_stream_wait(stream, MU_STREAM_READY_WR, - &timeout); + &tctl); if (rc == 0) { - UPDATE_TTW(timeout, start); + UPDATE_TTW(tctl); continue; } } mu_error("%sstream_open: %s, %d", mailfromd_msgid(ctx), mu_strerror(rc), count); mu_stream_destroy(&stream, mu_stream_get_owner(stream)); return mf_temp_failure; } debug(100,"stream opened"); if (smtp_io_data_init(&io, ctx, stream)) status = mf_temp_failure; @@ -818,45 +830,46 @@ method_standard(eval_environ_t env, char *email, char *ehlo, char *mailfrom) set_last_poll_result(env, "", "", ""); set_cache_used(env, 1); } return rc; } mf_status listens_on (const char *client_addr, int port) { unsigned count = 0; mu_stream_t stream; int rc; - time_t timeout = connect_timeout, start = time(NULL); + struct timeout_ctl tctl; if (port == 0) port = 25; debug2(10, "client_addr = %s, port = %d", client_addr, port); rc = mu_tcp_stream_create_with_source_ip (&stream, client_addr, port, source_address, MU_STREAM_NONBLOCK); if (rc) { debug1 (10, "mu_tcp_stream_create_with_source_ip: %s", mu_strerror (rc)); return mf_failure; } + init_timeout_ctl(&tctl, connect_timeout); while ((rc = mu_stream_open(stream))) { - if ((rc == EAGAIN || rc == EINPROGRESS) && timeout) { + if ((rc == EAGAIN || rc == EINPROGRESS) && tctl.timeout) { rc = smtp_stream_wait(stream, MU_STREAM_READY_WR, - &timeout); + &tctl); if (rc == 0) { - UPDATE_TTW(timeout, start); + UPDATE_TTW(tctl); continue; } } break; } mu_stream_destroy(&stream, mu_stream_get_owner(stream)); debug3 (10, "mu_stream_open(%s): %s, %u", client_addr, mu_strerror(rc), count); return rc == 0 ? mf_success : (rc == EAGAIN || rc == EINPROGRESS) ? |