summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVladislav Grishenko <themiron@mail.ru>2026-07-26 15:01:03 +0500
committerVladislav Grishenko <themiron@mail.ru>2026-08-02 19:36:00 +0500
commitcbc1527ec446dcaa5b338db1f34d5789a162115c (patch)
tree85b8b3b4a83a3425521c6ee39da1f4fe9a189e9b
parente9df37a8518548a6de415909eb90466d7a836f5e (diff)
downloadaccel-ppp-cbc1527ec446dcaa5b338db1f34d5789a162115c.tar.gz
accel-ppp-cbc1527ec446dcaa5b338db1f34d5789a162115c.zip
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
-rw-r--r--accel-pppd/ctrl/sstp/sstp.c25
1 files changed, 25 insertions, 0 deletions
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);
}