session: fix session layer socket read 33/35433/4
authorFilip Tehlar <ftehlar@cisco.com>
Fri, 18 Feb 2022 08:49:43 +0000 (08:49 +0000)
committerFlorin Coras <florin.coras@gmail.com>
Thu, 24 Feb 2022 19:21:20 +0000 (19:21 +0000)
This fixes an issue caused by session layer reading expected part of
data (cert + key) before the client actually sends it.

Type: fix

Signed-off-by: Filip Tehlar <ftehlar@cisco.com>
Change-Id: I6ddddb08f9576211b302e814d7c2b040383e5fb7

src/plugins/hs_apps/vcl/vcl_test_client.c
src/vnet/session/session_api.c

index f0c626e..182de8f 100644 (file)
@@ -1041,7 +1041,11 @@ main (int argc, char **argv)
 
   /* Protos like tls/dtls/quic need init */
   if (vt->protos[vcm->proto]->init)
-    vt->protos[vcm->proto]->init (&ctrl->cfg);
+    {
+      rv = vt->protos[vcm->proto]->init (&ctrl->cfg);
+      if (rv)
+       vtfail ("client init failed", rv);
+    }
 
   if ((rv = vtc_ctrl_session_init (vcm, ctrl)))
     vtfail ("vppcom_session_create() ctrl session", rv);
index f6170de..615e2ad 100644 (file)
@@ -1372,6 +1372,31 @@ done:
   clib_socket_sendmsg (cs, &msg, sizeof (msg), fds, n_fds);
 }
 
+/* This is a workaround for the case when session layer starts reading
+ * the socket before the client actualy sends the data
+ */
+static clib_error_t *
+sapi_socket_receive_wait (clib_socket_t *cs, u8 *msg, u32 msg_len)
+{
+  clib_error_t *err;
+  int n_tries = 5;
+
+  while (1)
+    {
+      err = clib_socket_recvmsg (cs, msg, msg_len, 0, 0);
+      if (!err)
+       break;
+
+      if (!n_tries)
+       return err;
+
+      n_tries--;
+      usleep (1);
+    }
+
+  return err;
+}
+
 static void
 sapi_add_del_cert_key_handler (app_namespace_t *app_ns, clib_socket_t *cs,
                               app_sapi_cert_key_add_del_msg_t *mp)
@@ -1395,11 +1420,11 @@ sapi_add_del_cert_key_handler (app_namespace_t *app_ns, clib_socket_t *cs,
        }
 
       vec_validate (certkey, mp->certkey_len - 1);
-      err = clib_socket_recvmsg (cs, certkey, mp->certkey_len, 0, 0);
+
+      err = sapi_socket_receive_wait (cs, certkey, mp->certkey_len);
       if (err)
        {
          clib_error_report (err);
-         clib_error_free (err);
          rv = SESSION_E_INVALID;
          goto send_reply;
        }