summaryrefslogtreecommitdiff
path: root/usr.sbin/relayd/check_tcp.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr.sbin/relayd/check_tcp.c')
-rw-r--r--usr.sbin/relayd/check_tcp.c109
1 files changed, 108 insertions, 1 deletions
diff --git a/usr.sbin/relayd/check_tcp.c b/usr.sbin/relayd/check_tcp.c
index 7567a16184c..ede50ce5729 100644
--- a/usr.sbin/relayd/check_tcp.c
+++ b/usr.sbin/relayd/check_tcp.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: check_tcp.c,v 1.14 2007/02/03 17:45:59 reyk Exp $ */
+/* $OpenBSD: check_tcp.c,v 1.15 2007/02/03 20:24:21 reyk Exp $ */
/*
* Copyright (c) 2006 Pierre-Yves Ritschard <pyr@spootnik.org>
@@ -20,8 +20,10 @@
#include <sys/queue.h>
#include <sys/socket.h>
#include <sys/param.h>
+
#include <netinet/in.h>
#include <net/if.h>
+
#include <limits.h>
#include <event.h>
#include <fcntl.h>
@@ -29,6 +31,8 @@
#include <string.h>
#include <stdlib.h>
#include <errno.h>
+#include <fnmatch.h>
+#include <sha1.h>
#include <openssl/ssl.h>
@@ -259,3 +263,106 @@ retry:
event_again(&cte->ev, s, EV_TIMEOUT|EV_READ, tcp_read_buf,
&cte->tv_start, &cte->table->timeout, cte);
}
+
+int
+check_send_expect(struct ctl_tcp_event *cte)
+{
+ u_char *b;
+
+ /*
+ * ensure string is nul-terminated.
+ */
+ b = buf_reserve(cte->buf, 1);
+ if (b == NULL)
+ fatal("out of memory");
+ *b = '\0';
+ if (fnmatch(cte->table->exbuf, cte->buf->buf, 0) == 0) {
+ cte->host->up = HOST_UP;
+ return (0);
+ }
+ cte->host->up = HOST_UNKNOWN;
+
+ /*
+ * go back to original position.
+ */
+ cte->buf->wpos--;
+ return (1);
+}
+
+int
+check_http_code(struct ctl_tcp_event *cte)
+{
+ char *head;
+ char scode[4];
+ const char *estr;
+ u_char *b;
+ int code;
+
+ /*
+ * ensure string is nul-terminated.
+ */
+ b = buf_reserve(cte->buf, 1);
+ if (b == NULL)
+ fatal("out of memory");
+ *b = '\0';
+
+ head = cte->buf->buf;
+ if (strncmp(head, "HTTP/1.1 ", strlen("HTTP/1.1 ")) &&
+ strncmp(head, "HTTP/1.0 ", strlen("HTTP/1.0 "))) {
+ log_debug("check_http_code: cannot parse HTTP version");
+ cte->host->up = HOST_DOWN;
+ return (1);
+ }
+ head += strlen("HTTP/1.1 ");
+ if (strlen(head) < 5) /* code + \r\n */ {
+ cte->host->up = HOST_DOWN;
+ return (1);
+ }
+ strlcpy(scode, head, sizeof(scode));
+ code = strtonum(scode, 100, 999, &estr);
+ if (estr != NULL) {
+ log_debug("check_http_code: cannot parse HTTP code");
+ cte->host->up = HOST_DOWN;
+ return (1);
+ }
+ if (code != cte->table->retcode) {
+ log_debug("check_http_code: invalid HTTP code returned");
+ cte->host->up = HOST_DOWN;
+ } else
+ cte->host->up = HOST_UP;
+ return (!(cte->host->up == HOST_UP));
+}
+
+int
+check_http_digest(struct ctl_tcp_event *cte)
+{
+ char *head;
+ u_char *b;
+ char digest[(SHA1_DIGEST_LENGTH*2)+1];
+
+ /*
+ * ensure string is nul-terminated.
+ */
+ b = buf_reserve(cte->buf, 1);
+ if (b == NULL)
+ fatal("out of memory");
+ *b = '\0';
+
+ head = cte->buf->buf;
+ if ((head = strstr(head, "\r\n\r\n")) == NULL) {
+ log_debug("check_http_digest: host %u no end of headers",
+ cte->host->id);
+ cte->host->up = HOST_DOWN;
+ return (1);
+ }
+ head += strlen("\r\n\r\n");
+ SHA1Data(head, strlen(head), digest);
+
+ if (strcmp(cte->table->digest, digest)) {
+ log_warnx("check_http_digest: wrong digest for host %u",
+ cte->host->id);
+ cte->host->up = HOST_DOWN;
+ } else
+ cte->host->up = HOST_UP;
+ return (!(cte->host->up == HOST_UP));
+}