diff options
Diffstat (limited to 'usr.sbin/hoststated')
-rw-r--r-- | usr.sbin/hoststated/check_http.c | 120 | ||||
-rw-r--r-- | usr.sbin/hoststated/check_send_expect.c | 101 | ||||
-rw-r--r-- | usr.sbin/hoststated/check_tcp.c | 130 | ||||
-rw-r--r-- | usr.sbin/hoststated/hoststated.h | 12 | ||||
-rw-r--r-- | usr.sbin/hoststated/parse.y | 38 |
5 files changed, 161 insertions, 240 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 { |