aboutsummaryrefslogtreecommitdiffstats
path: root/src/vcl/vppcom.c
diff options
context:
space:
mode:
authorwanghanlin <wanghanlin@corp.netease.com>2023-08-08 10:40:04 +0800
committerFlorin Coras <florin.coras@gmail.com>2023-08-15 18:06:10 +0000
commit4747b346d0b34133acb3e41e59c42a7633ff41b9 (patch)
treecbb55693a377d211ec9d16a8cd05ffaab86c5a3a /src/vcl/vppcom.c
parent61ab0947219c93590f6ec1198da93fe339ba70ca (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/vcl/vppcom.c')
-rw-r--r--src/vcl/vppcom.c20
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;