[Spice-devel] [spice-gtk 08/13] openssl: learn to handle a new kind of BIO based on GIOStream

Marc-André Lureau marcandre.lureau at gmail.com
Mon Feb 3 10:02:39 PST 2014


From: Marc-André Lureau <marcandre.lureau at redhat.com>

Although reusing BIO_new_socket() once again is a hack, it seems
to be the easiest way... The proper solution is certainly to start
using GTls instead, but that will require a glib 2.28 dep bump.
---
 gtk/Makefile.am     |   4 +-
 gtk/bio-gio.c       | 135 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 gtk/bio-gio.h       |  34 +++++++++++++
 gtk/bio-gsocket.c   | 111 ------------------------------------------
 gtk/bio-gsocket.h   |  30 ------------
 gtk/spice-channel.c |   2 +-
 6 files changed, 172 insertions(+), 144 deletions(-)
 create mode 100644 gtk/bio-gio.c
 create mode 100644 gtk/bio-gio.h
 delete mode 100644 gtk/bio-gsocket.c
 delete mode 100644 gtk/bio-gsocket.h

diff --git a/gtk/Makefile.am b/gtk/Makefile.am
index 62afd36..840d129 100644
--- a/gtk/Makefile.am
+++ b/gtk/Makefile.am
@@ -210,8 +210,8 @@ USB_ACL_HELPER_SRCS =
 endif
 
 libspice_client_glib_2_0_la_SOURCES =			\
-	bio-gsocket.c					\
-	bio-gsocket.h					\
+	bio-gio.c					\
+	bio-gio.h					\
 	glib-compat.c					\
 	glib-compat.h					\
 	spice-audio.c					\
