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>
diff --git a/src/vcl/vppcom.c b/src/vcl/vppcom.c
index 1791b1b..6bdeb5a 100644
--- a/src/vcl/vppcom.c
+++ b/src/vcl/vppcom.c
@@ -1054,7 +1054,15 @@
 	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 @@
 	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;