From cbc1527ec446dcaa5b338db1f34d5789a162115c Mon Sep 17 00:00:00 2001 From: Vladislav Grishenko Date: Sun, 26 Jul 2026 15:01:03 +0500 Subject: sstp: flush queued output on disconnect Drain out_queue to the stream in sstp_disconnect before closing, so a queued response is sent before the connection is torn down. Best-effort, non-blocking, via a sstp_flush() helper that mirrors sstp_write. Fixes: 635ab1b7 --- accel-pppd/ctrl/sstp/sstp.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/accel-pppd/ctrl/sstp/sstp.c b/accel-pppd/ctrl/sstp/sstp.c index 8203a1f0..6ffbf91a 100644 --- a/accel-pppd/ctrl/sstp/sstp.c +++ b/accel-pppd/ctrl/sstp/sstp.c @@ -2124,6 +2124,30 @@ static int sstp_send(struct sstp_conn_t *conn, struct buffer_t *buf) return 0; } +static void sstp_flush(struct sstp_conn_t *conn) +{ + struct buffer_t *buf; + int n; + + while (!list_empty(&conn->out_queue)) { + buf = list_first_entry(&conn->out_queue, typeof(*buf), entry); + while (buf->len) { + n = conn->stream->write(conn->stream, buf->head, buf->len); + if (n < 0) { + if (errno == EINTR) + continue; + if (conf_verbose && errno != EPIPE) + log_ppp_info2("sstp: flush: %s\n", strerror(errno)); + break; + } else if (n == 0) + break; + buf_pull(buf, n); + } + list_del(&buf->entry); + free_buf(buf); + } +} + static void sstp_msg_echo(struct triton_timer_t *t) { struct sstp_conn_t *conn = container_of(t, typeof(*conn), hello_timer); @@ -2225,6 +2249,7 @@ static void sstp_disconnect(struct sstp_conn_t *conn) triton_timer_del(&conn->hello_timer); if (conn->hnd.tpd) { + sstp_flush(conn); triton_md_unregister_handler(&conn->hnd, 0); conn->stream->close(conn->stream); } -- cgit v1.2.3