[vlc-commits] tls: make vlc_tls_ClientSessionCreate() cancellation-safe

Rémi Denis-Courmont git at videolan.org
Mon Nov 9 17:52:07 CET 2015


vlc | branch: master | Rémi Denis-Courmont <remi at remlab.net> | Mon Nov  9 18:45:03 2015 +0200| [949032db15370c1e35049337f85f9c22a91fb8e3] | committer: Rémi Denis-Courmont

tls: make vlc_tls_ClientSessionCreate() cancellation-safe

> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=949032db15370c1e35049337f85f9c22a91fb8e3
---

 include/vlc_tls.h |    3 ++-
 src/network/tls.c |   33 ++++++++++++++++++++++++++-------
 2 files changed, 28 insertions(+), 8 deletions(-)

diff --git a/include/vlc_tls.h b/include/vlc_tls.h
index 7c42fd4..48e5d70 100644
--- a/include/vlc_tls.h
+++ b/include/vlc_tls.h
@@ -50,7 +50,8 @@ struct vlc_tls
  * Initiates a client TLS session.
  *
  * Performs client side of TLS handshake through a connected socket, and
- * establishes a secure channel. This is a blocking network operation.
+ * establishes a secure channel. This is a blocking network operation and may
+ * be a thread cancellation point.
  *
  * @param fd socket through which to establish the secure channel
  * @param hostname expected server name, used both as Server Name Indication
diff --git a/src/network/tls.c b/src/network/tls.c
index 4edf2ad..a153ddf 100644
--- a/src/network/tls.c
+++ b/src/network/tls.c
@@ -159,13 +159,27 @@ void vlc_tls_SessionDelete (vlc_tls_t *session)
     vlc_object_release (session);
 }
 
+static void cleanup_tls(void *data)
+{
+    vlc_tls_t *session = data;
+
+    vlc_tls_SessionDelete (session);
+}
+
 vlc_tls_t *vlc_tls_ClientSessionCreate (vlc_tls_creds_t *crd, int fd,
                                         const char *host, const char *service,
                                         const char *const *alpn, char **alp)
 {
-    vlc_tls_t *session = vlc_tls_SessionCreate (crd, fd, host, alpn);
+    vlc_tls_t *session;
+    int canc, val;
+
+    canc = vlc_savecancel();
+    session = vlc_tls_SessionCreate (crd, fd, host, alpn);
     if (session == NULL)
+    {
+        vlc_restorecancel(canc);
         return NULL;
+    }
 
     mtime_t deadline = mdate ();
     deadline += var_InheritInteger (crd, "ipv4-timeout") * 1000;
@@ -173,13 +187,16 @@ vlc_tls_t *vlc_tls_ClientSessionCreate (vlc_tls_creds_t *crd, int fd,
     struct pollfd ufd[1];
     ufd[0].fd = fd;
 
-    int val;
+    vlc_cleanup_push (cleanup_tls, session);
     while ((val = vlc_tls_SessionHandshake (session, host, service, alp)) != 0)
     {
         if (val < 0)
         {
             msg_Err (session, "TLS client session handshake error");
-            goto error;
+error:
+            vlc_tls_SessionDelete (session);
+            session = NULL;
+            break;
         }
 
         mtime_t now = mdate ();
@@ -189,16 +206,18 @@ vlc_tls_t *vlc_tls_ClientSessionCreate (vlc_tls_creds_t *crd, int fd,
         assert (val <= 2);
         ufd[0] .events = (val == 1) ? POLLIN : POLLOUT;
 
-        if (poll (ufd, 1, (deadline - now) / 1000) == 0)
+        vlc_restorecancel(canc);
+        val = poll (ufd, 1, (deadline - now) / 1000);
+        canc = vlc_savecancel();
+        if (val == 0)
         {
             msg_Err (session, "TLS client session handshake timeout");
             goto error;
         }
     }
+    vlc_cleanup_pop();
+    vlc_restorecancel(canc);
     return session;
-error:
-    vlc_tls_SessionDelete (session);
-    return NULL;
 }
 
 int vlc_tls_Read(vlc_tls_t *session, void *buf, size_t len, bool waitall)



More information about the vlc-commits mailing list