diff options
author | Alexander Bluhm <bluhm@cvs.openbsd.org> | 2017-09-23 11:56:58 +0000 |
---|---|---|
committer | Alexander Bluhm <bluhm@cvs.openbsd.org> | 2017-09-23 11:56:58 +0000 |
commit | a52d0e4a0c941cbe4cb302b5f1634b0b8231d458 (patch) | |
tree | 3e508f9ea139577d5994da97345880c6839d0c0c /usr.sbin | |
parent | 1ea57800e0e76824bbf3417e890c7cab3285ff6c (diff) |
The relayd regression tests for chunked HTTP traffic were failing
sporadically. If the \r and \n were read in separate chunks, relayd
got out of sync with the protocol as they were interpreted as two
lines. Use evbuffer_readln() with EVBUFFER_EOL_CRLF instead of
evbuffer_readline().
OK benno@
Diffstat (limited to 'usr.sbin')
-rw-r--r-- | usr.sbin/relayd/relay.c | 8 | ||||
-rw-r--r-- | usr.sbin/relayd/relay_http.c | 22 |
2 files changed, 17 insertions, 13 deletions
diff --git a/usr.sbin/relayd/relay.c b/usr.sbin/relayd/relay.c index c7448b3fd1b..45fa4435dc9 100644 --- a/usr.sbin/relayd/relay.c +++ b/usr.sbin/relayd/relay.c @@ -1,4 +1,4 @@ -/* $OpenBSD: relay.c,v 1.226 2017/08/28 17:31:00 bluhm Exp $ */ +/* $OpenBSD: relay.c,v 1.227 2017/09/23 11:56:57 bluhm Exp $ */ /* * Copyright (c) 2006 - 2014 Reyk Floeter <reyk@openbsd.org> @@ -1679,8 +1679,10 @@ relay_close(struct rsession *con, const char *msg) (void)print_host(&con->se_in.ss, ibuf, sizeof(ibuf)); (void)print_host(&con->se_out.ss, obuf, sizeof(obuf)); if (EVBUFFER_LENGTH(con->se_log) && - evbuffer_add_printf(con->se_log, "\r\n") != -1) - ptr = evbuffer_readline(con->se_log); + evbuffer_add_printf(con->se_log, "\r\n") != -1) { + ptr = evbuffer_readln(con->se_log, NULL, + EVBUFFER_EOL_CRLF); + } log_info("relay %s, " "session %d (%d active), %s, %s -> %s:%d, " "%s%s%s", rlay->rl_conf.name, con->se_id, relay_sessions, diff --git a/usr.sbin/relayd/relay_http.c b/usr.sbin/relayd/relay_http.c index 90ad49d63c7..2bd6952bbeb 100644 --- a/usr.sbin/relayd/relay_http.c +++ b/usr.sbin/relayd/relay_http.c @@ -1,4 +1,4 @@ -/* $OpenBSD: relay_http.c,v 1.66 2017/05/28 10:39:15 benno Exp $ */ +/* $OpenBSD: relay_http.c,v 1.67 2017/09/23 11:56:57 bluhm Exp $ */ /* * Copyright (c) 2006 - 2016 Reyk Floeter <reyk@openbsd.org> @@ -169,14 +169,16 @@ relay_read_http(struct bufferevent *bev, void *arg) goto done; } - while (!cre->done && (line = evbuffer_readline(src)) != NULL) { - linelen = strlen(line); + while (!cre->done) { + line = evbuffer_readln(src, &linelen, EVBUFFER_EOL_CRLF); + if (line == NULL) + break; /* * An empty line indicates the end of the request. * libevent already stripped the \r\n for us. */ - if (!linelen) { + if (linelen == 0) { cre->done = 1; free(line); break; @@ -594,7 +596,7 @@ relay_read_httpchunks(struct bufferevent *bev, void *arg) struct evbuffer *src = EVBUFFER_INPUT(bev); char *line; long long llval; - size_t size; + size_t size, linelen; getmonotime(&con->se_tv_last); cre->timedout = 0; @@ -625,13 +627,13 @@ relay_read_httpchunks(struct bufferevent *bev, void *arg) } switch (cre->toread) { case TOREAD_HTTP_CHUNK_LENGTH: - line = evbuffer_readline(src); + line = evbuffer_readln(src, &linelen, EVBUFFER_EOL_CRLF); if (line == NULL) { /* Ignore empty line, continue */ bufferevent_enable(bev, EV_READ); return; } - if (strlen(line) == 0) { + if (linelen == 0) { free(line); goto next; } @@ -660,7 +662,7 @@ relay_read_httpchunks(struct bufferevent *bev, void *arg) break; case TOREAD_HTTP_CHUNK_TRAILER: /* Last chunk is 0 bytes followed by trailer and empty line */ - line = evbuffer_readline(src); + line = evbuffer_readln(src, &linelen, EVBUFFER_EOL_CRLF); if (line == NULL) { /* Ignore empty line, continue */ bufferevent_enable(bev, EV_READ); @@ -671,7 +673,7 @@ relay_read_httpchunks(struct bufferevent *bev, void *arg) free(line); goto fail; } - if (strlen(line) == 0) { + if (linelen == 0) { /* Switch to HTTP header mode */ cre->toread = TOREAD_HTTP_HEADER; bev->readcb = relay_read_http; @@ -680,7 +682,7 @@ relay_read_httpchunks(struct bufferevent *bev, void *arg) break; case 0: /* Chunk is terminated by an empty newline */ - line = evbuffer_readline(src); + line = evbuffer_readln(src, &linelen, EVBUFFER_EOL_CRLF); free(line); if (relay_bufferevent_print(cre->dst, "\r\n") == -1) goto fail; |