VCL: Return data for recvfrom(MSG_PEEK) 27/9027/4
authorSteven <sluong@cisco.com>
Wed, 25 Oct 2017 19:33:12 +0000 (12:33 -0700)
committerDave Wallace <dwallacelf@gmail.com>
Wed, 25 Oct 2017 21:33:40 +0000 (21:33 +0000)
Implement recvfrom(MSG_PEEK) by returning data in the provided buffer
without moving the read pointer

Change-Id: Idc1b22632d78e8a499cce7d48c15e8bab0b0bf88
Signed-off-by: Steven <sluong@cisco.com>
src/vcl/vppcom.c

index 1b1a08e..de46273 100644 (file)
@@ -2236,8 +2236,9 @@ vppcom_session_connect (uint32_t session_index, vppcom_endpt_t * server_ep)
   return VPPCOM_OK;
 }
 
-int
-vppcom_session_read (uint32_t session_index, void *buf, int n)
+static inline int
+vppcom_session_read_internal (uint32_t session_index, void *buf, int n,
+                             u8 peek)
 {
   vppcom_main_t *vcm = &vppcom_main;
   session_t *session = 0;
@@ -2287,7 +2288,10 @@ vppcom_session_read (uint32_t session_index, void *buf, int n)
 
   do
     {
-      n_read = svm_fifo_dequeue_nowait (rx_fifo, n, buf);
+      if (peek)
+       n_read = svm_fifo_peek (rx_fifo, 0, n, buf);
+      else
+       n_read = svm_fifo_dequeue_nowait (rx_fifo, n, buf);
     }
   while (!session->is_nonblocking && (n_read <= 0));
 
@@ -2305,6 +2309,18 @@ vppcom_session_read (uint32_t session_index, void *buf, int n)
   return (n_read <= 0) ? VPPCOM_EAGAIN : n_read;
 }
 
+int
+vppcom_session_read (uint32_t session_index, void *buf, int n)
+{
+  return (vppcom_session_read_internal (session_index, buf, n, 0));
+}
+
+static int
+vppcom_session_peek (uint32_t session_index, void *buf, int n)
+{
+  return (vppcom_session_read_internal (session_index, buf, n, 1));
+}
+
 static inline int
 vppcom_session_read_ready (session_t * session, u32 session_index)
 {
@@ -3296,19 +3312,15 @@ vppcom_session_recvfrom (uint32_t session_index, void *buffer,
        clib_memcpy (ep->ip, &session->peer_addr.ip46.ip6,
                     sizeof (ip6_address_t));
       clib_spinlock_unlock (&vcm->sessions_lockp);
-      rv = vppcom_session_read (session_index, buffer, buflen);
     }
-  else if (flags == 0)
+
+  if (flags == 0)
     rv = vppcom_session_read (session_index, buffer, buflen);
   else if (flags & MSG_PEEK)
-    {
-      rv = vppcom_session_attr (session_index, VPPCOM_ATTR_GET_NREAD, 0, 0);
-      if (rv > buflen)
-       rv = buflen;
-    }
+    rv = vppcom_session_peek (session_index, buffer, buflen);
   else
     {
-      clib_warning ("Unsupport flags for recvfro %d", flags);
+      clib_warning ("Unsupport flags for recvfrom %d", flags);
       rv = VPPCOM_EAFNOSUPPORT;
     }