When the relay process has exited, close the connection as soon as no
data can immediately be read from the socket anymore, and the read
buffer has been emptied.
This fixes timeouts with scripts that leave processes lingering around
without closing their fds.
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
+ if (r->process_done)
+ uloop_timeout_set(&r->timeout, 1);
+
relay_process_headers(r);
if (r->header_cb) {
relay_process_headers(r);
if (r->header_cb) {
ustream_consume(s, len);
}
ustream_consume(s, len);
}
-static void relay_close_if_done(struct relay *r)
+static void relay_close_if_done(struct uloop_timeout *timeout)
+ struct relay *r = container_of(timeout, struct relay, timeout);
struct ustream *s = &r->sfd.stream;
struct ustream *s = &r->sfd.stream;
- if (!s->eof || ustream_pending_data(s, false))
+ while (ustream_poll(&r->sfd.stream));
+
+ if (!(r->process_done || s->eof) || ustream_pending_data(s, false))
return;
uh_relay_close(r, r->ret);
return;
uh_relay_close(r, r->ret);
struct relay *r = container_of(s, struct relay, sfd.stream);
if (r->process_done)
struct relay *r = container_of(s, struct relay, sfd.stream);
if (r->process_done)
- relay_close_if_done(r);
+ uloop_timeout_set(&r->timeout, 1);
}
static void relay_proc_cb(struct uloop_process *proc, int ret)
{
struct relay *r = container_of(proc, struct relay, proc);
}
static void relay_proc_cb(struct uloop_process *proc, int ret)
{
struct relay *r = container_of(proc, struct relay, proc);
- ustream_poll(&r->sfd.stream);
r->process_done = true;
r->ret = ret;
r->process_done = true;
r->ret = ret;
- relay_close_if_done(r);
+ uloop_timeout_set(&r->timeout, 1);
}
void uh_relay_kill(struct client *cl, struct relay *r)
}
void uh_relay_kill(struct client *cl, struct relay *r)
r->proc.pid = pid;
r->proc.cb = relay_proc_cb;
uloop_process_add(&r->proc);
r->proc.pid = pid;
r->proc.cb = relay_proc_cb;
uloop_process_add(&r->proc);
+
+ r->timeout.cb = relay_close_if_done;
struct relay {
struct ustream_fd sfd;
struct uloop_process proc;
struct relay {
struct ustream_fd sfd;
struct uloop_process proc;
+ struct uloop_timeout timeout;
struct client *cl;
bool process_done;
struct client *cl;
bool process_done;