brings HAProxy most of its value.
health The instance will work in "health" mode. It will just reply "OK"
- to incoming connections and close the connection. Nothing will be
- logged. This mode is used to reply to external components health
- checks. This mode is deprecated and should not be used anymore as
- it is possible to do the same and even better by combining TCP or
- HTTP modes with the "monitor" keyword.
+ to incoming connections and close the connection. Alternatively,
+ If the "httpchk" option is set, "HTTP/1.0 200 OK" will be sent
+ instead. Nothing will be logged in either case. This mode is used
+ to reply to external components health checks. This mode is
+ deprecated and should not be used anymore as it is possible to do
+ the same and even better by combining TCP or HTTP modes with the
+ "monitor" keyword.
When doing content switching, it is mandatory that the frontend and the
backend are in the same mode (generally HTTP), otherwise the configuration
accepted, the following response will be sent without waiting for a request,
then the connection will be closed : "HTTP/1.0 200 OK". This is normally
enough for any front-end HTTP probe to detect that the service is UP and
- running without forwarding the request to a backend server.
-
- Monitor requests are processed very early. It is not possible to block nor
- divert them using ACLs. They cannot be logged either, and it is the intended
- purpose. They are only used to report HAProxy's health to an upper component,
- nothing more. Right now, it is not possible to set failure conditions on
- requests caught by "monitor-net".
+ running without forwarding the request to a backend server. Note that this
+ response is sent in raw format, without any transformation. This is important
+ as it means that it will not be SSL-encrypted on SSL listeners.
+
+ Monitor requests are processed very early, just after tcp-request connection
+ ACLs which are the only ones able to block them. These connections are short
+ lived and never wait for any data from the client. They cannot be logged, and
+ it is the intended purpose. They are only used to report HAProxy's health to
+ an upper component, nothing more. Please note that "monitor fail" rules do
+ not apply to connections intercepted by "monitor-net".
Last, please note that only one "monitor-net" statement can be specified in
a frontend. If more than one is found, only the last one will be considered.
s->req->rto = s->fe->timeout.client;
s->rep->wto = s->fe->timeout.client;
- if (unlikely((s->fe->mode == PR_MODE_HTTP && (s->flags & SN_MONITOR)) ||
- (s->fe->mode == PR_MODE_HEALTH && ((s->fe->options2 & PR_O2_CHK_ANY) == PR_O2_HTTP_CHK)))) {
- /* Either we got a request from a monitoring system on an HTTP instance,
- * or we're in health check mode with the 'httpchk' option enabled. In
- * both cases, we return a fake "HTTP/1.0 200 OK" response and we exit.
- */
- struct chunk msg;
- chunk_initstr(&msg, "HTTP/1.0 200 OK\r\n\r\n");
- stream_int_retnclose(&s->si[0], &msg); /* forge a 200 response */
- s->req->analysers = 0;
- s->task->expire = s->rep->wex;
- fd_stop_recv(cfd);
- }
- else if (unlikely(s->fe->mode == PR_MODE_HEALTH)) { /* health check mode, no client reading */
- struct chunk msg;
- chunk_initstr(&msg, "OK\n");
- stream_int_retnclose(&s->si[0], &msg); /* forge an "OK" response */
- s->req->analysers = 0;
- s->task->expire = s->rep->wex;
- fd_stop_recv(cfd);
- }
/* everything's OK, let's go on */
return 1;
}
}
- /* if this connection comes from a known monitoring system, we want to ignore
- * it as soon as possible, which means closing it immediately if it is only a
- * TCP-based monitoring check.
- */
- if (unlikely((l->options & LI_O_CHK_MONNET) &&
- (p->mode == PR_MODE_TCP) &&
- addr.ss_family == AF_INET &&
- (((struct sockaddr_in *)&addr)->sin_addr.s_addr & p->mon_mask.s_addr) == p->mon_net.s_addr)) {
- close(cfd);
- continue;
- }
-
if (unlikely(cfd >= global.maxsock)) {
send_log(p, LOG_EMERG,
"Proxy %s reached the configured maximum connection limit. Please check the global 'maxconn' value.\n",
proxy_inc_fe_conn_ctr(l, p);
- /* if this session comes from a known monitoring system, we want to ignore
- * it as soon as possible, which means closing it immediately for TCP, but
- * cleanly.
- */
- if (unlikely((l->options & LI_O_CHK_MONNET) &&
- addr->ss_family == AF_INET &&
- (((struct sockaddr_in *)addr)->sin_addr.s_addr & p->mon_mask.s_addr) == p->mon_net.s_addr)) {
- s->flags |= SN_MONITOR;
- s->logs.logwait = 0;
- }
-
/* now evaluate the tcp-request layer4 rules. Since we expect to be able
* to abort right here as soon as possible, we check the rules before
* even initializing the stream interfaces.
goto out_free_session;
}
+ /* Adjust some socket options */
+ if (unlikely(fcntl(cfd, F_SETFL, O_NONBLOCK) == -1))
+ goto out_free_session;
+
+ /* monitor-net and health mode are processed immediately after TCP
+ * connection rules. This way it's possible to block them, but they
+ * never use the lower data layers, they send directly over the socket,
+ * as they were designed for. We first flush the socket receive buffer
+ * in order to avoid emission of an RST by the system. We ignore any
+ * error.
+ */
+ if (unlikely((p->mode == PR_MODE_HEALTH) ||
+ ((l->options & LI_O_CHK_MONNET) &&
+ addr->ss_family == AF_INET &&
+ (((struct sockaddr_in *)addr)->sin_addr.s_addr & p->mon_mask.s_addr) == p->mon_net.s_addr))) {
+ /* we have 4 possibilities here :
+ * - HTTP mode, from monitoring address => send "HTTP/1.0 200 OK"
+ * - HEALTH mode with HTTP check => send "HTTP/1.0 200 OK"
+ * - HEALTH mode without HTTP check => just send "OK"
+ * - TCP mode from monitoring address => just close
+ */
+ recv(cfd, trash, trashlen, 0&MSG_DONTWAIT);
+ if (p->mode == PR_MODE_HTTP ||
+ (p->mode == PR_MODE_HEALTH && (p->options2 & PR_O2_CHK_ANY) == PR_O2_HTTP_CHK))
+ send(cfd, "HTTP/1.0 200 OK\r\n\r\n", 19, MSG_DONTWAIT|MSG_NOSIGNAL|MSG_MORE);
+ else if (p->mode == PR_MODE_HEALTH)
+ send(cfd, "OK\n", 3, MSG_DONTWAIT|MSG_NOSIGNAL|MSG_MORE);
+ ret = 0;
+ goto out_free_session;
+ }
+
+
/* wait for a PROXY protocol header */
if (l->options & LI_O_ACC_PROXY) {
s->si[0].conn.flags |= CO_FL_ACCEPT_PROXY;
conn_sock_want_recv(&s->si[0].conn);
}
- /* Adjust some socket options */
- if (unlikely(fcntl(cfd, F_SETFL, O_NONBLOCK) == -1))
- goto out_free_session;
-
if (unlikely((t = task_new()) == NULL))
goto out_free_session;