mirror of
https://github.com/polhenarejos/pico-keys-sdk.git
synced 2026-08-28 23:53:02 +01:00
Add 30-second idle and 60-second pre-request deadlines, updates activity timestamps during TCP/TLS progress, and apply receive timeouts to emulation sockets.
This prevents incomplete plaintext or TLS requests from occupying a connection indefinitely, including byte-trickle attempts. Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
This commit is contained in:
@@ -52,6 +52,7 @@ typedef int socket_t;
|
||||
#include <netinet/in.h>
|
||||
#include <pthread.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/time.h>
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#else
|
||||
@@ -61,6 +62,8 @@ typedef int socket_t;
|
||||
|
||||
#define REST_SESSION_TIMEOUT_INACTIVITY_MS (10 * 60 * 1000) // 10 minutes
|
||||
#define REST_SESSION_TIMEOUT_TOTAL_MS (2 * 60 * 60 * 1000) // 2 hours
|
||||
#define REST_CONN_TIMEOUT_MS (30 * 1000)
|
||||
#define REST_CONN_TOTAL_TIMEOUT_MS (60 * 1000)
|
||||
|
||||
#ifndef ENABLE_EMULATION
|
||||
static struct tcp_pcb *listener_pcb = NULL;
|
||||
@@ -287,6 +290,8 @@ static rest_conn_t *alloc_conn(
|
||||
if (!conns[i].in_use) {
|
||||
memset(&conns[i], 0, sizeof(conns[i]));
|
||||
conns[i].in_use = true;
|
||||
conns[i].opened_ms = board_millis();
|
||||
conns[i].last_progress_ms = board_millis();
|
||||
#ifdef ENABLE_EMULATION
|
||||
conns[i].sock = sock;
|
||||
struct sockaddr_in addr;
|
||||
@@ -1214,6 +1219,7 @@ static err_t rest_recv(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err
|
||||
}
|
||||
pbuf_copy_partial(p, buffer + *len, p->tot_len, 0);
|
||||
*len += p->tot_len;
|
||||
conn->last_progress_ms = board_millis();
|
||||
tcp_recved(pcb, p->tot_len);
|
||||
pbuf_free(p);
|
||||
if (conn->conn_type == REST_CONN_TLS) {
|
||||
@@ -1226,6 +1232,15 @@ static err_t rest_recv(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err
|
||||
static err_t rest_poll(void *arg, struct tcp_pcb *pcb) {
|
||||
rest_conn_t *conn = (rest_conn_t *)arg;
|
||||
LWIP_UNUSED_ARG(pcb);
|
||||
if (conn == NULL) {
|
||||
return ERR_OK;
|
||||
}
|
||||
uint32_t now = board_millis();
|
||||
if (now - conn->last_progress_ms >= REST_CONN_TIMEOUT_MS ||
|
||||
(!conn->request_dispatched && now - conn->opened_ms >= REST_CONN_TOTAL_TIMEOUT_MS)) {
|
||||
rest_close_conn(conn);
|
||||
return ERR_ABRT;
|
||||
}
|
||||
if (conn != NULL && conn->tx_pending) {
|
||||
return rest_lwip_continue_send(conn);
|
||||
}
|
||||
@@ -1379,15 +1394,27 @@ static void *rest_emulation_thread(void *arg) {
|
||||
(void)close(accepted);
|
||||
continue;
|
||||
}
|
||||
#ifndef _MSC_VER
|
||||
{
|
||||
struct timeval timeout = { .tv_sec = REST_CONN_TIMEOUT_MS / 1000, .tv_usec = 0 };
|
||||
(void)setsockopt(accepted, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout));
|
||||
}
|
||||
#endif
|
||||
if (conn->conn_type == REST_CONN_TLS) {
|
||||
mbedtls_ssl_init(&conn->ssl);
|
||||
if (mbedtls_ssl_setup(&conn->ssl, &tls_conf) != 0) {
|
||||
rest_close_conn(conn);
|
||||
continue;
|
||||
}
|
||||
mbedtls_ssl_set_bio(&conn->ssl, &conn->sock, tls_send_cb, tls_recv_cb, NULL);
|
||||
mbedtls_ssl_set_bio(&conn->ssl, conn, tls_send_cb, tls_recv_cb, NULL);
|
||||
}
|
||||
while (conn->in_use) {
|
||||
uint32_t now = board_millis();
|
||||
if (now - conn->last_progress_ms >= REST_CONN_TIMEOUT_MS ||
|
||||
(!conn->request_dispatched && now - conn->opened_ms >= REST_CONN_TOTAL_TIMEOUT_MS)) {
|
||||
rest_close_conn(conn);
|
||||
break;
|
||||
}
|
||||
if (conn->conn_type == REST_CONN_TLS) {
|
||||
/* TLS on emulation reads directly from socket through mbedtls BIO callbacks. */
|
||||
if (tls_progress_conn(conn) != ERR_OK) {
|
||||
@@ -1402,6 +1429,7 @@ static void *rest_emulation_thread(void *arg) {
|
||||
break;
|
||||
}
|
||||
conn->request_len += (size_t)n;
|
||||
conn->last_progress_ms = board_millis();
|
||||
if (conn->request_len > REST_MAX_REQUEST_SIZE) {
|
||||
send_json_error(conn, 413, "payload_too_large");
|
||||
break;
|
||||
|
||||
@@ -57,6 +57,8 @@ typedef struct {
|
||||
struct tcp_pcb *pcb;
|
||||
#endif
|
||||
size_t request_len;
|
||||
uint32_t opened_ms;
|
||||
uint32_t last_progress_ms;
|
||||
rest_conn_type_t conn_type;
|
||||
#ifdef _MSC_VER
|
||||
char _padding[sizeof(void *) - sizeof(rest_conn_type_t)];
|
||||
|
||||
@@ -191,9 +191,11 @@ int emulation_rest_tls_port(void) {
|
||||
}
|
||||
|
||||
int tls_send_cb(void *ctx, const unsigned char *buf, size_t len) {
|
||||
const socket_t fd = (socket_t)(*(const intptr_t *)ctx);
|
||||
rest_conn_t *conn = (rest_conn_t *)ctx;
|
||||
const socket_t fd = conn->sock;
|
||||
ssize_t r = send(fd, (const char *)buf, (int)len, 0);
|
||||
if (r >= 0) {
|
||||
conn->last_progress_ms = board_millis();
|
||||
return (int)r;
|
||||
}
|
||||
#ifdef _MSC_VER
|
||||
@@ -212,9 +214,11 @@ int tls_send_cb(void *ctx, const unsigned char *buf, size_t len) {
|
||||
}
|
||||
|
||||
int tls_recv_cb(void *ctx, unsigned char *buf, size_t len) {
|
||||
const socket_t fd = (socket_t)(*(const intptr_t *)ctx);
|
||||
rest_conn_t *conn = (rest_conn_t *)ctx;
|
||||
const socket_t fd = conn->sock;
|
||||
ssize_t r = recv(fd, (char *)buf, (int)len, 0);
|
||||
if (r > 0) {
|
||||
conn->last_progress_ms = board_millis();
|
||||
return (int)r;
|
||||
}
|
||||
if (r == 0) {
|
||||
@@ -313,6 +317,7 @@ err_t tls_progress_conn(rest_conn_t *conn) {
|
||||
return ERR_ABRT;
|
||||
}
|
||||
conn->handshake_done = true;
|
||||
conn->last_progress_ms = board_millis();
|
||||
}
|
||||
|
||||
while (!conn->request_complete) {
|
||||
@@ -326,6 +331,7 @@ err_t tls_progress_conn(rest_conn_t *conn) {
|
||||
return ERR_ABRT;
|
||||
}
|
||||
conn->request_len += (size_t)ret;
|
||||
conn->last_progress_ms = board_millis();
|
||||
conn->request[conn->request_len] = '\0';
|
||||
ret = request_is_complete(conn->request, conn->request_len, &payload_offset, &payload_len);
|
||||
if (ret < 0) {
|
||||
|
||||
Reference in New Issue
Block a user