stcp: гасить on_close_cb/close_arg в stcp_link_close; keepalive: снапшот+ревалидация link до/после каскада (UAF)
This commit is contained in:
1 parent
da329d0479
commit
e0f5afbff8
2 files changed
+20
-3
No files matched your search
@@ -129,12 +129,24 @@ static void keepalive_timer_cb(void* arg) {
|
||||
int old_link_status = link->link_status;
|
||||
link->link_status = 0;
|
||||
etcp_fire_link_status_cbk(link, link->link_state, old_link_status);
|
||||
struct ETCP_CONN *etcp = link->etcp; /* сохранить до каскада: etcp_on_link_down может закрыть conn и освободить link */
|
||||
/* Снапшот до каскада: etcp_on_link_down может синхронно закрыть conn/линки
|
||||
* (topo_recovery → ncd_revive_entry) — link может быть освобождён. */
|
||||
struct ETCP_CONN *etcp = link->etcp;
|
||||
int is_tcp = link->is_tcp;
|
||||
struct stcp_link *tcp_link = link->tcp_link;
|
||||
int local_link_id = link->local_link_id;
|
||||
struct sockaddr_storage raddr = link->remote_addr;
|
||||
uint8_t remote_ka = link->remote_keepalive;
|
||||
int link_state = link->link_state, initialized = link->initialized;
|
||||
etcp_on_link_down(etcp, link);
|
||||
if (etcp->state == 2) return; /* conn+link освобождены каскадом, link трогать нельзя */
|
||||
if (link->is_tcp && link->tcp_link) { stcp_link_close(link->tcp_link); link->tcp_link = NULL; }
|
||||
/* каскад мог закрыть линк и без state==2 — проверить, что link ещё в списке */
|
||||
int alive = 0;
|
||||
for (struct ETCP_LINK *x = etcp->links; x; x = x->next) if (x == link) { alive = 1; break; }
|
||||
if (!alive) return;
|
||||
if (is_tcp && tcp_link) stcp_link_close(tcp_link);
|
||||
if (old_link_status) {
|
||||
DEBUG_INFO(DEBUG_CATEGORY_CONNECTION, "[%s] Link %d down: addr=%s ka=%d remote_ka=%d state=%d init=%d tmo: %llu>%llu els=%llums", link->etcp->log_name, link->local_link_id, sockaddr_storage_to_str(&link->remote_addr).str, link->recv_keepalive, link->remote_keepalive, link->link_state, link->initialized, (unsigned long long)timeout_units, (unsigned long long)elapsed, (unsigned long long)(elapsed/10));
|
||||
DEBUG_INFO(DEBUG_CATEGORY_CONNECTION, "[%s] Link %d down: addr=%s ka=%d remote_ka=%d state=%d init=%d tmo: %llu>%llu els=%llums", etcp->log_name, local_link_id, sockaddr_storage_to_str(&raddr).str, 0, remote_ka, link_state, initialized, (unsigned long long)timeout_units, (unsigned long long)elapsed, (unsigned long long)(elapsed/10));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -294,6 +294,11 @@ void stcp_link_close(struct stcp_link *link) {
|
||||
link->closing = 1;
|
||||
link->etcp_conn = NULL;
|
||||
link->etcp_link = NULL;
|
||||
/* Явный teardown гасит «внезапное» уведомление: отложенный stcp_link_close_impl
|
||||
* через stcp_conn_do_close → stcp_link_on_stcp_close не должен перевызвать
|
||||
* on_close_cb с уже освобождённым ETCP_LINK. */
|
||||
link->on_close_cb = NULL;
|
||||
link->close_arg = NULL;
|
||||
|
||||
if (link->cli) {
|
||||
struct stcp_conn *c = stcp_client_get_conn(link->cli);
|
||||
|
||||
Reference in new issue
Block a user