diff options
Diffstat (limited to 'usr.sbin/relayd/check_tcp.c')
-rw-r--r-- | usr.sbin/relayd/check_tcp.c | 109 |
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)); +} |