headless/call: закрывать клиента и логировать при ошибке send() (EPIPE/ECONNRESET)

This commit is contained in:
evgeny committed 2026-09-19 10:43:04 +03:00
1 parent 6c42390fc2
commit 398078a28f
2 files changed
+21 -4

No files matched your search

+11 -3
View File
@@ -71,6 +71,8 @@ static struct call_audio* ca_of(struct UTUN_INSTANCE* inst) {
return inst ? (struct call_audio*)inst->call_audio : NULL;
}
static void ca_close_client(struct call_audio_client* cli);
/* ── отправка фрейма клиенту (с буферизацией как в control-сокете) ── */
static void ca_send_raw(struct call_audio_client* cli, const uint8_t* data, size_t len) {
@@ -94,6 +96,10 @@ static void ca_send_raw(struct call_audio_client* cli, const uint8_t* data, size
if (remain <= sizeof(cli->send_buf)) { memcpy(cli->send_buf, data + r, remain); cli->send_len = (int)remain; cli->send_offset = 0; }
if (ca && ca->ua) uasync_set_socket_write(ca->ua, cli->socket_id, 1);
}
if (r < 0) {
DEBUG_ERROR(DEBUG_CATEGORY_CALL, "%s: send failed err=%d, closing client", CH_ID, socket_get_error());
ca_close_client(cli);
}
}
static void ca_write_frame(struct call_audio_client* cli, uint8_t type, uint64_t call_id,
@@ -165,8 +171,6 @@ static void ca_media_recv(struct UTUN_INSTANCE* inst, uint64_t call_id,
/* ── разбор входящих фреймов ── */
static void ca_close_client(struct call_audio_client* cli);
static void ca_parse_frames(struct call_audio_client* cli) {
struct call_audio* ca = cli->ca;
uint8_t* p = cli->recv_buf;
@@ -228,7 +232,11 @@ static void ca_write_callback(socket_t fd, void* arg) {
if (cli->send_len <= 0) { if (ca && ca->ua) uasync_set_socket_write(ca->ua, cli->socket_id, 0); return; }
ssize_t r = send(cli->fd, cli->send_buf + cli->send_offset, cli->send_len - cli->send_offset, 0);
if (r < 0 && (socket_get_error() == ERR_AGAIN || socket_get_error() == ERR_WOULDBLOCK)) return;
if (r <= 0) { cli->send_len = 0; cli->send_offset = 0; if (ca && ca->ua) uasync_set_socket_write(ca->ua, cli->socket_id, 0); return; }
if (r <= 0) {
DEBUG_ERROR(DEBUG_CATEGORY_CALL, "%s: send failed (r=%zd err=%d) — closing client", CH_ID, r, socket_get_error());
ca_close_client(cli);
return;
}
cli->send_offset += (int)r;
if (cli->send_offset >= cli->send_len) { cli->send_len = 0; cli->send_offset = 0; if (ca && ca->ua) uasync_set_socket_write(ca->ua, cli->socket_id, 0); }
}
+10 -1
View File
@@ -84,6 +84,7 @@ static struct headless_control* hc_of(struct UTUN_INSTANCE* inst) {
/* ── Forward declarations ── */
static void hc_handle_command(struct headless_client* cli, const char* json);
static void hc_close_client(struct headless_client* cli);
/* ── JSON helpers ── */
@@ -145,6 +146,10 @@ static void cli_send(struct headless_client* cli, const char* data, size_t len)
if (remain <= sizeof(cli->send_buf)) { memcpy(cli->send_buf, data + r, remain); cli->send_len = (int)remain; cli->send_offset = 0; }
if (hc && hc->ua) uasync_set_socket_write(hc->ua, cli->socket_id, 1);
}
if (r < 0) {
DEBUG_ERROR(DEBUG_CATEGORY_HEADLESS, "headless: send failed err=%d, closing client", socket_get_error());
hc_close_client(cli);
}
}
static void cli_send_str(struct headless_client* cli, const char* s) {
@@ -237,7 +242,11 @@ static void client_write_callback(socket_t fd, void* arg) {
if (cli->send_len <= 0) { if (hc && hc->ua) uasync_set_socket_write(hc->ua, cli->socket_id, 0); return; }
ssize_t r = send(cli->fd, cli->send_buf + cli->send_offset, (int)(cli->send_len - cli->send_offset), 0);
if (r < 0 && (socket_get_error() == ERR_AGAIN || socket_get_error() == ERR_WOULDBLOCK)) return;
if (r <= 0) { cli->send_len = 0; cli->send_offset = 0; if (hc && hc->ua) uasync_set_socket_write(hc->ua, cli->socket_id, 0); return; }
if (r <= 0) {
DEBUG_ERROR(DEBUG_CATEGORY_HEADLESS, "headless: send failed (r=%zd err=%d) — closing client", r, socket_get_error());
hc_close_client(cli);
return;
}
cli->send_offset += (int)r;
if (cli->send_offset >= cli->send_len) { cli->send_len = 0; cli->send_offset = 0; if (hc && hc->ua) uasync_set_socket_write(hc->ua, cli->socket_id, 0); }
}