vlc | branch: master | Rémi Denis-Courmont <[email protected]> | Sat Feb 25 19:36:24 2017 +0200| [16d88a1a386724202f3fb8c2efc81e9fd9e941c2] | committer: Rémi Denis-Courmont
tls: drop obj and sys from vlc_tls_t > http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=16d88a1a386724202f3fb8c2efc81e9fd9e941c2 --- include/vlc_tls.h | 7 +-- modules/access/http/tunnel.c | 49 +++++++++++-------- modules/misc/gnutls.c | 111 +++++++++++++++++++++++++++---------------- src/network/tls.c | 66 ++++++++++++------------- 4 files changed, 132 insertions(+), 101 deletions(-) diff --git a/include/vlc_tls.h b/include/vlc_tls.h index 2e5da35..81772a6 100644 --- a/include/vlc_tls.h +++ b/include/vlc_tls.h @@ -38,9 +38,6 @@ typedef struct vlc_tls_creds vlc_tls_creds_t; /** TLS session */ struct vlc_tls { - vlc_object_t *obj; - void *sys; - int (*get_fd)(struct vlc_tls *); ssize_t (*readv)(struct vlc_tls *, struct iovec *, unsigned); ssize_t (*writev)(struct vlc_tls *, const struct iovec *, unsigned); @@ -180,8 +177,8 @@ struct vlc_tls_creds module_t *module; void *sys; - int (*open)(vlc_tls_creds_t *, vlc_tls_t *session, vlc_tls_t *sock, - const char *host, const char *const *alpn); + vlc_tls_t *(*open)(vlc_tls_creds_t *, vlc_tls_t *sock, + const char *host, const char *const *alpn); int (*handshake)(vlc_tls_creds_t *, vlc_tls_t *session, const char *host, const char *service, char ** /*restrict*/ alp); }; diff --git a/modules/access/http/tunnel.c b/modules/access/http/tunnel.c index fcebafd..f311ecf 100644 --- a/modules/access/http/tunnel.c +++ b/modules/access/http/tunnel.c @@ -88,17 +88,24 @@ static struct vlc_http_msg *vlc_http_tunnel_open(struct vlc_http_conn *conn, return resp; } +typedef struct vlc_tls_proxy +{ + vlc_tls_t tls; + vlc_tls_t *sock; +} vlc_tls_proxy_t; + static int vlc_tls_ProxyGetFD(vlc_tls_t *tls) { - struct vlc_tls *sock = tls->sys; + vlc_tls_proxy_t *proxy = (vlc_tls_proxy_t *)tls; - return vlc_tls_GetFD(sock); + return vlc_tls_GetFD(proxy->sock); } static ssize_t vlc_tls_ProxyRead(vlc_tls_t *tls, struct iovec *iov, unsigned count) { - struct vlc_tls *sock = tls->sys; + vlc_tls_proxy_t *proxy = (vlc_tls_proxy_t *)tls; + vlc_tls_t *sock = proxy->sock; return sock->readv(sock, iov, count); } @@ -106,21 +113,24 @@ static ssize_t vlc_tls_ProxyRead(vlc_tls_t *tls, struct iovec *iov, static ssize_t vlc_tls_ProxyWrite(vlc_tls_t *tls, const struct iovec *iov, unsigned count) { - struct vlc_tls *sock = tls->sys; + vlc_tls_proxy_t *proxy = (vlc_tls_proxy_t *)tls; + vlc_tls_t *sock = proxy->sock; return sock->writev(sock, iov, count); } static int vlc_tls_ProxyShutdown(vlc_tls_t *tls, bool duplex) { - struct vlc_tls *sock = tls->sys; + vlc_tls_proxy_t *proxy = (vlc_tls_proxy_t *)tls; - return vlc_tls_Shutdown(sock, duplex); + return vlc_tls_Shutdown(proxy->sock, duplex); } static void vlc_tls_ProxyClose(vlc_tls_t *tls) { - (void) tls; + vlc_tls_proxy_t *proxy = (vlc_tls_proxy_t *)tls; + + free(proxy); } vlc_tls_t *vlc_https_connect_proxy(void *ctx, vlc_tls_creds_t *creds, @@ -164,27 +174,26 @@ vlc_tls_t *vlc_https_connect_proxy(void *ctx, vlc_tls_creds_t *creds, assert(!ptwo); /* HTTP/2 proxy not supported yet */ - struct vlc_tls *psock = malloc(sizeof (*psock)); + vlc_tls_proxy_t *psock = malloc(sizeof (*psock)); if (unlikely(psock == NULL)) { vlc_UrlClean(&url); goto error; } - psock->obj = VLC_OBJECT(creds); - psock->sys = sock; - psock->get_fd = vlc_tls_ProxyGetFD; - psock->readv = vlc_tls_ProxyRead; - psock->writev = vlc_tls_ProxyWrite; - psock->shutdown = vlc_tls_ProxyShutdown; - psock->close = vlc_tls_ProxyClose; - psock->p = NULL; - - struct vlc_http_conn *conn = /*ptwo ? vlc_h2_conn_create(ctx, psock) - :*/ vlc_h1_conn_create(ctx, psock, false); + psock->tls.get_fd = vlc_tls_ProxyGetFD; + psock->tls.readv = vlc_tls_ProxyRead; + psock->tls.writev = vlc_tls_ProxyWrite; + psock->tls.shutdown = vlc_tls_ProxyShutdown; + psock->tls.close = vlc_tls_ProxyClose; + psock->tls.p = NULL; + psock->sock = sock; + + struct vlc_http_conn *conn = /*ptwo ? vlc_h2_conn_create(ctx, &psock->tls) + :*/ vlc_h1_conn_create(ctx, &psock->tls, false); if (unlikely(conn == NULL)) { - vlc_tls_Close(psock); + vlc_tls_Close(&psock->tls); vlc_UrlClean(&url); goto error; } diff --git a/modules/misc/gnutls.c b/modules/misc/gnutls.c index e45110e..f6440ea 100644 --- a/modules/misc/gnutls.c +++ b/modules/misc/gnutls.c @@ -1,7 +1,7 @@ /***************************************************************************** * gnutls.c ***************************************************************************** - * Copyright (C) 2004-2015 Rémi Denis-Courmont + * Copyright (C) 2004-2017 Rémi Denis-Courmont * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by @@ -39,6 +39,13 @@ #include <gnutls/gnutls.h> #include <gnutls/x509.h> +typedef struct vlc_tls_gnutls +{ + vlc_tls_t tls; + gnutls_session_t session; + vlc_object_t *obj; +} vlc_tls_gnutls_t; + static int gnutls_Init (vlc_object_t *obj) { const char *version = gnutls_check_version ("3.3.0"); @@ -51,7 +58,7 @@ static int gnutls_Init (vlc_object_t *obj) return 0; } -static int gnutls_Error(vlc_tls_t *tls, int val) +static int gnutls_Error(vlc_tls_gnutls_t *priv, int val) { switch (val) { @@ -70,10 +77,10 @@ static int gnutls_Error(vlc_tls_t *tls, int val) break; default: - msg_Err(tls->obj, "%s", gnutls_strerror (val)); + msg_Err(priv->obj, "%s", gnutls_strerror (val)); #ifndef NDEBUG if (!gnutls_error_is_fatal (val)) - msg_Err(tls->obj, "Error above should be handled"); + msg_Err(priv->obj, "Error above should be handled"); #endif #ifdef _WIN32 WSASetLastError (WSAECONNRESET); @@ -125,22 +132,23 @@ static ssize_t vlc_gnutls_writev(gnutls_transport_ptr_t ptr, static int gnutls_GetFD(vlc_tls_t *tls) { - gnutls_session_t session = tls->sys; - vlc_tls_t *sock = gnutls_transport_get_ptr(session); + vlc_tls_gnutls_t *priv = (vlc_tls_gnutls_t *)tls; + vlc_tls_t *sock = gnutls_transport_get_ptr(priv->session); return vlc_tls_GetFD(sock); } static ssize_t gnutls_Recv(vlc_tls_t *tls, struct iovec *iov, unsigned count) { - gnutls_session_t session = tls->sys; + vlc_tls_gnutls_t *priv = (vlc_tls_gnutls_t *)tls; + gnutls_session_t session = priv->session; size_t rcvd = 0; while (count > 0) { ssize_t val = gnutls_record_recv(session, iov->iov_base, iov->iov_len); if (val < 0) - return rcvd ? (ssize_t)rcvd : gnutls_Error(tls, val); + return rcvd ? (ssize_t)rcvd : gnutls_Error(priv, val); rcvd += val; @@ -157,7 +165,8 @@ static ssize_t gnutls_Recv(vlc_tls_t *tls, struct iovec *iov, unsigned count) static ssize_t gnutls_Send (vlc_tls_t *tls, const struct iovec *iov, unsigned count) { - gnutls_session_t session = tls->sys; + vlc_tls_gnutls_t *priv = (vlc_tls_gnutls_t *)tls; + gnutls_session_t session = priv->session; ssize_t val; if (!gnutls_record_check_corked(session)) @@ -176,37 +185,44 @@ static ssize_t gnutls_Send (vlc_tls_t *tls, const struct iovec *iov, } val = gnutls_record_uncork(session, 0); - return (val < 0) ? gnutls_Error (tls, val) : val; + return (val < 0) ? gnutls_Error(priv, val) : val; } static int gnutls_Shutdown(vlc_tls_t *tls, bool duplex) { - gnutls_session_t session = tls->sys; + vlc_tls_gnutls_t *priv = (vlc_tls_gnutls_t *)tls; + gnutls_session_t session = priv->session; ssize_t val; /* Flush any pending data */ val = gnutls_record_uncork(session, 0); if (val < 0) - return gnutls_Error(tls, val); + return gnutls_Error(priv, val); val = gnutls_bye(session, duplex ? GNUTLS_SHUT_RDWR : GNUTLS_SHUT_WR); if (val < 0) - return gnutls_Error(tls, val); + return gnutls_Error(priv, val); return 0; } static void gnutls_Close (vlc_tls_t *tls) { - gnutls_session_t session = tls->sys; + vlc_tls_gnutls_t *priv = (vlc_tls_gnutls_t *)tls; - gnutls_deinit (session); + gnutls_deinit(priv->session); + free(priv); } -static int gnutls_SessionOpen(vlc_tls_creds_t *creds, vlc_tls_t *tls, int type, - gnutls_certificate_credentials_t x509, - vlc_tls_t *sock, const char *const *alpn) +static vlc_tls_gnutls_t *gnutls_SessionOpen(vlc_tls_creds_t *creds, int type, + gnutls_certificate_credentials_t x509, + vlc_tls_t *sock, + const char *const *alpn) { + vlc_tls_gnutls_t *priv = malloc(sizeof (*priv)); + if (unlikely(priv == NULL)) + return NULL; + gnutls_session_t session; const char *errp; int val; @@ -221,7 +237,8 @@ static int gnutls_SessionOpen(vlc_tls_creds_t *creds, vlc_tls_t *tls, int type, { msg_Err(creds, "cannot initialize TLS session: %s", gnutls_strerror(val)); - return VLC_EGENERIC; + free(priv); + return NULL; } char *priorities = var_InheritString(creds, "gnutls-priorities"); @@ -272,17 +289,23 @@ static int gnutls_SessionOpen(vlc_tls_creds_t *creds, vlc_tls_t *tls, int type, gnutls_transport_set_ptr(session, sock); gnutls_transport_set_vec_push_function(session, vlc_gnutls_writev); gnutls_transport_set_pull_function(session, vlc_gnutls_read); - tls->sys = session; + + priv->session = session; + priv->obj = VLC_OBJECT(creds); + + vlc_tls_t *tls = &priv->tls; + tls->get_fd = gnutls_GetFD; tls->readv = gnutls_Recv; tls->writev = gnutls_Send; tls->shutdown = gnutls_Shutdown; tls->close = gnutls_Close; - return VLC_SUCCESS; + return priv; error: gnutls_deinit (session); - return VLC_EGENERIC; + free(priv); + return NULL; } /** @@ -292,10 +315,11 @@ error: * 1 if more would-be blocking recv is needed, * 2 if more would-be blocking send is required. */ -static int gnutls_ContinueHandshake(vlc_tls_creds_t *crd, vlc_tls_t *tls, +static int gnutls_ContinueHandshake(vlc_tls_creds_t *crd, + vlc_tls_gnutls_t *priv, char **restrict alp) { - gnutls_session_t session = tls->sys; + gnutls_session_t session = priv->session; int val; #ifdef _WIN32 @@ -359,15 +383,17 @@ done: return 0; } -static int gnutls_ClientSessionOpen(vlc_tls_creds_t *crd, vlc_tls_t *tls, - vlc_tls_t *sk, const char *hostname, - const char *const *alpn) +static vlc_tls_t *gnutls_ClientSessionOpen(vlc_tls_creds_t *crd, + vlc_tls_t *sk, const char *hostname, + const char *const *alpn) { - int val = gnutls_SessionOpen(crd, tls, GNUTLS_CLIENT, crd->sys, sk, alpn); - if (val != VLC_SUCCESS) - return val; + vlc_tls_gnutls_t *priv; - gnutls_session_t session = tls->sys; + priv = gnutls_SessionOpen(crd, GNUTLS_CLIENT, crd->sys, sk, alpn); + if (priv == NULL) + return NULL; + + gnutls_session_t session = priv->session; /* minimum DH prime bits */ gnutls_dh_set_prime_bits (session, 1024); @@ -377,19 +403,21 @@ static int gnutls_ClientSessionOpen(vlc_tls_creds_t *crd, vlc_tls_t *tls, gnutls_server_name_set (session, GNUTLS_NAME_DNS, hostname, strlen (hostname)); - return VLC_SUCCESS; + return &priv->tls; } static int gnutls_ClientHandshake(vlc_tls_creds_t *creds, vlc_tls_t *tls, const char *host, const char *service, char **restrict alp) { - int val = gnutls_ContinueHandshake(creds, tls, alp); + vlc_tls_gnutls_t *priv = (vlc_tls_gnutls_t *)tls; + + int val = gnutls_ContinueHandshake(creds, priv, alp); if (val) return val; /* certificates chain verification */ - gnutls_session_t session = tls->sys; + gnutls_session_t session = priv->session; unsigned status; val = gnutls_certificate_verify_peers3 (session, host, &status); @@ -565,23 +593,26 @@ typedef struct vlc_tls_creds_sys /** * Initializes a server-side TLS session. */ -static int gnutls_ServerSessionOpen(vlc_tls_creds_t *crd, vlc_tls_t *tls, - vlc_tls_t *sock, const char *hostname, - const char *const *alpn) +static vlc_tls_t *gnutls_ServerSessionOpen(vlc_tls_creds_t *crd, + vlc_tls_t *sk, const char *hostname, + const char *const *alpn) { vlc_tls_creds_sys_t *sys = crd->sys; + vlc_tls_gnutls_t *priv; assert (hostname == NULL); - return gnutls_SessionOpen(crd, tls, GNUTLS_SERVER, sys->x509_cred, sock, - alpn); + priv = gnutls_SessionOpen(crd, GNUTLS_SERVER, sys->x509_cred, sk, alpn); + return (priv != NULL) ? &priv->tls : NULL; } static int gnutls_ServerHandshake(vlc_tls_creds_t *crd, vlc_tls_t *tls, const char *host, const char *service, char **restrict alp) { + vlc_tls_gnutls_t *priv = (vlc_tls_gnutls_t *)tls; + (void) host; (void) service; - return gnutls_ContinueHandshake(crd, tls, alp); + return gnutls_ContinueHandshake(crd, priv, alp); } /** diff --git a/src/network/tls.c b/src/network/tls.c index 393db5b..e7b4c47 100644 --- a/src/network/tls.c +++ b/src/network/tls.c @@ -134,21 +134,9 @@ static vlc_tls_t *vlc_tls_SessionCreate(vlc_tls_creds_t *crd, const char *host, const char *const *alpn) { - vlc_tls_t *session = malloc(sizeof (*session)); - if (unlikely(session == NULL)) - return NULL; - - session->obj = crd->obj.parent; - session->p = NULL; - + vlc_tls_t *session; int canc = vlc_savecancel(); - - if (crd->open(crd, session, sock, host, alpn) != VLC_SUCCESS) - { - free(session); - session = NULL; - } - + session = crd->open(crd, sock, host, alpn); vlc_restorecancel(canc); return session; } @@ -158,7 +146,6 @@ void vlc_tls_SessionDelete (vlc_tls_t *session) int canc = vlc_savecancel(); session->close(session); vlc_restorecancel(canc); - free(session); } static void cleanup_tls(void *data) @@ -337,63 +324,70 @@ error: return NULL; } +typedef struct vlc_tls_socket +{ + struct vlc_tls tls; + int fd; +} vlc_tls_socket_t; + static int vlc_tls_SocketGetFD(vlc_tls_t *tls) { - return (intptr_t)tls->sys; + vlc_tls_socket_t *sock = (struct vlc_tls_socket *)tls; + + return sock->fd; } static ssize_t vlc_tls_SocketRead(vlc_tls_t *tls, struct iovec *iov, unsigned count) { - int fd = (intptr_t)tls->sys; struct msghdr msg = { .msg_iov = iov, .msg_iovlen = count, }; - return recvmsg(fd, &msg, 0); + + return recvmsg(vlc_tls_SocketGetFD(tls), &msg, 0); } static ssize_t vlc_tls_SocketWrite(vlc_tls_t *tls, const struct iovec *iov, unsigned count) { - int fd = (intptr_t)tls->sys; const struct msghdr msg = { .msg_iov = (struct iovec *)iov, .msg_iovlen = count, }; - return sendmsg(fd, &msg, MSG_NOSIGNAL); + + return sendmsg(vlc_tls_SocketGetFD(tls), &msg, MSG_NOSIGNAL); } static int vlc_tls_SocketShutdown(vlc_tls_t *tls, bool duplex) { - int fd = (intptr_t)tls->sys; - return shutdown(fd, duplex ? SHUT_RDWR : SHUT_WR); + return shutdown(vlc_tls_SocketGetFD(tls), duplex ? SHUT_RDWR : SHUT_WR); } static void vlc_tls_SocketClose(vlc_tls_t *tls) { - int fd = (intptr_t)tls->sys; - - net_Close(fd); + net_Close(vlc_tls_SocketGetFD(tls)); + free(tls); } vlc_tls_t *vlc_tls_SocketOpen(vlc_object_t *obj, int fd) { - vlc_tls_t *session = malloc(sizeof (*session)); - if (unlikely(session == NULL)) + vlc_tls_socket_t *sock = malloc(sizeof (*sock)); + if (unlikely(sock == NULL)) return NULL; - session->obj = obj; - session->sys = (void *)(intptr_t)fd; - session->get_fd = vlc_tls_SocketGetFD; - session->readv = vlc_tls_SocketRead; - session->writev = vlc_tls_SocketWrite; - session->shutdown = vlc_tls_SocketShutdown; - session->close = vlc_tls_SocketClose; - session->p = NULL; - return session; + vlc_tls_t *tls = &sock->tls; + + tls->get_fd = vlc_tls_SocketGetFD; + tls->readv = vlc_tls_SocketRead; + tls->writev = vlc_tls_SocketWrite; + tls->shutdown = vlc_tls_SocketShutdown; + tls->close = vlc_tls_SocketClose; + tls->p = NULL; + sock->fd = fd; + return tls; } static vlc_tls_t *vlc_tls_SocketOpenAddrInfoSingle(vlc_object_t *obj, _______________________________________________ vlc-commits mailing list [email protected] https://mailman.videolan.org/listinfo/vlc-commits