diff --git a/gtk/bio-gio.c b/gtk/bio-gio.c
new file mode 100644
index 0000000..22d58b6
--- /dev/null
+++ b/gtk/bio-gio.c
@@ -0,0 +1,135 @@
+/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+   Copyright (C) 2012 Red Hat, Inc.
+
+   This library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   This library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <string.h>
+#include <glib.h>
+
+#include "spice-util.h"
+#include "bio-gio.h"
+
+typedef struct bio_gsocket_method {
+    BIO_METHOD method;
+#if GLIB_CHECK_VERSION(2, 28, 0)
+    GIOStream *stream;
+#else
+    GSocket *gsocket;
+#endif
+} bio_gsocket_method;
+
+#define BIO_GET_GSOCKET(bio)  (((bio_gsocket_method*)bio->method)->gsocket)
+#define BIO_GET_ISTREAM(bio)  (g_io_stream_get_input_stream(((bio_gsocket_method*)bio->method)->stream))
+#define BIO_GET_OSTREAM(bio)  (g_io_stream_get_output_stream(((bio_gsocket_method*)bio->method)->stream))
+
+static int bio_gio_write(BIO *bio, const char *in, int inl)
+{
+    gssize ret;
+    GError *error = NULL;
+
+#if GLIB_CHECK_VERSION(2, 28, 0)
+    ret = g_pollable_output_stream_write_nonblocking(G_POLLABLE_OUTPUT_STREAM(BIO_GET_OSTREAM(bio)),
+#else
+    ret = g_socket_send(BIO_GET_GSOCKET(bio),
+#endif
+                        in, inl, NULL, &error);
+    BIO_clear_retry_flags(bio);
+
+    if (g_error_matches(error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK))
+        BIO_set_retry_write(bio);
+    if (error != NULL) {
+        g_warning("%s", error->message);
+        g_clear_error(&error);
+    }
+
+    return ret;
+}
+
+static int bio_gio_read(BIO *bio, char *out, int outl)
+{
+    gssize ret;
+    GError *error = NULL;
+
+#if GLIB_CHECK_VERSION(2, 28, 0)
+    ret = g_pollable_input_stream_read_nonblocking(G_POLLABLE_INPUT_STREAM(BIO_GET_ISTREAM(bio)),
+#else
+    ret = g_socket_receive(BIO_GET_GSOCKET(bio),
+#endif
+                           out, outl, NULL, &error);
+    BIO_clear_retry_flags(bio);
+
+    if (g_error_matches(error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK))
+        BIO_set_retry_read(bio);
+    else if (error != NULL)
+        g_warning("%s", error->message);
+
+    g_clear_error(&error);
+
+    return ret;
+}
+
+static int bio_gio_destroy(BIO *bio)
+{
+    if (bio == NULL || bio->method == NULL)
+        return 0;
+
+    SPICE_DEBUG("bio gsocket destroy");
+    g_free(bio->method);
+    bio->method = NULL;;
+
+    return 1;
+}
+
+static int bio_gio_puts(BIO *bio, const char *str)
+{
+    int n, ret;
+
+    n = strlen(str);
+    ret = bio_gio_write(bio, str, n);
+
+    return ret;
+}
+
+G_GNUC_INTERNAL
+#if GLIB_CHECK_VERSION(2, 28, 0)
+BIO* bio_new_giostream(GIOStream *stream)
+{
+    // TODO: make an actual new BIO type, or just switch to GTls already...
+    BIO *bio = BIO_new_socket(-1, BIO_NOCLOSE);
+#else
+BIO* bio_new_gsocket(GSocket *gsocket)
+{
+    BIO *bio = BIO_new_socket(g_socket_get_fd(gsocket), BIO_NOCLOSE);
+#endif
+
+    bio_gsocket_method *bio_method = g_new(bio_gsocket_method, 1);
+    bio_method->method = *bio->method;
+#if GLIB_CHECK_VERSION(2, 28, 0)
+    bio_method->stream = stream;
+#else
+    bio_method->gsocket = gsocket;
+#endif
+
+    bio->method->destroy(bio);
+    bio->method = (BIO_METHOD*)bio_method;
+
+    bio->method->bwrite = bio_gio_write;
+    bio->method->bread = bio_gio_read;
+    bio->method->bputs = bio_gio_puts;
+    bio->method->destroy = bio_gio_destroy;
+
+    return bio;
+}
diff --git a/gtk/bio-gio.h b/gtk/bio-gio.h
new file mode 100644
index 0000000..9bd3566
--- /dev/null
+++ b/gtk/bio-gio.h
@@ -0,0 +1,34 @@
+/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+   Copyright (C) 2012 Red Hat, Inc.
+
+   This library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   This library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+#ifndef BIO_GIO_H_
+# define BIO_GIO_H_
+
+#include <openssl/bio.h>
+#include <gio/gio.h>
+
+G_BEGIN_DECLS
+
+#if GLIB_CHECK_VERSION(2, 28, 0)
+BIO* bio_new_giostream(GIOStream *stream);
+#else
+BIO* bio_new_gsocket(GSocket *gsocket);
+#endif
+
+G_END_DECLS
+
+#endif /* !BIO_GIO_H_ */
diff --git a/gtk/bio-gsocket.c b/gtk/bio-gsocket.c
deleted file mode 100644
index dbf17a2..0000000
--- a/gtk/bio-gsocket.c
+++ /dev/null
@@ -1,111 +0,0 @@
-/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
-/*
-   Copyright (C) 2012 Red Hat, Inc.
-
-   This library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   This library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with this library; if not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include <string.h>
-#include <glib.h>
-
-#include "spice-util.h"
-#include "bio-gsocket.h"
-
-typedef struct bio_gsocket_method {
-    BIO_METHOD method;
-    GSocket *gsocket;
-} bio_gsocket_method;
-
-#define BIO_GET_GSOCKET(bio)  (((bio_gsocket_method*)bio->method)->gsocket)
-
-static int bio_gsocket_bwrite(BIO *bio, const char *in, int inl)
-{
-    int ret;
-    GError *error = NULL;
-
-    ret = g_socket_send(BIO_GET_GSOCKET(bio),
-                        in, inl, NULL, &error);
-    BIO_clear_retry_flags(bio);
-
-    if (g_error_matches(error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK))
-        BIO_set_retry_write(bio);
-    if (error != NULL) {
-        g_warning("%s", error->message);
-        g_clear_error(&error);
-    }
-
-    return ret;
-}
-
-static int bio_gsocket_bread(BIO *bio, char *out, int outl)
-{
-    int ret;
-    GError *error = NULL;
-
-    ret = g_socket_receive(BIO_GET_GSOCKET(bio),
-                           out, outl, NULL, &error);
-    BIO_clear_retry_flags(bio);
-
-    if (g_error_matches(error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK))
-        BIO_set_retry_read(bio);
-    else if (error != NULL)
-        g_warning("%s", error->message);
-
-    g_clear_error(&error);
-
-    return ret;
-}
-
-static int bio_gsocket_destroy(BIO *bio)
-{
-    if (bio == NULL || bio->method == NULL)
-        return 0;
-
-    SPICE_DEBUG("bio gsocket destroy");
-    g_free(bio->method);
-    bio->method = NULL;;
-
-    return 1;
-}
-
-static int bio_gsocket_bputs(BIO *bio, const char *str)
-{
-    int n, ret;
-
-    n = strlen(str);
-    ret = bio_gsocket_bwrite(bio, str, n);
-
-    return ret;
-}
-
-G_GNUC_INTERNAL
-BIO* bio_new_gsocket(GSocket *gsocket)
-{
-    BIO *bio = BIO_new_socket(g_socket_get_fd(gsocket), BIO_NOCLOSE);
-
-    bio_gsocket_method *bio_method = g_new(bio_gsocket_method, 1);
-    bio_method->method = *bio->method;
-    bio_method->gsocket = gsocket;
-
-    bio->method->destroy(bio);
-    bio->method = (BIO_METHOD*)bio_method;
-
-    bio->method->bwrite = bio_gsocket_bwrite;
-    bio->method->bread = bio_gsocket_bread;
-    bio->method->bputs = bio_gsocket_bputs;
-    bio->method->destroy = bio_gsocket_destroy;
-
-    return bio;
-}
-
diff --git a/gtk/bio-gsocket.h b/gtk/bio-gsocket.h
deleted file mode 100644
index 7ee5e64..0000000
--- a/gtk/bio-gsocket.h
+++ /dev/null
@@ -1,30 +0,0 @@
-/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
-/*
-   Copyright (C) 2012 Red Hat, Inc.
-
-   This library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   This library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with this library; if not, see <http://www.gnu.org/licenses/>.
-*/
-#ifndef BIO_GSOCKET_H_
-# define BIO_GSOCKET_H_
-
-#include <openssl/bio.h>
-#include <gio/gio.h>
-
-G_BEGIN_DECLS
-
-BIO* bio_new_gsocket(GSocket *gsocket);
-
-G_END_DECLS
-
-#endif /* !BIO_GSOCKET_H_ */
diff --git a/gtk/spice-channel.c b/gtk/spice-channel.c
index f101c3a..9e97f28 100644
--- a/gtk/spice-channel.c
+++ b/gtk/spice-channel.c
@@ -22,7 +22,7 @@
 #include "spice-channel-priv.h"
 #include "spice-session-priv.h"
 #include "spice-marshal.h"
-#include "bio-gsocket.h"
+#include "bio-gio.h"
 
 #include <openssl/rsa.h>
 #include <openssl/evp.h>
-- 
1.8.4.2



More information about the Spice-devel mailing list