mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2025-09-21 22:01:31 +02:00
[MEDIUM] implement SMTP health checks
Peter van Dijk contributed this patch which implements the "smtpchk" option, which is to SMTP what "httpchk" is to HTTP. By default, it sends "HELO localhost" to the servers, and waits for the 250 message, but it can also send a specific request.
This commit is contained in:
parent
f3d259868b
commit
23677908dd
@ -1034,6 +1034,13 @@ the response is considered as valid. Note that Apache does not generate a log
|
||||
when it receives only an HELLO message, which makes this type of message
|
||||
perfectly suit this need.
|
||||
|
||||
Version 1.3.10 introduced the SMTP health check. By default, it sends
|
||||
"HELO localhost" to the servers, and waits for the 250 message. Note that it
|
||||
can also send a specific request :
|
||||
|
||||
- option smtpchk -> sends "HELO localhost"
|
||||
- option smtpchk EHLO mail.mydomain.com -> sends this ESMTP greeting
|
||||
|
||||
See examples below.
|
||||
|
||||
Since version 1.1.17, it is possible to specify backup servers. These servers
|
||||
|
@ -1044,6 +1044,14 @@ r
|
||||
lorsqu'il reçoit des messages HELLO, ce qui en fait un type de message
|
||||
parfaitement adapté à ce besoin.
|
||||
|
||||
La version 1.3.10 est accompagnée d'un nouveau test d'état pour le SMTP. Par
|
||||
défaut, il consiste à envoyer "HELO localhost" aux serveurs, et à attendre le
|
||||
message "250" en retour. Notez qu'il peut aussi envoyer une requête plus
|
||||
spécifique :
|
||||
|
||||
- option smtpchk -> envoie "HELO localhost"
|
||||
- option smtpchk EHLO mail.mydomain.com -> envoie ce message ESMTP
|
||||
|
||||
Voir les exemples ci-après.
|
||||
|
||||
Depuis la version 1.1.17, il est possible de définir des serveurs de secours,
|
||||
|
@ -92,6 +92,7 @@
|
||||
#define DEF_FALLTIME 3
|
||||
#define DEF_RISETIME 2
|
||||
#define DEF_CHECK_REQ "OPTIONS / HTTP/1.0\r\n\r\n"
|
||||
#define DEF_SMTP_CHECK_REQ "HELO localhost\r\n"
|
||||
|
||||
/* Default connections limit.
|
||||
*
|
||||
|
@ -59,6 +59,7 @@
|
||||
#define PR_O_TCPSPLICE 0x08000000 /* delegate data transfer to linux kernel's tcp_splice */
|
||||
#define PR_O_BALANCE_UH 0x10000000 /* balance on URI hash */
|
||||
#define PR_O_BALANCE (PR_O_BALANCE_RR | PR_O_BALANCE_SH | PR_O_BALANCE_UH)
|
||||
#define PR_O_SMTP_CHK 0x20000000 /* use SMTP EHLO check for server health - pvandijk@vision6.com.au */
|
||||
|
||||
|
||||
#endif /* _TYPES_BACKEND_H */
|
||||
|
@ -1029,13 +1029,14 @@ int cfg_parse_listen(const char *file, int linenum, char **args)
|
||||
if (curproxy->check_req != NULL) {
|
||||
free(curproxy->check_req);
|
||||
}
|
||||
curproxy->options |= PR_O_HTTP_CHK;
|
||||
curproxy->options &= ~PR_O_SSL3_CHK;
|
||||
curproxy->options &= ~PR_O_SMTP_CHK;
|
||||
curproxy->options |= PR_O_HTTP_CHK;
|
||||
if (!*args[2]) { /* no argument */
|
||||
curproxy->check_req = strdup(DEF_CHECK_REQ); /* default request */
|
||||
curproxy->check_len = strlen(DEF_CHECK_REQ);
|
||||
} else if (!*args[3]) { /* one argument : URI */
|
||||
int reqlen = strlen(args[2]) + strlen("OPTIONS / HTTP/1.0\r\n\r\n");
|
||||
int reqlen = strlen(args[2]) + strlen("OPTIONS HTTP/1.0\r\n\r\n") + 1;
|
||||
curproxy->check_req = (char *)malloc(reqlen);
|
||||
curproxy->check_len = snprintf(curproxy->check_req, reqlen,
|
||||
"OPTIONS %s HTTP/1.0\r\n\r\n", args[2]); /* URI to use */
|
||||
@ -1060,8 +1061,35 @@ int cfg_parse_listen(const char *file, int linenum, char **args)
|
||||
free(curproxy->check_req);
|
||||
}
|
||||
curproxy->options &= ~PR_O_HTTP_CHK;
|
||||
curproxy->options &= ~PR_O_SMTP_CHK;
|
||||
curproxy->options |= PR_O_SSL3_CHK;
|
||||
}
|
||||
else if (!strcmp(args[1], "smtpchk")) {
|
||||
/* use SMTP request to check servers' health */
|
||||
if (curproxy->check_req != NULL) {
|
||||
free(curproxy->check_req);
|
||||
}
|
||||
curproxy->options &= ~PR_O_HTTP_CHK;
|
||||
curproxy->options &= ~PR_O_SSL3_CHK;
|
||||
curproxy->options |= PR_O_SMTP_CHK;
|
||||
|
||||
if (!*args[2] || !*args[3]) { /* no argument or incomplete EHLO host */
|
||||
curproxy->check_req = strdup(DEF_SMTP_CHECK_REQ); /* default request */
|
||||
curproxy->check_len = strlen(DEF_SMTP_CHECK_REQ);
|
||||
} else { /* ESMTP EHLO, or SMTP HELO, and a hostname */
|
||||
if (!strcmp(args[2], "EHLO") || !strcmp(args[2], "HELO")) {
|
||||
int reqlen = strlen(args[2]) + strlen(args[3]) + strlen(" \r\n") + 1;
|
||||
curproxy->check_req = (char *)malloc(reqlen);
|
||||
curproxy->check_len = snprintf(curproxy->check_req, reqlen,
|
||||
"%s %s\r\n", args[2], args[3]); /* HELO hostname */
|
||||
} else {
|
||||
/* this just hits the default for now, but you could potentially expand it to allow for other stuff
|
||||
though, it's unlikely you'd want to send anything other than an EHLO or HELO */
|
||||
curproxy->check_req = strdup(DEF_SMTP_CHECK_REQ); /* default request */
|
||||
curproxy->check_len = strlen(DEF_SMTP_CHECK_REQ);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (!strcmp(args[1], "forwardfor")) {
|
||||
/* insert x-forwarded-for field, but not for the
|
||||
* IP address listed as an except.
|
||||
|
@ -122,7 +122,8 @@ static int event_srv_chk_w(int fd)
|
||||
if (s->result != -1) {
|
||||
/* we don't want to mark 'UP' a server on which we detected an error earlier */
|
||||
if ((s->proxy->options & PR_O_HTTP_CHK) ||
|
||||
(s->proxy->options & PR_O_SSL3_CHK)) {
|
||||
(s->proxy->options & PR_O_SSL3_CHK) ||
|
||||
(s->proxy->options & PR_O_SMTP_CHK)) {
|
||||
int ret;
|
||||
/* we want to check if this host replies to HTTP or SSLv3 requests
|
||||
* so we'll send the request, and won't wake the checker up now.
|
||||
@ -252,6 +253,10 @@ static int event_srv_chk_r(int fd)
|
||||
/* SSLv3 alert or handshake */
|
||||
result = 1;
|
||||
}
|
||||
else if ((s->proxy->options & PR_O_SMTP_CHK) && (len >= 3) &&
|
||||
(reply[0] == '2')) /* 2xx (should be 250) */ {
|
||||
result = 1;
|
||||
}
|
||||
|
||||
if (result == -1)
|
||||
fdtab[fd].state = FD_STERROR;
|
||||
|
Loading…
x
Reference in New Issue
Block a user