]> git.sesse.net Git - vlc/commitdiff
tls: allocate server session in core
authorRémi Denis-Courmont <remi@remlab.net>
Sat, 29 Sep 2012 08:05:43 +0000 (11:05 +0300)
committerRémi Denis-Courmont <remi@remlab.net>
Sat, 29 Sep 2012 16:12:52 +0000 (19:12 +0300)
This enables the use of vlc_custom_create() and, later, sharing more
code between server and client sides.

include/vlc_tls.h
modules/misc/gnutls.c
src/network/tls.c

index 66fcafda5ef1869d502cdc11a82e899ecb99c6d2..c2fb2e017594f94dff39ef9bbda0bea01ea830a8 100644 (file)
 
 # include <vlc_network.h>
 
+typedef struct vlc_tls vlc_tls_t;
 typedef struct vlc_tls_sys vlc_tls_sys_t;
+typedef struct vlc_tls_creds vlc_tls_creds_t;
+typedef struct vlc_tls_creds_sys vlc_tls_creds_sys_t;
+
 
-typedef struct vlc_tls
+struct vlc_tls
 {
     VLC_COMMON_MEMBERS
 
     union {
         module_t *module; /**< Plugin handle (client) */
-        void    (*close) (struct vlc_tls *); /**< Close callback (server) */
     } u;
     vlc_tls_sys_t *sys;
 
     struct virtual_socket_t sock;
     int  (*handshake) (struct vlc_tls *);
-} vlc_tls_t;
+};
 
 VLC_API vlc_tls_t *vlc_tls_ClientCreate (vlc_object_t *, int fd,
                                          const char *hostname);
@@ -55,21 +58,20 @@ VLC_API void vlc_tls_ClientDelete (vlc_tls_t *);
 # define tls_Recv( a, b, c ) (((vlc_tls_t *)a)->sock.pf_recv (a, b, c))
 
 
-typedef struct vlc_tls_creds_sys vlc_tls_creds_sys_t;
-
 /** TLS (server-side) credentials */
-typedef struct vlc_tls_creds
+struct vlc_tls_creds
 {
     VLC_COMMON_MEMBERS
 
     module_t  *module;
     vlc_tls_creds_sys_t *sys;
 
-    int (*add_CA) (struct vlc_tls_creds *, const char *path);
-    int (*add_CRL) (struct vlc_tls_creds *, const char *path);
+    int (*add_CA) (vlc_tls_creds_t *, const char *path);
+    int (*add_CRL) (vlc_tls_creds_t *, const char *path);
 
-    vlc_tls_t *(*open) (struct vlc_tls_creds *, int fd);
-} vlc_tls_creds_t;
+    int (*open) (vlc_tls_creds_t *, vlc_tls_t *, int fd);
+    void (*close) (vlc_tls_creds_t *, vlc_tls_t *);
+};
 
 vlc_tls_creds_t *vlc_tls_ServerCreate (vlc_object_t *,
                                        const char *cert, const char *key);
index 1f3d7b04d2f469dab4c30cec2cc22eb1af930b30..e5c6aec5286ae4f64af7e24e218c84149ac640c4 100644 (file)
@@ -635,7 +635,7 @@ struct vlc_tls_creds_sys
  * Terminates TLS session and releases session data.
  * You still have to close the socket yourself.
  */
-static void gnutls_SessionClose (vlc_tls_t *session)
+static void gnutls_SessionClose (vlc_tls_creds_t *crd, vlc_tls_t *session)
 {
     vlc_tls_sys_t *sys = session->sys;
 
@@ -643,57 +643,46 @@ static void gnutls_SessionClose (vlc_tls_t *session)
         gnutls_bye (sys->session, GNUTLS_SHUT_WR);
     gnutls_deinit (sys->session);
 
-    vlc_object_release (session);
     free (sys);
+    (void) crd;
 }
 
 
 /**
  * Initializes a server-side TLS session.
  */
