st = "STATE_DISCONNECT";
break;
- case STATE_FAILED:
- st = "STATE_FAILED";
+ case STATE_DETACHED:
+ st = "STATE_DETACHED";
break;
case STATE_UPDATED:
{
VDBG (0, "ERROR: session index %u: connect failed! %U",
session_index, format_api_error, ntohl (mp->retval));
- session->session_state = STATE_FAILED | STATE_DISCONNECT;
+ session->session_state = STATE_DETACHED | STATE_DISCONNECT;
session->vpp_handle = mp->handle;
return session_index;
}
{
VDBG (0, "segment for session %u is not mounted!",
session->session_index);
- session->session_state = STATE_FAILED | STATE_DISCONNECT;
+ session->session_state = STATE_DETACHED | STATE_DISCONNECT;
vcl_send_session_disconnect (wrk, session);
return session_index;
}
{
VDBG (0, "ct segment for session %u is not mounted!",
session->session_index);
- session->session_state = STATE_FAILED | STATE_DISCONNECT;
+ session->session_state = STATE_DETACHED | STATE_DISCONNECT;
vcl_send_session_disconnect (wrk, session);
return session_index;
}
format_api_error, mp->retval);
if (session)
{
- session->session_state = STATE_FAILED;
+ session->session_state = STATE_DETACHED;
session->vpp_handle = mp->handle;
return sid;
}
}
clib_fifo_add2 (session->accept_evts_fifo, vcl_msg);
+ vcl_msg->flags = 0;
vcl_msg->accepted_msg = *msg;
/* Session handle points to listener until fully accepted by app */
vcl_session_table_add_vpp_handle (wrk, msg->handle, session->session_index);
return 0;
}
+ /* Late disconnect notification on a session that has been closed */
+ if (session->session_state == STATE_CLOSED)
+ return 0;
+
/* Caught a disconnect before actually accepting the session */
if (session->session_state == STATE_LISTEN)
{
return 0;
}
- session->session_state = STATE_VPP_CLOSING;
+ /* If not already reset change state */
+ if (session->session_state != STATE_DISCONNECT)
+ session->session_state = STATE_VPP_CLOSING;
+
return session;
}
}
vcl_session_table_del_vpp_handle (wrk, msg->handle);
+ /* Should not happen. App did not close the connection so don't free it. */
+ if (session->session_state != STATE_CLOSED)
+ {
+ VDBG (0, "app did not close session %d", session->session_index);
+ session->session_state = STATE_DETACHED;
+ session->vpp_handle = VCL_INVALID_SESSION_HANDLE;
+ return;
+ }
vcl_session_free (wrk, session);
}
{
return VPPCOM_OK;
}
- if (session->session_state & STATE_FAILED)
+ if (session->session_state & STATE_DETACHED)
{
return VPPCOM_ECONNREFUSED;
}
vcl_send_session_reset_reply (mq, wrk->my_client_index,
session->vpp_handle, 0);
}
+ else if (state == STATE_DETACHED)
+ {
+ /* Should not happen. VPP cleaned up before app confirmed close */
+ VDBG (0, "vpp freed session %d before close", session->session_index);
+ goto free_session;
+ }
session->session_state = STATE_CLOSED;
cleanup:
vcl_session_table_del_vpp_handle (wrk, vpp_handle);
+free_session:
vcl_session_free (wrk, session);
vcl_evt (VCL_EVT_CLOSE, session, rv);
*proto = VPPCOM_PROTO_UDPC;
else if (!strcmp (proto_str, "udpc"))
*proto = VPPCOM_PROTO_UDPC;
- else if (!strcmp (proto_str, "SCTP"))
- *proto = VPPCOM_PROTO_SCTP;
- else if (!strcmp (proto_str, "sctp"))
- *proto = VPPCOM_PROTO_SCTP;
else if (!strcmp (proto_str, "TLS"))
*proto = VPPCOM_PROTO_TLS;
else if (!strcmp (proto_str, "tls"))
return vcl_session_handle (client_session);
}
-static void
-vcl_ip_copy_from_ep (ip46_address_t * ip, vppcom_endpt_t * ep)
-{
- if (ep->is_ip4)
- clib_memcpy_fast (&ip->ip4, ep->ip, sizeof (ip4_address_t));
- else
- clib_memcpy_fast (&ip->ip6, ep->ip, sizeof (ip6_address_t));
-}
-
-void
-vcl_ip_copy_to_ep (ip46_address_t * ip, vppcom_endpt_t * ep, u8 is_ip4)
-{
- ep->is_ip4 = is_ip4;
- if (is_ip4)
- clib_memcpy_fast (ep->ip, &ip->ip4, sizeof (ip4_address_t));
- else
- clib_memcpy_fast (ep->ip, &ip->ip6, sizeof (ip6_address_t));
-}
-
int
vppcom_session_connect (uint32_t session_handle, vppcom_endpt_t * server_ep)
{
add_event = 1;
events[*num_ev].events |= EPOLLOUT;
session_evt_data = session->vep.ev.data.u64;
- if (session->session_state & STATE_FAILED)
+ if (session->session_state & STATE_DETACHED)
events[*num_ev].events |= EPOLLHUP;
break;
case SESSION_CTRL_EVT_DISCONNECTED:
/* VPP-TBD */
*(size_t *) buffer = (session->sndbuf_size ? session->sndbuf_size :
- session->tx_fifo ? session->tx_fifo->nitems :
+ session->tx_fifo ?
+ svm_fifo_size (session->tx_fifo) :
vcm->cfg.tx_fifo_size);
*buflen = sizeof (u32);
/* VPP-TBD */
*(size_t *) buffer = (session->rcvbuf_size ? session->rcvbuf_size :
- session->rx_fifo ? session->rx_fifo->nitems :
+ session->rx_fifo ?
+ svm_fifo_size (session->rx_fifo) :
vcm->cfg.rx_fifo_size);
*buflen = sizeof (u32);
uint32_t buflen, int flags, vppcom_endpt_t * ep)
{
vcl_worker_t *wrk = vcl_worker_get_current ();
+ vcl_session_t *session;
int rv = VPPCOM_OK;
- vcl_session_t *session = 0;
-
- if (ep)
- {
- session = vcl_session_get_w_handle (wrk, session_handle);
- if (PREDICT_FALSE (!session))
- {
- VDBG (0, "sh 0x%llx is closed!", session_handle);
- return VPPCOM_EBADFD;
- }
- ep->is_ip4 = session->transport.is_ip4;
- ep->port = session->transport.rmt_port;
- }
if (flags == 0)
rv = vppcom_session_read (session_handle, buffer, buflen);
return VPPCOM_EAFNOSUPPORT;
}
- if (ep)
+ if (ep && !rv)
{
+ session = vcl_session_get_w_handle (wrk, session_handle);
if (session->transport.is_ip4)
clib_memcpy_fast (ep->ip, &session->transport.rmt_ip.ip4,
sizeof (ip4_address_t));
else
clib_memcpy_fast (ep->ip, &session->transport.rmt_ip.ip6,
sizeof (ip6_address_t));
+ ep->is_ip4 = session->transport.is_ip4;
+ ep->port = session->transport.rmt_port;
}
return rv;
if (ep)
{
- // TBD
- return VPPCOM_EINVAL;
+ vcl_worker_t *wrk = vcl_worker_get_current ();
+ vcl_session_t *s;
+
+ s = vcl_session_get_w_handle (wrk, session_handle);
+ if (!s)
+ return VPPCOM_EBADFD;
+
+ if (s->session_type != VPPCOM_PROTO_UDP)
+ return VPPCOM_EINVAL;
+
+ /* Session not connected/bound in vpp. Create it by 'connecting' it */
+ if (PREDICT_FALSE (s->session_state == STATE_CLOSED))
+ {
+ vcl_send_session_connect (wrk, s);
+ }
+ else
+ {
+ 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)