MINOR: mailers: make it possible to configure the connection timeout

This patch introduces a configurable connection timeout for mailers
with a new "timeout mail <time>" directive.

Acked-by: Simon Horman <horms@verge.net.au>
diff --git a/doc/configuration.txt b/doc/configuration.txt
index f55f68d..279d076 100644
--- a/doc/configuration.txt
+++ b/doc/configuration.txt
@@ -1574,6 +1574,16 @@
         server srv1 192.168.0.30:80
         server srv2 192.168.0.31:80
 
+timeout mail <time>
+  Defines the time available for a mail/connection to be made and send to
+  the mail-server. If not defined the default value is 10 seconds. To allow
+  for at least two SYN-ACK packets to be send during initial TCP handshake it
+  is advised to keep this value above 4 seconds.
+
+  Example:
+    mailers mymailers
+        timeout mail 20s
+        mailer smtp1 192.168.0.1:587
 
 4. Proxies
 ----------
diff --git a/include/types/mailers.h b/include/types/mailers.h
index 07374a7..2b88442 100644
--- a/include/types/mailers.h
+++ b/include/types/mailers.h
@@ -56,6 +56,9 @@
 	struct mailers *next;	        /* next mailers section */
 	int count;			/* total number of mailers in this mailers section */
 	int users;			/* number of users of this mailers section */
+	struct {			/* time to: */
+		int mail;		/*   try connecting to mailserver and sending a email */
+	} timeout;
 };
 
 
diff --git a/src/cfgparse.c b/src/cfgparse.c
index 99e97c7..dd6f8a2 100644
--- a/src/cfgparse.c
+++ b/src/cfgparse.c
@@ -2537,6 +2537,9 @@
 		curmailers->conf.file = strdup(file);
 		curmailers->conf.line = linenum;
 		curmailers->id = strdup(args[1]);
+		curmailers->timeout.mail = DEF_MAILALERTTIME;/* XXX: Would like to Skip to the next alert, if any, ASAP.
+			* But need enough time so that timeouts don't occur
+			* during tcp procssing. For now just us an arbitrary default. */
 	}
 	else if (strcmp(args[0], "mailer") == 0) { /* mailer definition */
 		struct sockaddr_storage *sk;
@@ -2607,7 +2610,43 @@
 		newmailer->proto = proto;
 		newmailer->xprt  = &raw_sock;
 		newmailer->sock_init_arg = NULL;
-	} /* neither "mailer" nor "mailers" */
+	}
+	else if (strcmp(args[0], "timeout") == 0) {
+		if (!*args[1]) {
+			Alert("parsing [%s:%d] : '%s' expects 'mail' and <time> as arguments.\n",
+				file, linenum, args[0]);
+			err_code |= ERR_ALERT | ERR_FATAL;
+			goto out;
+		}
+		else if (strcmp(args[1], "mail") == 0) {
+			const char *res;
+			unsigned int timeout_mail;
+			if (!*args[2]) {
+				Alert("parsing [%s:%d] : '%s %s' expects <time> as argument.\n",
+					file, linenum, args[0], args[1]);
+				err_code |= ERR_ALERT | ERR_FATAL;
+				goto out;
+			}
+			res = parse_time_err(args[2], &timeout_mail, TIME_UNIT_MS);
+			if (res) {
+				Alert("parsing [%s:%d]: unexpected character '%c' in argument to <%s>.\n",
+					file, linenum, *res, args[0]);
+				err_code |= ERR_ALERT | ERR_FATAL;
+				goto out;
+			}
+			if (timeout_mail <= 0) {
+				Alert("parsing [%s:%d] : '%s %s' expects a positive <time> argument.\n", file, linenum, args[0], args[1]);
+				err_code |= ERR_ALERT | ERR_FATAL;
+				goto out;
+			}
+			curmailers->timeout.mail = timeout_mail;
+		} else {
+			Alert("parsing [%s:%d] : '%s' expects 'mail' and <time> as arguments got '%s'.\n",
+				file, linenum, args[0], args[1]);
+			err_code |= ERR_ALERT | ERR_FATAL;
+			goto out;
+		}
+	}
 	else if (*args[0] != 0) {
 		Alert("parsing [%s:%d] : unknown keyword '%s' in '%s' section\n", file, linenum, args[0], cursection);
 		err_code |= ERR_ALERT | ERR_FATAL;
diff --git a/src/checks.c b/src/checks.c
index 4d3b393..35fd020 100644
--- a/src/checks.c
+++ b/src/checks.c
@@ -3108,9 +3108,7 @@
 
 		LIST_INIT(&q->email_alerts);
 
-		check->inter = DEF_MAILALERTTIME; /* XXX: Would like to Skip to the next alert, if any, ASAP.
-					     * But need enough time so that timeouts don't occur
-					     * during tcp check procssing. For now just us an arbitrary default. */
+		check->inter = p->email_alert.mailers.m->timeout.mail;
 		check->rise = DEF_AGENT_RISETIME;
 		check->fall = DEF_AGENT_FALLTIME;
 		err_str = init_check(check, PR_O2_TCPCHK_CHK);