Commit 949032db authored by Rémi Denis-Courmont's avatar Rémi Denis-Courmont

tls: make vlc_tls_ClientSessionCreate() cancellation-safe

parent cc80d6a2
......@@ -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
......
......@@ -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)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment