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;
 

Reply via email to