On Sat, Feb 4, 2012 at 3:44 PM, Patrick Mézard <[email protected]> wrote: > Le 04/02/12 15:01, Baptiste a écrit : >> Hi everybody, >> >> Please find in attachment a patch which provides IMAP health checking. >> >> Note that it provides also a clean application logout :) >> >> it applies on HAProxy HEAD git. >> >> I've tested it on my courier IMAP server and it works as expected. >> You can test it with the simple conf below: >> listen imap >> bind 0.0.0.0:1143 >> mode tcp >> option imapchk >> server imapserver <IP>:143 check >> >> Your feedback are welcome. > > Some remarks about the documentation : > - It would be great if Willy could pronounce on the options naming: *chk / > *-check / *-chk > - I would mention the check in the "server" "check" parameter paragraph > (maybe it should be turned into a list). > - s/operrating/operating/ > > What about something a bit shorter (please give us inline diffs to comment on > :-)): > > Set "option imapchk" to test IMAP servers availability. The > health check consists in establishing a TCP connection, > reading the IMAP banner and verifying it starts with "* OK". > > Sidenote: it would be great to unify all the health checks descriptions. All > of them describe the check with more or less details, then sometimes add > consideration about logging and whatnots. > > -- > Patrick Mézard >
Hi, I just updated the patch with a logout option to make the check silent. Patrick, I also updated the doc with your remarks. cheers
From e8d8498f50038417649be337c67d22fd0061f010 Mon Sep 17 00:00:00 2001 From: bedis <[email protected]> Date: Sat, 11 Feb 2012 08:32:29 +0100 Subject: [PATCH] imap health check --- doc/configuration.txt | 27 +++++++++++++++++++++++++-- include/types/proxy.h | 2 ++ src/cfgparse.c | 11 +++++++++++ src/checks.c | 25 ++++++++++++++++++++++++- 4 files changed, 62 insertions(+), 3 deletions(-) diff --git a/doc/configuration.txt b/doc/configuration.txt index 28e7330..9d0b727 100644 --- a/doc/configuration.txt +++ b/doc/configuration.txt @@ -1024,6 +1024,7 @@ option httpchk X - X X option httpclose (*) X X X X option httplog X X X X option http_proxy (*) X X X X +option imapchk X - X X option independant-streams (*) X X X X option ldap-check X - X X option log-health-checks (*) X - X X @@ -3393,8 +3394,8 @@ option httpchk <method> <uri> <version> server apache1 192.168.1.1:443 check port 80 See also : "option ssl-hello-chk", "option smtpchk", "option mysql-check", - "option pgsql-check", "http-check" and the "check", "port" and - "inter" server options. + "option pgsql-check", "http-check", "option imapchk" and the + "check", "port" and "inter" server options. option httpclose @@ -3494,6 +3495,28 @@ no option http_proxy See also : "option httpclose" +option imapchk [logout] + Use imap health checks for server testing + May be used in sections : defaults | frontend | listen | backend + yes | no | yes | yes + Arguments : none + + Set "option imapchk" to test IMAP servers availability. The health check + consists in establishing a TCP connection, reading the IMAP banner and + verifying it starts with "* OK". + + Option logout parameters allows you to decide wether to send or not a + logout command. + The purpose of this option is to make the check as silent as possible. + Some IMAP server may log that somebody get connected without issuing any + command while other would log any command sent (including the logout) + + Example : + option imapchk logout + + See also : "option httpchk" + + option independant-streams no option independant-streams Enable or disable independant timeout processing for both directions diff --git a/include/types/proxy.h b/include/types/proxy.h index d0bc51c..2f5ab44 100644 --- a/include/types/proxy.h +++ b/include/types/proxy.h @@ -159,6 +159,7 @@ enum { #define PR_O2_MYSQL_CHK 0x50000000 /* use MYSQL check for server health */ #define PR_O2_LDAP_CHK 0x60000000 /* use LDAP check for server health */ #define PR_O2_SSL3_CHK 0x70000000 /* use SSLv3 CLIENT_HELLO packets for server health */ +#define PR_O2_IMAP_CHK 0x80000000 /* use IMAP check for server health */ /* unused: 0x80000000 to 0xF000000, reserved for health checks */ #define PR_O2_CHK_ANY 0xF0000000 /* Mask to cover any check */ /* end of proxy->options2 */ @@ -309,6 +310,7 @@ struct proxy { char *expect_str; /* http-check expected content : string or text version of the regex */ regex_t *expect_regex; /* http-check expected content */ struct chunk errmsg[HTTP_ERR_SIZE]; /* default or customized error messages for known errors */ + unsigned int imapchk_logout; /* IMAP health checks to send LOGOUT string or not */ int uuid; /* universally unique proxy ID, used for SNMP */ unsigned int backlog; /* force the frontend's listen backlog */ unsigned int bind_proc; /* bitmask of processes using this proxy. 0 = all. */ diff --git a/src/cfgparse.c b/src/cfgparse.c index 4fed92e..820fb92 100644 --- a/src/cfgparse.c +++ b/src/cfgparse.c @@ -3530,6 +3530,17 @@ stats_error_parsing: memcpy(curproxy->check_req, DEF_LDAP_CHECK_REQ, sizeof(DEF_LDAP_CHECK_REQ) - 1); curproxy->check_len = sizeof(DEF_LDAP_CHECK_REQ) - 1; } + else if (!strcmp(args[1], "imapchk")) { + /* use IMAP connection to check server status */ + free(curproxy->check_req); + curproxy->check_req = NULL; + curproxy->options2 &= ~PR_O2_CHK_ANY; + curproxy->options2 |= PR_O2_IMAP_CHK; + if ( *args[2] && !strcmp(args[2], "logout") ) + curproxy->imapchk_logout = 1; + else + curproxy->imapchk_logout = 0; + } else if (!strcmp(args[1], "forwardfor")) { int cur_arg; diff --git a/src/checks.c b/src/checks.c index 7a9b56d..d713bcb 100644 --- a/src/checks.c +++ b/src/checks.c @@ -1194,8 +1194,23 @@ static int event_srv_chk_r(int fd) } break; + case PR_O2_IMAP_CHK: + /* IMAP welcome banner: '* OK ' */ + if (!done && s->check_data_len < 5) + goto wait_more_data; + + desc = ltrim(s->check_data + 4, ' '); + cut_crlf(desc); + + if (*s->check_data == '*' && *(s->check_data + 2) == 'O' && *(s->check_data + 3) == 'K') + set_server_check_status(s, HCHK_STATUS_L7OKD, desc); + else + set_server_check_status(s, HCHK_STATUS_L7STS, desc); + + break; + default: - /* other checks are valid if the connection succeeded anyway */ + /* checks are valid if the connection succeeded anyway */ set_server_check_status(s, HCHK_STATUS_L4OK, NULL); break; } /* switch */ @@ -1209,6 +1224,14 @@ static int event_srv_chk_r(int fd) s->check_data_len = 0; /* Close the connection... */ + switch (s->proxy->options2 & PR_O2_CHK_ANY) { + case PR_O2_IMAP_CHK: + if (s->proxy->imapchk_logout == 1) + write(fd, "1 LOGOUT\r\n", strlen("1 LOGOUT\r\n")); + break; + default: + break; + } shutdown(fd, SHUT_RDWR); EV_FD_CLR(fd, DIR_RD); task_wakeup(t, TASK_WOKEN_IO); -- 1.7.5.4

