summaryrefslogtreecommitdiff
path: root/usr.sbin
diff options
context:
space:
mode:
authorAlexander Bluhm <bluhm@cvs.openbsd.org>2017-09-23 11:56:58 +0000
committerAlexander Bluhm <bluhm@cvs.openbsd.org>2017-09-23 11:56:58 +0000
commita52d0e4a0c941cbe4cb302b5f1634b0b8231d458 (patch)
tree3e508f9ea139577d5994da97345880c6839d0c0c /usr.sbin
parent1ea57800e0e76824bbf3417e890c7cab3285ff6c (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.c8
-rw-r--r--usr.sbin/relayd/relay_http.c22
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;