Hi! relay_error() sets se_done even if write buffer is not drained and relay_write() will close the connection if se_done is set
I have a case with 76k json payload where relay_error() detects EOF on read socket, sets so_done but write socket is not drained yet and socket is closed before all the content is transfered. debug output: version: HTTP/1.1 rescode: 200 resmsg: OK relay_writeheader_kv: Connection: close relay_writeheader_kv: Content-Length: 76854 relay_writeheader_kv: Content-Type: application/json;charset=utf-8 relay_read_httpcontent: session 1: size 3752, to read 76854 relay_read_httpcontent: done, size 3752, to read 73102 relay_read_httpcontent: session 1: size 16384, to read 73102 relay_read_httpcontent: done, size 16384, to read 56718 relay_write buffer len 4081 se_done 0 relay_read_httpcontent: session 1: size 56718, to read 56718 relay_read_httpcontent: done, size 56718, to read 0 relay_read_http: session 1: size 0, to read -2 relay_write buffer len 44415 se_done 0 relay_write buffer len 28031 se_done 1 relay test, session 1 (1 active), 0, 1.2.3.4 -> 5.5.66.66:9999, last write (done), GET fix: Index: usr.sbin/relayd/relay.c =================================================================== RCS file: /cvs/src/usr.sbin/relayd/relay.c,v retrieving revision 1.225 diff -u -p -r1.225 relay.c --- usr.sbin/relayd/relay.c 9 Aug 2017 21:29:17 -0000 1.225 +++ usr.sbin/relayd/relay.c 22 Aug 2017 17:07:33 -0000 @@ -788,9 +788,12 @@ relay_write(struct bufferevent *bev, voi { struct ctl_relay_event *cre = arg; struct rsession *con = cre->con; + struct evbuffer *dst = EVBUFFER_OUTPUT(bev); getmonotime(&con->se_tv_last); + if (EVBUFFER_LENGTH(dst)) + return; if (con->se_done) goto done; if (relay_splice(cre->dst) == -1) @@ -962,7 +965,6 @@ relay_error(struct bufferevent *bev, sho { struct ctl_relay_event *cre = arg; struct rsession *con = cre->con; - struct evbuffer *dst; if (error & EVBUFFER_TIMEOUT) { if (cre->splicelen >= 0) { @@ -1017,9 +1019,7 @@ relay_error(struct bufferevent *bev, sho con->se_done = 1; if (cre->dst->bev != NULL) { - dst = EVBUFFER_OUTPUT(cre->dst->bev); - if (EVBUFFER_LENGTH(dst)) - return; + return; } else if (cre->toread == TOREAD_UNLIMITED || cre->toread == 0) return; Rivo