Hi! If you http PUT a "big" file through relayd, server<>relay read side will eventually get a EVBUFFER_TIMEOUT. Nothing comes back from the server until the PUT is done. I disabled server read timeouts for PUT requests.
While trying to fix the issue I managed to trigger another problem. For HTTP relays we open relay<>server connection only after the first request is completely read from the client. If http PUT is the the first request and is big enough we will run out of memory and eventually out of swap. To avoid the issue I will open relay<>server connection earlyer and let relayd to start sending the stuff to the server. And another one I don't know how to fix. If relayd fills all memory and swap with buffers kernel enters infinite loop. relayd is in flt_noram state and pagedaemon constantly tries to free something without any luck. userland scheduling halts. bgp looses its peers but carp still happily sends its hellos... Rivo Index: usr.sbin/relayd/relay.c =================================================================== RCS file: /cvs/src/usr.sbin/relayd/relay.c,v retrieving revision 1.236 diff -u -p -r1.236 relay.c --- usr.sbin/relayd/relay.c 28 Nov 2017 01:51:47 -0000 1. 236 +++ usr.sbin/relayd/relay.c 13 Dec 2017 00:05:33 -0000 @@ -723,7 +723,8 @@ relay_connected(int fd, short sig, void relay_tls_connected(out); bufferevent_settimeout(bev, - rlay->rl_conf.timeout.tv_sec, rlay- >rl_conf.timeout.tv_sec); + con->se_out.writeonly ? 0 : rlay->rl_conf.timeout.tv_sec, + rlay->rl_conf.timeout.tv_sec); bufferevent_setwatermark(bev, EV_WRITE, RELAY_MIN_PREFETCHED * proto->tcpbufsiz, 0); bufferevent_enable(bev, EV_READ|EV_WRITE); Index: usr.sbin/relayd/relay_http.c =================================================================== RCS file: /cvs/src/usr.sbin/relayd/relay_http.c,v retrieving revision 1.70 diff -u -p -r1.70 relay_http.c --- usr.sbin/relayd/relay_http.c 27 Nov 2017 16:25:50 -0000 1.70 +++ usr.sbin/relayd/relay_http.c 13 Dec 2017 00:05:33 -0000 @@ -439,6 +439,10 @@ relay_read_http(struct bufferevent *bev, case HTTP_METHOD_OPTIONS: case HTTP_METHOD_POST: case HTTP_METHOD_PUT: + con->se_out.writeonly = 1; + if(cre->dst->state == STATE_CONNECTED) + bufferevent_settimeout(bev, + 0, rlay->rl_conf.timeout.tv_sec); case HTTP_METHOD_RESPONSE: /* WebDAV methods */ case HTTP_METHOD_PROPFIND: @@ -569,6 +573,9 @@ relay_read_httpcontent(struct buffereven goto fail; cre->toread -= size; } + if (cre->dst->writeonly && cre->dst->state != STATE_CONNECTED) + if (relay_connect(con) == -1) + goto fail; DPRINTF("%s: done, size %lu, to read %lld", __func__, size, cre->toread); } Index: usr.sbin/relayd/relayd.h =================================================================== RCS file: /cvs/src/usr.sbin/relayd/relayd.h,v retrieving revision 1.248 diff -u -p -r1.248 relayd.h --- usr.sbin/relayd/relayd.h 28 Nov 2017 18:25:53 -0000 1 .248 +++ usr.sbin/relayd/relayd.h 13 Dec 2017 00:05:33 -0000 @@ -218,6 +218,7 @@ struct ctl_relay_event { int line; int done; int timedout; + int writeonly; enum relay_state state; enum direction dir;