summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--usr.sbin/hoststated/check_http.c120
-rw-r--r--usr.sbin/hoststated/check_send_expect.c101
-rw-r--r--usr.sbin/hoststated/check_tcp.c130
-rw-r--r--usr.sbin/hoststated/hoststated.h12
-rw-r--r--usr.sbin/hoststated/parse.y38
-rw-r--r--usr.sbin/relayd/check_tcp.c130
-rw-r--r--usr.sbin/relayd/parse.y38
-rw-r--r--usr.sbin/relayd/relayd.h12
8 files changed, 305 insertions, 276 deletions
diff --git a/usr.sbin/hoststated/check_http.c b/usr.sbin/hoststated/check_http.c
index d53f5b0b3fa..ea851233dfd 100644
--- a/usr.sbin/hoststated/check_http.c
+++ b/usr.sbin/hoststated/check_http.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: check_http.c,v 1.9 2007/01/11 18:05:08 reyk Exp $ */
+/* $OpenBSD: check_http.c,v 1.10 2007/01/12 16:43:01 pyr Exp $ */
/*
* Copyright (c) 2006 Pierre-Yves Ritschard <pyr@spootnik.org>
*
@@ -33,11 +33,7 @@
#include "hoststated.h"
-void check_http_code(struct ctl_tcp_event *);
-void check_http_digest(struct ctl_tcp_event *);
-void http_read(int, short, void *);
-
-void
+int
check_http_code(struct ctl_tcp_event *cte)
{
char *head;
@@ -50,28 +46,29 @@ check_http_code(struct ctl_tcp_event *cte)
strncmp(head, "HTTP/1.0 ", strlen("HTTP/1.0 "))) {
log_debug("check_http_code: cannot parse HTTP version");
cte->host->up = HOST_DOWN;
- return;
+ return (1);
}
head += strlen("HTTP/1.1 ");
if (strlen(head) < 5) /* code + \r\n */ {
cte->host->up = HOST_DOWN;
- return;
+ 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;
+ 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));
}
-void
+int
check_http_digest(struct ctl_tcp_event *cte)
{
char *head;
@@ -82,7 +79,7 @@ check_http_digest(struct ctl_tcp_event *cte)
log_debug("check_http_digest: host %u no end of headers",
cte->host->id);
cte->host->up = HOST_DOWN;
- return;
+ return (1);
}
head += strlen("\r\n\r\n");
SHA1Data(head, strlen(head), digest);
@@ -93,104 +90,5 @@ check_http_digest(struct ctl_tcp_event *cte)
cte->host->up = HOST_DOWN;
} else
cte->host->up = HOST_UP;
-}
-
-void
-http_read(int s, short event, void *arg)
-{
- ssize_t br;
- char rbuf[SMALL_READ_BUF_SIZE];
- struct ctl_tcp_event *cte = arg;
-
- if (event == EV_TIMEOUT) {
- cte->host->up = HOST_DOWN;
- buf_free(cte->buf);
- hce_notify_done(cte->host, "http_read: timeout");
- return;
- }
- br = read(s, rbuf, sizeof(rbuf));
- if (br == -1) {
- if (errno == EAGAIN || errno == EINTR)
- goto retry;
- cte->host->up = HOST_DOWN;
- buf_free(cte->buf);
- hce_notify_done(cte->host, "http_read: read failed");
- return;
- } else if (br == 0) {
- cte->host->up = HOST_DOWN;
- switch (cte->table->check) {
- case CHECK_HTTP_CODE:
- check_http_code(cte);
- break;
- case CHECK_HTTP_DIGEST:
- check_http_digest(cte);
- break;
- default:
- fatalx("http_read: unhandled check type");
- }
- buf_free(cte->buf);
- hce_notify_done(cte->host, "http_read: connection closed");
- return;
- }
-
- buf_add(cte->buf, rbuf, br);
-
- retry:
- event_again(&cte->ev, s, EV_TIMEOUT|EV_READ, http_read,
- &cte->tv_start, &cte->table->timeout, cte);
-}
-
-void
-send_http_request(int s, short event, void *arg)
-{
- struct ctl_tcp_event *cte = (struct ctl_tcp_event *)arg;
- int bs;
- int pos;
- int len;
- char *req;
-
- switch (cte->table->check) {
- case CHECK_HTTP_CODE:
- asprintf(&req, "HEAD %s HTTP/1.0\r\n\r\n",
- cte->table->path);
- break;
- case CHECK_HTTP_DIGEST:
- asprintf(&req, "GET %s HTTP/1.0\r\n\r\n",
- cte->table->path);
- break;
- default:
- fatalx("send_http_request: unhandled check type");
- }
- if (req == NULL)
- fatal("out of memory");
- pos = 0;
- len = strlen(req);
- /*
- * write all at once for now.
- */
- do {
- bs = write(cte->s, req + pos, len);
- if (bs == -1) {
- if (errno == EAGAIN || errno == EINTR)
- goto retry;
- log_warnx("send_http_request: cannot send request");
- cte->host->up = HOST_DOWN;
- hce_notify_done(cte->host, "send_http_request: write");
- free(req);
- return;
- }
- pos += bs;
- len -= bs;
- } while (len > 0);
- free(req);
- if ((cte->buf = buf_dynamic(SMALL_READ_BUF_SIZE, UINT_MAX)) == NULL)
- fatalx("send_http_request: cannot create dynamic buffer");
-
- event_again(&cte->ev, s, EV_TIMEOUT|EV_READ, http_read,
- &cte->tv_start, &cte->table->timeout, cte);
- return;
-
- retry:
- event_again(&cte->ev, s, EV_TIMEOUT|EV_WRITE, send_http_request,
- &cte->tv_start, &cte->table->timeout, cte);
+ return (!(cte->host->up == HOST_UP));
}
diff --git a/usr.sbin/hoststated/check_send_expect.c b/usr.sbin/hoststated/check_send_expect.c
index 81c9519b567..f569bf43091 100644
--- a/usr.sbin/hoststated/check_send_expect.c
+++ b/usr.sbin/hoststated/check_send_expect.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: check_send_expect.c,v 1.4 2007/01/11 18:05:08 reyk Exp $ */
+/* $OpenBSD: check_send_expect.c,v 1.5 2007/01/12 16:43:01 pyr Exp $ */
/*
* Copyright (c) 2006 Pierre-Yves Ritschard <pyr@spootnik.org>
*
@@ -33,11 +33,8 @@
#include "hoststated.h"
-void se_validate(struct ctl_tcp_event *);
-void se_read(int, short, void *);
-
-void
-se_validate(struct ctl_tcp_event *cte)
+int
+check_send_expect(struct ctl_tcp_event *cte)
{
u_char *b;
@@ -48,97 +45,15 @@ se_validate(struct ctl_tcp_event *cte)
if (b == NULL)
fatal("out of memory");
*b = '\0';
- if (fnmatch(cte->table->exbuf, cte->buf->buf, 0) == 0)
+ if (fnmatch(cte->table->exbuf, cte->buf->buf, 0) == 0) {
cte->host->up = HOST_UP;
- else
- cte->host->up = HOST_UNKNOWN;
+ return (0);
+ }
+ cte->host->up = HOST_UNKNOWN;
/*
* go back to original position.
*/
cte->buf->wpos--;
-}
-
-void
-se_read(int s, short event, void *arg)
-{
- ssize_t br;
- char rbuf[SMALL_READ_BUF_SIZE];
- struct ctl_tcp_event *cte = arg;
-
- if (event == EV_TIMEOUT) {
- cte->host->up = HOST_DOWN;
- buf_free(cte->buf);
- hce_notify_done(cte->host, "se_read: timeout");
- return;
- }
-
- br = read(s, rbuf, sizeof(rbuf));
- if (br == -1) {
- if (errno == EAGAIN || errno == EINTR)
- goto retry;
- cte->host->up = HOST_DOWN;
- buf_free(cte->buf);
- hce_notify_done(cte->host, "se_read: read failed");
- return;
- } else if (br == 0) {
- cte->host->up = HOST_DOWN;
- se_validate(cte);
- buf_free(cte->buf);
- hce_notify_done(cte->host, "se_read: connection closed");
- return;
- }
-
- buf_add(cte->buf, rbuf, br);
- se_validate(cte);
- if (cte->host->up == HOST_UP) {
- buf_free(cte->buf);
- hce_notify_done(cte->host, "se_read: done");
- return;
- }
-
- retry:
- event_again(&cte->ev, s, EV_TIMEOUT|EV_READ, se_read,
- &cte->tv_start, &cte->table->timeout, cte);
-}
-
-void
-start_send_expect(int s, short event, void *arg)
-{
- struct ctl_tcp_event *cte = (struct ctl_tcp_event *)arg;
- int bs;
- int pos;
- int len;
- char *req;
-
- req = cte->table->sendbuf;
- pos = 0;
- len = strlen(req);
- if (len) {
- do {
- bs = write(cte->s, req + pos, len);
- if (bs == -1) {
- if (errno == EAGAIN || errno == EINTR)
- goto retry;
- log_warnx("send_se_data: cannot send");
- cte->host->up = HOST_DOWN;
- hce_notify_done(cte->host,
- "start_send_expect: write");
- return;
- }
- pos += bs;
- len -= bs;
- } while (len > 0);
- }
-
- if ((cte->buf = buf_dynamic(SMALL_READ_BUF_SIZE, UINT_MAX)) == NULL)
- fatalx("send_se_data: cannot create dynamic buffer");
-
- event_again(&cte->ev, s, EV_TIMEOUT|EV_READ, se_read,
- &cte->tv_start, &cte->table->timeout, cte);
- return;
-
- retry:
- event_again(&cte->ev, s, EV_TIMEOUT|EV_WRITE, start_send_expect,
- &cte->tv_start, &cte->table->timeout, cte);
+ return (1);
}
diff --git a/usr.sbin/hoststated/check_tcp.c b/usr.sbin/hoststated/check_tcp.c
index fc365c18d9d..f5142118c8e 100644
--- a/usr.sbin/hoststated/check_tcp.c
+++ b/usr.sbin/hoststated/check_tcp.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: check_tcp.c,v 1.9 2007/01/11 18:05:08 reyk Exp $ */
+/* $OpenBSD: check_tcp.c,v 1.10 2007/01/12 16:43:01 pyr Exp $ */
/*
* Copyright (c) 2006 Pierre-Yves Ritschard <pyr@spootnik.org>
@@ -33,7 +33,9 @@
#include "hoststated.h"
void tcp_write(int, short, void *);
-void tcp_host_up(int s, struct ctl_tcp_event *);
+void tcp_host_up(int, struct ctl_tcp_event *);
+void tcp_send_req(int, short, void *);
+void tcp_read_buf(int, short, void *);
void
check_tcp(struct ctl_tcp_event *cte)
@@ -123,17 +125,127 @@ tcp_host_up(int s, struct ctl_tcp_event *cte)
case CHECK_TCP:
close(s);
hce_notify_done(cte->host, "tcp_host_up: success");
- break;
+ return;
case CHECK_HTTP_CODE:
+ cte->validate_read = NULL;
+ cte->validate_close = check_http_code;
+ break;
case CHECK_HTTP_DIGEST:
- event_again(&cte->ev, s, EV_TIMEOUT|EV_WRITE, send_http_request,
- &cte->tv_start, &cte->table->timeout, cte);
+ cte->validate_read = NULL;;
+ cte->validate_close = check_http_digest;
break;
case CHECK_SEND_EXPECT:
- event_again(&cte->ev, s, EV_TIMEOUT|EV_WRITE, start_send_expect,
- &cte->tv_start, &cte->table->timeout, cte);
+ cte->validate_read = check_send_expect;
+ cte->validate_close = check_send_expect;
break;
- default:
- fatalx("tcp_host_up: unhandled check type");
}
+ cte->req = cte->table->sendbuf;
+
+ if (cte->table->sendbuf != NULL) {
+ event_again(&cte->ev, s, EV_TIMEOUT|EV_WRITE, tcp_send_req,
+ &cte->tv_start, &cte->table->timeout, cte);
+ return;
+ }
+
+ log_debug("tcp_host_up: nothing to write");
+ if ((cte->buf = buf_dynamic(SMALL_READ_BUF_SIZE, UINT_MAX)) == NULL)
+ fatalx("tcp_host_up: cannot create dynamic buffer");
+ event_again(&cte->ev, s, EV_TIMEOUT|EV_READ, tcp_read_buf,
+ &cte->tv_start, &cte->table->timeout, cte);
+}
+
+void
+tcp_send_req(int s, short event, void *arg)
+{
+ struct ctl_tcp_event *cte = arg;
+ int bs;
+ int pos;
+ int len;
+
+ if (event == EV_TIMEOUT) {
+ cte->host->up = HOST_DOWN;
+ hce_notify_done(cte->host, "tcp_send_req: timeout");
+ return;
+ }
+ pos = 0;
+ len = strlen(cte->req);
+ do {
+ bs = write(s, cte->req + pos, len);
+ if (bs == -1) {
+ if (errno == EAGAIN || errno == EINTR)
+ goto retry;
+ log_warnx("tcp_send_req: cannot send request");
+ cte->host->up = HOST_DOWN;
+ hce_notify_done(cte->host, "tcp_send_req: write");
+ return;
+ }
+ pos += bs;
+ len -= bs;
+ } while (len > 0);
+
+ log_debug("tcp_send_req: write done");
+ if ((cte->buf = buf_dynamic(SMALL_READ_BUF_SIZE, UINT_MAX)) == NULL)
+ fatalx("tcp_send_req: cannot create dynamic buffer");
+ event_again(&cte->ev, s, EV_TIMEOUT|EV_READ, tcp_read_buf,
+ &cte->tv_start, &cte->table->timeout, cte);
+ return;
+
+ retry:
+ event_again(&cte->ev, s, EV_TIMEOUT|EV_WRITE, tcp_send_req,
+ &cte->tv_start, &cte->table->timeout, cte);
+}
+
+void
+tcp_read_buf(int s, short event, void *arg)
+{
+ ssize_t br;
+ char rbuf[SMALL_READ_BUF_SIZE];
+ struct ctl_tcp_event *cte = arg;
+
+ if (event == EV_TIMEOUT) {
+ cte->host->up = HOST_DOWN;
+ buf_free(cte->buf);
+ hce_notify_done(cte->host, "tcp_read_buf: timeout");
+ return;
+ }
+
+ log_debug("reading");
+ bzero(rbuf, sizeof(rbuf));
+ br = read(s, rbuf, sizeof(rbuf) - 1);
+ if (br == -1) {
+ if (errno == EAGAIN || errno == EINTR)
+ goto retry;
+ cte->host->up = HOST_DOWN;
+ buf_free(cte->buf);
+ hce_notify_done(cte->host, "tcp_read_buf: read failed");
+ return;
+ } else if (br == 0) {
+ cte->host->up = HOST_DOWN;
+ (void)cte->validate_close(cte);
+ close(cte->s);
+ buf_free(cte->buf);
+ if (cte->host->up == HOST_UP)
+ hce_notify_done(cte->host, "check succeeded");
+ else
+ hce_notify_done(cte->host, "check failed");
+ return;
+ }
+ buf_add(cte->buf, rbuf, br);
+ if (cte->validate_read != NULL) {
+ log_debug("calling check");
+ if (cte->validate_read(cte) != 0)
+ goto retry;
+
+ close(cte->s);
+ buf_free(cte->buf);
+ if (cte->host->up == HOST_UP)
+ hce_notify_done(cte->host, "check succeeded");
+ else
+ hce_notify_done(cte->host, "check failed");
+ return;
+ }
+retry:
+ event_again(&cte->ev, s, EV_TIMEOUT|EV_READ, tcp_read_buf,
+ &cte->tv_start, &cte->table->timeout, cte);
+
}
diff --git a/usr.sbin/hoststated/hoststated.h b/usr.sbin/hoststated/hoststated.h
index f629ddf266d..204af8a5332 100644
--- a/usr.sbin/hoststated/hoststated.h
+++ b/usr.sbin/hoststated/hoststated.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: hoststated.h,v 1.14 2007/01/11 18:05:08 reyk Exp $ */
+/* $OpenBSD: hoststated.h,v 1.15 2007/01/12 16:43:01 pyr Exp $ */
/*
* Copyright (c) 2006 Pierre-Yves Ritschard <pyr@spootnik.org>
@@ -135,11 +135,14 @@ struct ctl_icmp_event {
struct ctl_tcp_event {
int s;
+ char *req;
struct buf *buf;
struct host *host;
struct table *table;
struct timeval tv_start;
struct event ev;
+ int (*validate_read)(struct ctl_tcp_event *);
+ int (*validate_close)(struct ctl_tcp_event *);
};
struct address {
@@ -191,7 +194,7 @@ struct table {
struct timeval timeout;
char name[TABLE_NAME_SIZE];
char path[MAXPATHLEN];
- char sendbuf[64];
+ char *sendbuf;
char exbuf[64];
char digest[41]; /* length of sha1 digest * 2 */
struct hostlist hosts;
@@ -347,10 +350,11 @@ void check_icmp(struct hoststated *, struct timeval *);
void check_tcp(struct ctl_tcp_event *);
/* check_http.c */
-void send_http_request(int, short, void *);
+int check_http_code(struct ctl_tcp_event *);
+int check_http_digest(struct ctl_tcp_event *);
/* check_send_expect.c */
-void start_send_expect(int, short, void *);
+int check_send_expect(struct ctl_tcp_event *);
/* hoststated.c */
struct host *host_find(struct hoststated *, objid_t);
diff --git a/usr.sbin/hoststated/parse.y b/usr.sbin/hoststated/parse.y
index e3428244243..541bb752cd5 100644
--- a/usr.sbin/hoststated/parse.y
+++ b/usr.sbin/hoststated/parse.y
@@ -1,4 +1,4 @@
-/* $OpenBSD: parse.y,v 1.15 2007/01/09 13:50:11 pyr Exp $ */
+/* $OpenBSD: parse.y,v 1.16 2007/01/12 16:43:01 pyr Exp $ */
/*
* Copyright (c) 2006 Pierre-Yves Ritschard <pyr@spootnik.org>
@@ -176,15 +176,12 @@ varset : STRING '=' STRING {
;
sendbuf : NOTHING {
- bzero(table->sendbuf, sizeof(table->sendbuf));
+ table->sendbuf = NULL;
}
| STRING {
- if (strlcpy(table->sendbuf, $1, sizeof(table->sendbuf))
- >= sizeof(table->sendbuf)) {
- yyerror("yyparse: send buffer truncated");
- free($1);
- YYERROR;
- }
+ table->sendbuf = strdup($1);
+ if (table->sendbuf == NULL)
+ fatal("out of memory");
free($1);
}
;
@@ -386,30 +383,25 @@ tableoptsl : host {
| CHECK HTTP STRING CODE number {
table->check = CHECK_HTTP_CODE;
table->retcode = $5;
- if (strlcpy(table->path, $3, sizeof(table->path)) >=
- sizeof(table->path)) {
- yyerror("http path truncated");
- free($3);
- YYERROR;
- }
+ asprintf(&table->sendbuf, "HEAD %s HTTP/1.0\r\n\r\n",
+ $3);
+ free($3);
+ if (table->sendbuf == NULL)
+ fatal("out of memory");
}
| CHECK HTTP STRING DIGEST STRING {
table->check = CHECK_HTTP_DIGEST;
- if (strlcpy(table->path, $3, sizeof(table->path)) >=
- sizeof(table->path)) {
- yyerror("http path truncated");
- free($3);
- free($5);
- YYERROR;
- }
+ asprintf(&table->sendbuf, "GET %s HTTP/1.0\r\n\r\n",
+ $3);
+ free($3);
+ if (table->sendbuf == NULL)
+ fatal("out of memory");
if (strlcpy(table->digest, $5,
sizeof(table->digest)) >= sizeof(table->digest)) {
yyerror("http digest truncated");
- free($3);
free($5);
YYERROR;
}
- free($3);
free($5);
}
| CHECK SEND sendbuf EXPECT STRING {
diff --git a/usr.sbin/relayd/check_tcp.c b/usr.sbin/relayd/check_tcp.c
index fc365c18d9d..f5142118c8e 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.9 2007/01/11 18:05:08 reyk Exp $ */
+/* $OpenBSD: check_tcp.c,v 1.10 2007/01/12 16:43:01 pyr Exp $ */
/*
* Copyright (c) 2006 Pierre-Yves Ritschard <pyr@spootnik.org>
@@ -33,7 +33,9 @@
#include "hoststated.h"
void tcp_write(int, short, void *);
-void tcp_host_up(int s, struct ctl_tcp_event *);
+void tcp_host_up(int, struct ctl_tcp_event *);
+void tcp_send_req(int, short, void *);
+void tcp_read_buf(int, short, void *);
void
check_tcp(struct ctl_tcp_event *cte)
@@ -123,17 +125,127 @@ tcp_host_up(int s, struct ctl_tcp_event *cte)
case CHECK_TCP:
close(s);
hce_notify_done(cte->host, "tcp_host_up: success");
- break;
+ return;
case CHECK_HTTP_CODE:
+ cte->validate_read = NULL;
+ cte->validate_close = check_http_code;
+ break;
case CHECK_HTTP_DIGEST:
- event_again(&cte->ev, s, EV_TIMEOUT|EV_WRITE, send_http_request,
- &cte->tv_start, &cte->table->timeout, cte);
+ cte->validate_read = NULL;;
+ cte->validate_close = check_http_digest;
break;
case CHECK_SEND_EXPECT:
- event_again(&cte->ev, s, EV_TIMEOUT|EV_WRITE, start_send_expect,
- &cte->tv_start, &cte->table->timeout, cte);
+ cte->validate_read = check_send_expect;
+ cte->validate_close = check_send_expect;
break;
- default:
- fatalx("tcp_host_up: unhandled check type");
}
+ cte->req = cte->table->sendbuf;
+
+ if (cte->table->sendbuf != NULL) {
+ event_again(&cte->ev, s, EV_TIMEOUT|EV_WRITE, tcp_send_req,
+ &cte->tv_start, &cte->table->timeout, cte);
+ return;
+ }
+
+ log_debug("tcp_host_up: nothing to write");
+ if ((cte->buf = buf_dynamic(SMALL_READ_BUF_SIZE, UINT_MAX)) == NULL)
+ fatalx("tcp_host_up: cannot create dynamic buffer");
+ event_again(&cte->ev, s, EV_TIMEOUT|EV_READ, tcp_read_buf,
+ &cte->tv_start, &cte->table->timeout, cte);
+}
+
+void
+tcp_send_req(int s, short event, void *arg)
+{
+ struct ctl_tcp_event *cte = arg;
+ int bs;
+ int pos;
+ int len;
+
+ if (event == EV_TIMEOUT) {
+ cte->host->up = HOST_DOWN;
+ hce_notify_done(cte->host, "tcp_send_req: timeout");
+ return;
+ }
+ pos = 0;
+ len = strlen(cte->req);
+ do {
+ bs = write(s, cte->req + pos, len);
+ if (bs == -1) {
+ if (errno == EAGAIN || errno == EINTR)
+ goto retry;
+ log_warnx("tcp_send_req: cannot send request");
+ cte->host->up = HOST_DOWN;
+ hce_notify_done(cte->host, "tcp_send_req: write");
+ return;
+ }
+ pos += bs;
+ len -= bs;
+ } while (len > 0);
+
+ log_debug("tcp_send_req: write done");
+ if ((cte->buf = buf_dynamic(SMALL_READ_BUF_SIZE, UINT_MAX)) == NULL)
+ fatalx("tcp_send_req: cannot create dynamic buffer");
+ event_again(&cte->ev, s, EV_TIMEOUT|EV_READ, tcp_read_buf,
+ &cte->tv_start, &cte->table->timeout, cte);
+ return;
+
+ retry:
+ event_again(&cte->ev, s, EV_TIMEOUT|EV_WRITE, tcp_send_req,
+ &cte->tv_start, &cte->table->timeout, cte);
+}
+
+void
+tcp_read_buf(int s, short event, void *arg)
+{
+ ssize_t br;
+ char rbuf[SMALL_READ_BUF_SIZE];
+ struct ctl_tcp_event *cte = arg;
+
+ if (event == EV_TIMEOUT) {
+ cte->host->up = HOST_DOWN;
+ buf_free(cte->buf);
+ hce_notify_done(cte->host, "tcp_read_buf: timeout");
+ return;
+ }
+
+ log_debug("reading");
+ bzero(rbuf, sizeof(rbuf));
+ br = read(s, rbuf, sizeof(rbuf) - 1);
+ if (br == -1) {
+ if (errno == EAGAIN || errno == EINTR)
+ goto retry;
+ cte->host->up = HOST_DOWN;
+ buf_free(cte->buf);
+ hce_notify_done(cte->host, "tcp_read_buf: read failed");
+ return;
+ } else if (br == 0) {
+ cte->host->up = HOST_DOWN;
+ (void)cte->validate_close(cte);
+ close(cte->s);
+ buf_free(cte->buf);
+ if (cte->host->up == HOST_UP)
+ hce_notify_done(cte->host, "check succeeded");
+ else
+ hce_notify_done(cte->host, "check failed");
+ return;
+ }
+ buf_add(cte->buf, rbuf, br);
+ if (cte->validate_read != NULL) {
+ log_debug("calling check");
+ if (cte->validate_read(cte) != 0)
+ goto retry;
+
+ close(cte->s);
+ buf_free(cte->buf);
+ if (cte->host->up == HOST_UP)
+ hce_notify_done(cte->host, "check succeeded");
+ else
+ hce_notify_done(cte->host, "check failed");
+ return;
+ }
+retry:
+ event_again(&cte->ev, s, EV_TIMEOUT|EV_READ, tcp_read_buf,
+ &cte->tv_start, &cte->table->timeout, cte);
+
}
diff --git a/usr.sbin/relayd/parse.y b/usr.sbin/relayd/parse.y
index e3428244243..541bb752cd5 100644
--- a/usr.sbin/relayd/parse.y
+++ b/usr.sbin/relayd/parse.y
@@ -1,4 +1,4 @@
-/* $OpenBSD: parse.y,v 1.15 2007/01/09 13:50:11 pyr Exp $ */
+/* $OpenBSD: parse.y,v 1.16 2007/01/12 16:43:01 pyr Exp $ */
/*
* Copyright (c) 2006 Pierre-Yves Ritschard <pyr@spootnik.org>
@@ -176,15 +176,12 @@ varset : STRING '=' STRING {
;
sendbuf : NOTHING {
- bzero(table->sendbuf, sizeof(table->sendbuf));
+ table->sendbuf = NULL;
}
| STRING {
- if (strlcpy(table->sendbuf, $1, sizeof(table->sendbuf))
- >= sizeof(table->sendbuf)) {
- yyerror("yyparse: send buffer truncated");
- free($1);
- YYERROR;
- }
+ table->sendbuf = strdup($1);
+ if (table->sendbuf == NULL)
+ fatal("out of memory");
free($1);
}
;
@@ -386,30 +383,25 @@ tableoptsl : host {
| CHECK HTTP STRING CODE number {
table->check = CHECK_HTTP_CODE;
table->retcode = $5;
- if (strlcpy(table->path, $3, sizeof(table->path)) >=
- sizeof(table->path)) {
- yyerror("http path truncated");
- free($3);
- YYERROR;
- }
+ asprintf(&table->sendbuf, "HEAD %s HTTP/1.0\r\n\r\n",
+ $3);
+ free($3);
+ if (table->sendbuf == NULL)
+ fatal("out of memory");
}
| CHECK HTTP STRING DIGEST STRING {
table->check = CHECK_HTTP_DIGEST;
- if (strlcpy(table->path, $3, sizeof(table->path)) >=
- sizeof(table->path)) {
- yyerror("http path truncated");
- free($3);
- free($5);
- YYERROR;
- }
+ asprintf(&table->sendbuf, "GET %s HTTP/1.0\r\n\r\n",
+ $3);
+ free($3);
+ if (table->sendbuf == NULL)
+ fatal("out of memory");
if (strlcpy(table->digest, $5,
sizeof(table->digest)) >= sizeof(table->digest)) {
yyerror("http digest truncated");
- free($3);
free($5);
YYERROR;
}
- free($3);
free($5);
}
| CHECK SEND sendbuf EXPECT STRING {
diff --git a/usr.sbin/relayd/relayd.h b/usr.sbin/relayd/relayd.h
index dc801ea20c9..7828e60f8ce 100644
--- a/usr.sbin/relayd/relayd.h
+++ b/usr.sbin/relayd/relayd.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: relayd.h,v 1.14 2007/01/11 18:05:08 reyk Exp $ */
+/* $OpenBSD: relayd.h,v 1.15 2007/01/12 16:43:01 pyr Exp $ */
/*
* Copyright (c) 2006 Pierre-Yves Ritschard <pyr@spootnik.org>
@@ -135,11 +135,14 @@ struct ctl_icmp_event {
struct ctl_tcp_event {
int s;
+ char *req;
struct buf *buf;
struct host *host;
struct table *table;
struct timeval tv_start;
struct event ev;
+ int (*validate_read)(struct ctl_tcp_event *);
+ int (*validate_close)(struct ctl_tcp_event *);
};
struct address {
@@ -191,7 +194,7 @@ struct table {
struct timeval timeout;
char name[TABLE_NAME_SIZE];
char path[MAXPATHLEN];
- char sendbuf[64];
+ char *sendbuf;
char exbuf[64];
char digest[41]; /* length of sha1 digest * 2 */
struct hostlist hosts;
@@ -347,10 +350,11 @@ void check_icmp(struct hoststated *, struct timeval *);
void check_tcp(struct ctl_tcp_event *);
/* check_http.c */
-void send_http_request(int, short, void *);
+int check_http_code(struct ctl_tcp_event *);
+int check_http_digest(struct ctl_tcp_event *);
/* check_send_expect.c */
-void start_send_expect(int, short, void *);
+int check_send_expect(struct ctl_tcp_event *);
/* hoststated.c */
struct host *host_find(struct hoststated *, objid_t);