[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