diff options
author | wanghanlin <wanghanlin@corp.netease.com> | 2023-08-08 10:40:04 +0800 |
---|---|---|
committer | Florin Coras <florin.coras@gmail.com> | 2023-08-15 18:06:10 +0000 |
commit | 4747b346d0b34133acb3e41e59c42a7633ff41b9 (patch) | |
tree | cbb55693a377d211ec9d16a8cd05ffaab86c5a3a /src | |
parent | 61ab0947219c93590f6ec1198da93fe339ba70ca (diff) |
vcl: fix error state switch for vcl_handle_mq_event
When a listen session receives an ACCEPTED message, but then
receives either a RESET or DISCONNECTED message from VPP before the
session is accepted, the listen session state is switched to
VPP_CLOSING or DISCONNECT.
The subsequent CLEANUP message handler attempts to send a
disconneted or reset reply message to VPP, but since the vpp_evt_q
for the listen session is null, this leads to a crash.
Type: fix
Change-Id: Ic51f78f631fe8d15bf8c56b795f4a900c3e2f724
Signed-off-by: wanghanlin <wanghanlin@corp.netease.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/vcl/vppcom.c | 20 |
1 files changed, 18 insertions, 2 deletions
diff --git a/src/vcl/vppcom.c b/src/vcl/vppcom.c index 1791b1be7f8..6bdeb5a0db2 100644 --- a/src/vcl/vppcom.c +++ b/src/vcl/vppcom.c @@ -1054,7 +1054,15 @@ vcl_handle_mq_event (vcl_worker_t * wrk, session_event_t * e) break; if (s->session_state == VCL_STATE_CLOSED) break; - if (vcl_session_has_attr (s, VCL_SESS_ATTR_NONBLOCK)) + /* We do not postpone for blocking sessions or listen sessions because: + * 1. Blocking sessions are not part of epoll instead they're used in a + * synchronous manner, such as read/write and etc. + * 2. Listen sessions that have not yet been accepted can't change to + * VPP_CLOSING state instead can been marked as ACCEPTED_F_CLOSED. + */ + if (vcl_session_has_attr (s, VCL_SESS_ATTR_NONBLOCK) && + !(s->session_state == VCL_STATE_LISTEN || + s->session_state == VCL_STATE_LISTEN_NO_MQ)) { s->session_state = VCL_STATE_VPP_CLOSING; s->flags |= VCL_SESSION_F_PENDING_DISCONNECT; @@ -1075,7 +1083,15 @@ vcl_handle_mq_event (vcl_worker_t * wrk, session_event_t * e) break; if (s->session_state == VCL_STATE_CLOSED) break; - if (vcl_session_has_attr (s, VCL_SESS_ATTR_NONBLOCK)) + /* We do not postpone for blocking sessions or listen sessions because: + * 1. Blocking sessions are not part of epoll instead they're used in a + * synchronous manner, such as read/write and etc. + * 2. Listen sessions that have not yet been accepted can't change to + * DISCONNECT state instead can been marked as ACCEPTED_F_RESET. + */ + if (vcl_session_has_attr (s, VCL_SESS_ATTR_NONBLOCK) && + !(s->session_state == VCL_STATE_LISTEN || + s->session_state == VCL_STATE_LISTEN_NO_MQ)) { s->flags |= VCL_SESSION_F_PENDING_DISCONNECT; s->session_state = VCL_STATE_DISCONNECT; |