From 313a04bd35534a6cd024149d9f2c9b9487f08165 Mon Sep 17 00:00:00 2001 From: Eric Wong Date: Fri, 19 Jul 2013 00:15:31 +0000 Subject: split out {mgmt,http}_parse_continue checks Incomplete request headers are uncommon, so if we see them, something is probably off or strange. This should make it easier to maintain probe points to watch for this behavior. --- http.c | 33 +++++++++++++++++++++++---------- mgmt.c | 33 +++++++++++++++++++++++---------- probes.d | 2 ++ 3 files changed, 48 insertions(+), 20 deletions(-) diff --git a/http.c b/http.c index 6f51cf8..a7f9bad 100644 --- a/http.c +++ b/http.c @@ -236,7 +236,7 @@ http_client_died(struct mog_fd *mfd, size_t buf_len, int save_err) return MOG_NEXT_CLOSE; } -MOG_NOINLINE static char * +static char * http_rbuf_grow(struct mog_fd *mfd, struct mog_rbuf **rbuf, size_t buf_len) { struct mog_http *http = &mfd->as.http; @@ -246,6 +246,24 @@ http_rbuf_grow(struct mog_fd *mfd, struct mog_rbuf **rbuf, size_t buf_len) return *rbuf ? (*rbuf)->rptr : NULL; } +MOG_NOINLINE static bool +http_parse_continue(struct mog_fd *mfd, struct mog_rbuf **rbuf, + char **buf, size_t buf_len, uint32_t *off) +{ + struct mog_http *http = &mfd->as.http; + + assert(http->wbuf == NULL && + "tried to write (and failed) with partial req"); + if (http->_p.buf_off >= (*rbuf)->rcapa) { + *buf = http_rbuf_grow(mfd, rbuf, buf_len); + if (!*buf) + return false; + } + + *off = http->_p.buf_off; + return true; +} + static enum mog_next __http_queue_step(struct mog_fd *mfd) { struct mog_http *http = &mfd->as.http; @@ -295,15 +313,10 @@ parse: case MOG_PARSER_ERROR: goto err507or400; case MOG_PARSER_CONTINUE: - assert(http->wbuf == NULL && - "tried to write (and failed) with partial req"); - if (http->_p.buf_off >= rbuf->rcapa) { - buf = http_rbuf_grow(mfd, &rbuf, buf_len); - if (!buf) - goto err400; - } - off = http->_p.buf_off; - goto reread; + if (http_parse_continue(mfd, &rbuf, &buf, buf_len, + &off)) + goto reread; + goto err400; case MOG_PARSER_DONE: return http_run(mfd, rbuf, buf, buf_len); } diff --git a/mgmt.c b/mgmt.c index b80718c..6dd1b77 100644 --- a/mgmt.c +++ b/mgmt.c @@ -214,7 +214,7 @@ static enum mog_next mgmt_run(struct mog_fd *mfd, struct mog_rbuf *rbuf, return mgmt->wbuf ? MOG_NEXT_WAIT_WR : MOG_NEXT_ACTIVE; } -MOG_NOINLINE static char * +static char * mgmt_rbuf_grow(struct mog_fd *mfd, struct mog_rbuf **rbuf, size_t buf_len) { struct mog_mgmt *mgmt = &mfd->as.mgmt; @@ -223,6 +223,24 @@ mgmt_rbuf_grow(struct mog_fd *mfd, struct mog_rbuf **rbuf, size_t buf_len) return *rbuf ? (*rbuf)->rptr : NULL; } +MOG_NOINLINE static bool +mgmt_parse_continue(struct mog_fd *mfd, struct mog_rbuf **rbuf, + char **buf, size_t buf_len, off_t *off) +{ + struct mog_mgmt *mgmt = &mfd->as.mgmt; + + assert(mgmt->wbuf == NULL && + "tried to write (and failed) with partial req"); + if (mgmt->buf_off >= (*rbuf)->rcapa) { + *buf = mgmt_rbuf_grow(mfd, rbuf, buf_len); + if (!*buf) + return false; + } + + *off = mgmt->buf_off; + return true; +} + /* * this is the main event callback and called whenever mgmt * is pulled out of a queue (either idle or active) @@ -271,15 +289,10 @@ parse: syslog(LOG_ERR, "mgmt parser error"); return MOG_NEXT_CLOSE; case MOG_PARSER_CONTINUE: - assert(mgmt->wbuf == NULL && - "tried to write (and failed) with partial req"); - if (mgmt->buf_off >= rbuf->rcapa) { - buf = mgmt_rbuf_grow(mfd, &rbuf, buf_len); - if (!buf) - goto too_large; - } - off = mgmt->buf_off; - goto reread; + if (mgmt_parse_continue(mfd, &rbuf, &buf, buf_len, + &off)) + goto reread; + goto too_large; case MOG_PARSER_DONE: return mgmt_run(mfd, rbuf, buf, buf_len); } diff --git a/probes.d b/probes.d index c5f55ba..d6197d6 100644 --- a/probes.d +++ b/probes.d @@ -29,5 +29,7 @@ provider cmogstored { probe write_buffered(); /* DWARF: mgmt_rbuf_grow */ + /* DWARF: mgmt_parse_continue */ /* DWARF: http_rbuf_grow */ + /* DWARF: http_parse_continue */ }; -- cgit v1.2.3-24-ge0c7