From: Jeremy Harris Date: Wed, 28 Jan 2015 21:19:14 +0000 (+0000) Subject: Add timeout option to spamd_address server specification. Bug 68 X-Git-Tag: exim-4_86_RC1~123 X-Git-Url: https://vcs.fsf.org/?p=exim.git;a=commitdiff_plain;h=237638980ecece7f98c1dbdb9a02382d7f772dca;ds=sidebyside Add timeout option to spamd_address server specification. Bug 68 --- diff --git a/doc/doc-docbook/spec.xfpt b/doc/doc-docbook/spec.xfpt index cb3d78d5d..3e9cb733a 100644 --- a/doc/doc-docbook/spec.xfpt +++ b/doc/doc-docbook/spec.xfpt @@ -30790,12 +30790,19 @@ The supported option are: .code variant=rspamd Use Rspamd rather than SpamAssassin protocol time=- Use only between these times of day +tmo= Connection time limit. weight= Selection bias backup Use only if all non-backup servers fail .endd Time specifications for the &`time`& option are .. in the local time zone; each element being one or more digits. +Either the seconds or both minutes and seconds, plus the leading &`.`& +characters, may be omitted and will be taken as zero. + +Timeout specifications for the &`tmo`& option are the usual Exim +time interval standard, eg. &`20s`& or &`1m`&. +The default value is two minutes. Servers are queried in a random fashion, weighted by the selection bias. The default value for selection bias is 1. diff --git a/doc/doc-txt/ChangeLog b/doc/doc-txt/ChangeLog index fbfe7507e..5b2155239 100644 --- a/doc/doc-txt/ChangeLog +++ b/doc/doc-txt/ChangeLog @@ -37,7 +37,7 @@ JH/08 The EXPERIMENTAL_DSN compile option is no longer needed; all Delivery JH/09 A timeout of 2 minutes is now applied to all malware scanner types by default, modifiable by a malware= option. The list separator for - the options can now be changed in the usual way. + the options can now be changed in the usual way. Bug 68. JH/10 The smtp_receive_timeout main option is now expanded before use. @@ -61,6 +61,9 @@ JH/16 The spamd_address main option now supports a mixed list of local and remote servers. Remote servers can be IPv6 addresses, and specify a port-range. +JH/17 Bug 68: The spamd_address main option now supports an optional + timeout value per server. + Exim version 4.85 diff --git a/src/src/malware.c b/src/src/malware.c index 2a1e21654..3ef149827 100644 --- a/src/src/malware.c +++ b/src/src/malware.c @@ -1205,7 +1205,6 @@ if (!malware_ok) unsigned int fsize_uint; BOOL use_scan_command = FALSE; clamd_address_container * clamd_address_vector[MAX_CLAMD_SERVERS]; - int current_server; int num_servers = 0; #ifdef WITH_OLD_CLAMAV_STREAM unsigned int port; @@ -1289,8 +1288,7 @@ if (!malware_ok) while (num_servers > 0) { int i; - /* Randomly pick a server to start with */ - current_server = random_number( num_servers ); + int current_server = random_number( num_servers ); DEBUG(D_acl) debug_printf("trying server name %s, port %u\n", diff --git a/src/src/spam.c b/src/src/spam.c index 76db2b667..8817af0cd 100644 --- a/src/src/spam.c +++ b/src/src/spam.c @@ -21,8 +21,10 @@ int spam_ok = 0; int spam_rc = 0; uschar *prev_spamd_address_work = NULL; +static int timeout_sec; static const uschar * loglabel = US"spam acl condition:"; + static int spamd_param_init(spamd_address_container *spamd) { @@ -38,7 +40,7 @@ static int spamd_param(const uschar *param, spamd_address_container *spamd) { static int timesinceday = -1; -uschar buffer[256]; +const uschar * s; /* check backup parameter */ if (Ustrcmp(param, "backup") == 0) @@ -58,32 +60,30 @@ if (sscanf(param, "weight=%u", &spamd->weight)) } /* check time parameter */ -if (sscanf(param, "time=%s", buffer)) +if (Ustrncmp(param, "time=", 5) == 0) { unsigned int start_h = 0, start_m = 0, start_s = 0; unsigned int end_h = 24, end_m = 0, end_s = 0; unsigned int time_start, time_end; - uschar *start_string; - uschar *end_string; - uschar *delimiter; + const uschar * end_string; - if ((delimiter = US strchr(CS buffer, '-'))) + s = param+5; + if ((end_string = Ustrchr(s, '-'))) { - *delimiter = '\0'; - start_string = buffer; - end_string = delimiter + 1; - if (sscanf(CS end_string, "%u.%u.%u", &end_h, &end_m, &end_s) == 0 || - sscanf(CS start_string, "%u.%u.%u", &start_h, &start_m, &start_s) == 0) + end_string++; + if ( sscanf(CS end_string, "%u.%u.%u", &end_h, &end_m, &end_s) == 0 + || sscanf(CS s, "%u.%u.%u", &start_h, &start_m, &start_s) == 0 + ) { log_write(0, LOG_MAIN, - "%s warning - invalid spamd time value: '%s'", loglabel, buffer); + "%s warning - invalid spamd time value: '%s'", loglabel, s); return -1; /* syntax error */ } } else { log_write(0, LOG_MAIN, - "%s warning - invalid spamd time value: '%s'", loglabel, buffer); + "%s warning - invalid spamd time value: '%s'", loglabel, s); return -1; /* syntax error */ } @@ -109,6 +109,19 @@ if (Ustrcmp(param, "variant=rspamd") == 0) return 0; } +if (Ustrncmp(param, "tmo=", 4) == 0) + { + int sec = readconf_readtime((s = param+4), '\0', FALSE); + if (sec < 0) + { + log_write(0, LOG_MAIN, + "%s warning - invalid spamd timeout value: '%s'", loglabel, s); + return -1; /* syntax error */ + } + timeout_sec = sec; + return 0; + } + log_write(0, LOG_MAIN, "%s warning - invalid spamd parameter: '%s'", loglabel, param); return -1; /* syntax error */ @@ -211,6 +224,8 @@ if ( (Ustrcmp(user_name,"0") == 0) || (strcmpic(user_name,US"false") == 0) ) return FAIL; +timeout_sec = SPAMD_TIMEOUT; + /* if there is an additional option, check if it is "true" */ if (strcmpic(list,US"true") == 0) /* in that case, always return true later */ @@ -434,7 +449,7 @@ again: "%s %s on spamd socket", loglabel, strerror(errno)); else { - if (time(NULL) - start < SPAMD_TIMEOUT) + if (time(NULL) - start < timeout_sec) goto again; log_write(0, LOG_MAIN|LOG_PANIC, "%s timed out writing spamd socket", loglabel); @@ -479,7 +494,7 @@ offset = 0; while ((i = ip_recv(spamd_sock, spamd_buffer + offset, sizeof(spamd_buffer) - offset - 1, - SPAMD_TIMEOUT - time(NULL) + start)) > 0 ) + timeout_sec - time(NULL) + start)) > 0 ) offset += i; /* error handling */