diff options
author | Stef Walter <stef@memberwebs.com> | 2004-10-01 20:20:41 +0000 |
---|---|---|
committer | Stef Walter <stef@memberwebs.com> | 2004-10-01 20:20:41 +0000 |
commit | a6778ed6bf02bc95d5da124b671880e5a1fd5df3 (patch) | |
tree | 07e2cdc0bf30683821b6274670cfcae6674a7bad | |
parent | 8f37ccc8081a8a8b53b27069ebc7c518ec6e0632 (diff) |
Send NOOPs to the server during slow connections to prevent timeouts. Bug #134
-rw-r--r-- | ChangeLog | 2 | ||||
-rw-r--r-- | common/smtppass.c | 21 | ||||
-rw-r--r-- | common/smtppass.h | 2 | ||||
-rw-r--r-- | common/spio.c | 10 | ||||
-rw-r--r-- | configure.in | 4 |
5 files changed, 36 insertions, 3 deletions
@@ -1,5 +1,7 @@ 0.9.6 - Fixed problem when filtering the last of a list of EHLO responses + - Send NOOPs to the server when receiving data slowly from client + to prevent timeouts on the server side. 0.9.5 - Fixed problems with the select zeroing out timeouts. diff --git a/common/smtppass.c b/common/smtppass.c index dc1cf77..8b71f4d 100644 --- a/common/smtppass.c +++ b/common/smtppass.c @@ -78,7 +78,7 @@ typedef struct spthread spthread_t; /* ----------------------------------------------------------------------- - * STRINGS + * DATA */ #define CRLF "\r\n" @@ -93,6 +93,7 @@ spthread_t; #define SMTP_REJPREFIX "550 Content Rejected; " #define SMTP_DATA "DATA" CRLF +#define SMTP_NOOP "NOOP" CRLF #define SMTP_BANNER "220 smtp.passthru" CRLF #define SMTP_HELO_RSP "250 smtp.passthru" CRLF #define SMTP_EHLO_RSP "250-smtp.passthru" CRLF @@ -126,6 +127,9 @@ spthread_t; #define LINE_TOO_LONG(l) ((l) >= (SP_LINE_LENGTH - 2)) +/* The amount interval at which to send NOOPS to server */ +#define INTERACTION_DELTA 10 + /* ----------------------------------------------------------------------- * CONFIGURATION OPTIONS * @@ -179,6 +183,7 @@ static int read_server_response(spctx_t* ctx); static int parse_config_file(const char* configfile); static char* parse_address(char* line); static const char* get_successful_rsp(const char* line, int* cont); +static void do_server_noop(spctx_t* ctx); /* Used externally in some cases */ int sp_parse_option(const char* name, const char* option); @@ -1123,6 +1128,14 @@ int sp_read_data(spctx_t* ctx, const char** data) return -1; }; + /* + * During this time we're just reading from the client. If we haven't + * had any interaction with the server recently then send something + * to let it know we're still around. + */ + if((ctx->server.last_action + INTERACTION_DELTA) < time(NULL)) + do_server_noop(ctx); + if(ctx->_crlf && strcmp(ctx->client.line, DATA_END_SIG) == 0) return 0; @@ -1373,6 +1386,12 @@ static int read_server_response(spctx_t* ctx) return 0; } +static void do_server_noop(spctx_t* ctx) +{ + if(spio_write_data(ctx, &(ctx->server), SMTP_NOOP) != -1) + spio_read_line(ctx, &(ctx->server), SPIO_DISCARD); +} + void sp_setup_forked(spctx_t* ctx, int file) { /* Signals we've messed with */ diff --git a/common/smtppass.h b/common/smtppass.h index aebace1..e7fc780 100644 --- a/common/smtppass.h +++ b/common/smtppass.h @@ -66,6 +66,7 @@ typedef struct spio { int fd; /* The file descriptor wrapped */ const char* name; /* The name for logging */ + time_t last_action; /* Time of last action on descriptor */ /* Internal use only */ char line[SP_LINE_LENGTH]; @@ -124,6 +125,7 @@ typedef struct spctx int _crlf; /* Private data */ char _l1[SP_LINE_LENGTH]; char _l2[SP_LINE_LENGTH]; + time_t _tm; } spctx_t; diff --git a/common/spio.c b/common/spio.c index 67d32b1..4075e9a 100644 --- a/common/spio.c +++ b/common/spio.c @@ -245,6 +245,9 @@ unsigned int spio_select(spctx_t* ctx, ...) if(i > (sizeof(int) * 8) - 2) break; + /* We have data on the descriptor, which is an action */ + io->last_action = time(NULL); + /* Check if the buffer has something in it */ if(FD_ISSET(io->fd, &mask)) ret |= (1 << i); @@ -363,6 +366,9 @@ int read_raw(spctx_t* ctx, spio_t* io, int opts) return count; } + /* Read data which is a descriptor action */ + io->last_action = time(NULL); + /* Check for a new line */ p = (char*)memchr(at, '\n', x); if(p != NULL) @@ -489,6 +495,8 @@ int spio_write_data_raw(spctx_t* ctx, spio_t* io, unsigned char* buf, int len) if(io->fd == -1) return 0; + io->last_action = time(NULL); + while(len > 0) { r = write(io->fd, buf, len); @@ -556,6 +564,8 @@ void spio_read_junk(spctx_t* ctx, spio_t* io) if(l <= 0) break; + io->last_action = time(NULL); + buf[l] = 0; t = trim_start(buf); diff --git a/configure.in b/configure.in index fed6f7e..7c612c8 100644 --- a/configure.in +++ b/configure.in @@ -36,8 +36,8 @@ dnl Nate Nielsen <nielsen@memberwebs.com> dnl dnl Process this file with autoconf to produce a configure script. -AC_INIT(clamsmtp, 0.9.5.90, nielsen@memberwebs.com) -AM_INIT_AUTOMAKE(clamsmtp, 0.9.5.90) +AC_INIT(clamsmtp, 0.9.5.91, nielsen@memberwebs.com) +AM_INIT_AUTOMAKE(clamsmtp, 0.9.5.91) LDFLAGS="$LDFLAGS -L/usr/local/lib" CFLAGS="$CFLAGS -I/usr/local/include" |