From e9df37a8518548a6de415909eb90466d7a836f5e Mon Sep 17 00:00:00 2001 From: Vladislav Grishenko Date: Sun, 26 Jul 2026 14:56:53 +0500 Subject: Revert "Fixes the issue #124 HTTP replay for non SSTP query" Reverts 635ab1b7, e7a03684, 382b02b6, 4fbba471 on accel-pppd/ctrl/sstp/sstp.c: - http_send_response: sstp_send(buf) || sstp_write(&hnd) -> sstp_send(buf) - http_handler: drop the r/return 1 path - sstp_read: drop else if (n > 0) return 1 - remove the sstp_write forward decl --- accel-pppd/ctrl/sstp/sstp.c | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) (limited to 'accel-pppd/ctrl') diff --git a/accel-pppd/ctrl/sstp/sstp.c b/accel-pppd/ctrl/sstp/sstp.c index 1ab08a14..8203a1f0 100644 --- a/accel-pppd/ctrl/sstp/sstp.c +++ b/accel-pppd/ctrl/sstp/sstp.c @@ -193,7 +193,6 @@ static mempool_t conn_pool; static inline void sstp_queue(struct sstp_conn_t *conn, struct buffer_t *buf); static int sstp_send(struct sstp_conn_t *conn, struct buffer_t *buf); static inline void sstp_queue_deferred(struct sstp_conn_t *conn, struct buffer_t *buf); -static int sstp_write(struct triton_md_handler_t *h); static int sstp_read_deferred(struct sstp_conn_t *conn); static int sstp_abort(struct sstp_conn_t *conn, int disconnect); static void sstp_disconnect(struct sstp_conn_t *conn); @@ -895,7 +894,7 @@ static int http_send_response(struct sstp_conn_t *conn, char *proto, char *statu } } - return sstp_send(conn, buf) || sstp_write(&conn->hnd); + return sstp_send(conn, buf); } static int http_recv_request(struct sstp_conn_t *conn, uint8_t *data, int len) @@ -974,7 +973,7 @@ static int http_handler(struct sstp_conn_t *conn, struct buffer_t *buf) static const char *table[] = { "\n\r\n", "\r\r\n", NULL }; const char **pptr; uint8_t *ptr, *end = NULL; - int n, r; + int n; if (conn->sstp_state != STATE_SERVER_CALL_DISCONNECTED) return -1; @@ -1000,11 +999,8 @@ static int http_handler(struct sstp_conn_t *conn, struct buffer_t *buf) } else n = end - buf->head; - r = http_recv_request(conn, buf->head, n); - if (r < 0) + if (http_recv_request(conn, buf->head, n) < 0) return -1; - else if (r > 0) - return 1; buf_pull(buf, n); conn->sstp_state = STATE_SERVER_CONNECT_REQUEST_PENDING; @@ -1979,8 +1975,6 @@ static int sstp_read(struct triton_md_handler_t *h) n = conn->handler(conn, buf); if (n < 0) goto drop; - else if (n > 0) - return 1; buf_expand_tail(buf, SSTP_MAX_PACKET_SIZE); } -- cgit v1.2.3 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(+) (limited to 'accel-pppd/ctrl') 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 From 4ac0b4f396825441042ecfbbb3850ce765ae3686 Mon Sep 17 00:00:00 2001 From: Vladislav Grishenko Date: Sun, 2 Aug 2026 19:37:05 +0500 Subject: sstp: enforce standard http replies w/o body fixes http client warnings (curl): < HTTP/1.1 404 Not Found < Date: Sun, 02 Aug 2026 14:05:21 GMT * no chunk, no close, no size. Assume close to signal end --- accel-pppd/ctrl/sstp/sstp.c | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) (limited to 'accel-pppd/ctrl') diff --git a/accel-pppd/ctrl/sstp/sstp.c b/accel-pppd/ctrl/sstp/sstp.c index 6ffbf91a..9e0a63ee 100644 --- a/accel-pppd/ctrl/sstp/sstp.c +++ b/accel-pppd/ctrl/sstp/sstp.c @@ -4,6 +4,7 @@ #include #include #include +#include #include #include #include @@ -866,7 +867,7 @@ static char *http_getvalue(char *line, const char *name, int len) return sep ? line : NULL; } -static int http_send_response(struct sstp_conn_t *conn, char *proto, char *status, char *headers) +static int http_send_response(struct sstp_conn_t *conn, char *proto, char *status, char *headers, u_int64_t length) { char datetime[sizeof("aaa, dd bbb yyyy HH:MM:SS GMT")]; char linebuf[1024], *line; @@ -879,7 +880,12 @@ static int http_send_response(struct sstp_conn_t *conn, char *proto, char *statu /* "Server: %s\r\n" */ "Date: %s\r\n" "%s" - "\r\n", proto, status, /* "accel-ppp",*/ datetime, headers ? : ""); + "Content-Length: %" PRIu64 "\r\n" + "Connection: %s\r\n" + "\r\n", + proto, status, /* "accel-ppp",*/ datetime, + headers ? : "", + length, length ? "keep-alive" : "close"); if (!buf) { log_error("sstp: no memory\n"); return -1; @@ -916,17 +922,17 @@ static int http_recv_request(struct sstp_conn_t *conn, uint8_t *data, int len) if (vstrsep(line, " ", &method, &request, &proto) < 3) { if (conf_http_mode != HTTP_ERR_DENY) - http_send_response(conn, "HTTP/1.1", "400 Bad Request", NULL); + http_send_response(conn, "HTTP/1.1", "400 Bad Request", NULL, 0); return -1; } if (strncasecmp(proto, "HTTP/1", sizeof("HTTP/1") - 1) != 0) { if (conf_http_mode != HTTP_ERR_DENY) - http_send_response(conn, "HTTP/1.1", "400 Bad Request", NULL); + http_send_response(conn, "HTTP/1.1", "400 Bad Request", NULL, 0); return -1; } if (strcasecmp(method, SSTP_HTTP_METHOD) != 0 && strcasecmp(method, "GET") != 0) { if (conf_http_mode != HTTP_ERR_DENY) - http_send_response(conn, proto, "501 Not Implemented", NULL); + http_send_response(conn, proto, "501 Not Implemented", NULL, 0); return -1; } @@ -948,7 +954,7 @@ static int http_recv_request(struct sstp_conn_t *conn, uint8_t *data, int len) if (host_error) { if (conf_http_mode != HTTP_ERR_DENY) - http_send_response(conn, proto, "404 Not Found", NULL); + http_send_response(conn, proto, "404 Not Found", NULL, 0); return -1; } @@ -957,15 +963,14 @@ static int http_recv_request(struct sstp_conn_t *conn, uint8_t *data, int len) if (_asprintf(&line, "Location: %s%s\r\n", conf_http_url, (conf_http_mode == HTTP_ERR_REDIRECT_APPEND) ? request : "") < 0) return -1; - http_send_response(conn, proto, "301 Moved Permanently", line); + http_send_response(conn, proto, "301 Moved Permanently", line, 0); _free(line); } else if (conf_http_mode == HTTP_ERR_ALLOW) - http_send_response(conn, proto, "404 Not Found", NULL); + http_send_response(conn, proto, "404 Not Found", NULL, 0); return -1; } - return http_send_response(conn, proto, "200 OK", - "Content-Length: 18446744073709551615\r\n"); + return http_send_response(conn, proto, "200 OK", NULL, -1); } static int http_handler(struct sstp_conn_t *conn, struct buffer_t *buf) -- cgit v1.2.3