/* Transport was cleaned up before we confirmed close. Probably the
* app is still waiting for some data that cannot be delivered.
* Confirm close to make sure everything is cleaned up */
- if (session->session_state == VCL_STATE_VPP_CLOSING)
- vcl_session_cleanup (wrk, session, vcl_session_handle (session),
- 1 /* do_disconnect */ );
+ if (session->session_state == VCL_STATE_VPP_CLOSING
+ || session->session_state == VCL_STATE_DISCONNECT)
+ {
+ vcl_session_cleanup (wrk, session, vcl_session_handle (session),
+ 1 /* do_disconnect */ );
+ /* Move to undetermined state to ensure that the session is not
+ * removed before both vpp and the app cleanup.
+ * - If the app closes first, the session is moved to CLOSED state
+ * and the session cleanup notification from vpp removes the
+ * session.
+ * - If vpp cleans up the session first, the session is moved to
+ * DETACHED state lower and subsequently the close from the app
+ * frees the session
+ */
+ session->session_state = VCL_STATE_UPDATED;
+ }
return;
}
if (ep)
{
- if (s->session_type != VPPCOM_PROTO_UDP
- || (s->flags & VCL_SESSION_F_CONNECTED))
+ if (!vcl_session_is_cl (s))
return VPPCOM_EINVAL;
/* Session not connected/bound in vpp. Create it by 'connecting' it */
if (PREDICT_FALSE (s->session_state == VCL_STATE_CLOSED))
{
+ u32 session_index = s->session_index;
+ f64 timeout = vcm->cfg.session_timeout;
+ int rv;
+
vcl_send_session_connect (wrk, s);
+ rv = vppcom_wait_for_session_state_change (session_index,
+ VCL_STATE_READY,
+ timeout);
+ if (rv < 0)
+ return rv;
+ s = vcl_session_get (wrk, session_index);
}
- else
- {
- s->transport.is_ip4 = ep->is_ip4;
- s->transport.rmt_port = ep->port;
- vcl_ip_copy_from_ep (&s->transport.rmt_ip, ep);
- }
+
+ s->transport.is_ip4 = ep->is_ip4;
+ s->transport.rmt_port = ep->port;
+ vcl_ip_copy_from_ep (&s->transport.rmt_ip, ep);
}
if (flags)