-static vlc_tls_t *gnutls_SessionOpen (vlc_tls_creds_t *server, int fd)
+static int gnutls_SessionOpen (vlc_tls_creds_t *crd, vlc_tls_t *session,
+                               int fd)
 {
-    vlc_tls_creds_sys_t *ssys = server->sys;
-    int val;
-
-    vlc_tls_t *session = vlc_object_create (server, sizeof (*session));
-    if (unlikely(session == NULL))
-        return NULL;
-
     vlc_tls_sys_t *sys = malloc (sizeof (*session->sys));
     if (unlikely(sys == NULL))
-    {
-        vlc_object_release (session);
-        return NULL;
-    }
+        return VLC_ENOMEM;
 
     session->sys = sys;
     session->sock.p_sys = session;
     session->sock.pf_send = gnutls_Send;
     session->sock.pf_recv = gnutls_Recv;
-    session->handshake = ssys->handshake;
-    session->u.close = gnutls_SessionClose;
+    session->handshake = crd->sys->handshake;
     sys->handshaked = false;
     sys->hostname = NULL;
 
-    val = gnutls_init (&sys->session, GNUTLS_SERVER);
+    int val = gnutls_init (&sys->session, GNUTLS_SERVER);
     if (val != 0)
     {
-        msg_Err (server, "cannot initialize TLS session: %s",
+        msg_Err (session, "cannot initialize TLS session: %s",
                  gnutls_strerror (val));
         free (sys);
-        vlc_object_release (session);
-        return NULL;
+        return VLC_EGENERIC;
     }
 
-    if (gnutls_SessionPrioritize (VLC_OBJECT (server), sys->session))
+    if (gnutls_SessionPrioritize (VLC_OBJECT (crd), sys->session))
         goto error;
 
     val = gnutls_credentials_set (sys->session, GNUTLS_CRD_CERTIFICATE,
-                                  ssys->x509_cred);
+                                  crd->sys->x509_cred);
     if (val < 0)
     {
-        msg_Err (server, "cannot set TLS session credentials: %s",
+        msg_Err (session, "cannot set TLS session credentials: %s",
                  gnutls_strerror (val));
         goto error;
     }
@@ -704,11 +693,11 @@ static vlc_tls_t *gnutls_SessionOpen (vlc_tls_creds_t *server, int fd)
 
     gnutls_transport_set_ptr (sys->session,
                               (gnutls_transport_ptr_t)(intptr_t)fd);
-    return session;
+    return VLC_SUCCESS;
 
 error:
-    gnutls_SessionClose (session);
-    return NULL;
+    gnutls_SessionClose (crd, session);
+    return VLC_EGENERIC;
 }
 
 
@@ -791,6 +780,7 @@ static int OpenServer (vlc_object_t *obj)
     server->add_CA  = gnutls_ServerAddCA;
     server->add_CRL = gnutls_ServerAddCRL;
     server->open    = gnutls_SessionOpen;
+    server->close   = gnutls_SessionClose;
     /* No certificate validation by default */
     sys->handshake  = gnutls_ContinueHandshake;
 
index 93892aaf4dcf8c4c151a363581819123b8c18fcc..13f049dea43801dc42c8e7ec641ae8e44e5457b6 100644 (file)
@@ -113,15 +113,24 @@ int vlc_tls_ServerAddCRL (vlc_tls_creds_t *srv, const char *path)
 }
 
 
-vlc_tls_t *vlc_tls_ServerSessionCreate (vlc_tls_creds_t *srv, int fd)
+vlc_tls_t *vlc_tls_ServerSessionCreate (vlc_tls_creds_t *crd, int fd)
 {
-    return srv->open (srv, fd);
+    vlc_tls_t *session = vlc_custom_create (crd, sizeof (*session),
+                                            "tls server");
+    int val = crd->open (crd, session, fd);
+    if (val == VLC_SUCCESS)
+        return session;
+    vlc_object_release (session);
+    return NULL;
 }
 
 
-void vlc_tls_ServerSessionDelete (vlc_tls_t *ses)
+void vlc_tls_ServerSessionDelete (vlc_tls_t *session)
 {
-    ses->u.close (ses);
+    vlc_tls_creds_t *crd = (vlc_tls_creds_t *)(session->p_parent);
+
+    crd->close (crd, session);
+    vlc_object_release (session);
 }