summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSøren Sandmann <sandmann@redhat.com>2007-07-30 03:43:10 -0400
committerSøren Sandmann <sandmann@redhat.com>2007-07-30 03:43:10 -0400
commit08f39c1719b52169896b176e576adddeb57974d3 (patch)
treee0ef662d7e8f1855ac67506f4381e4897f9c64ba
parentdcabef177686cbaba73333a556db78e490d4f86c (diff)
Add writing support to LacTlsConnection
-rw-r--r--src/lacconnection.c4
-rw-r--r--src/lactlsconnection.c85
-rwxr-xr-xtests/Makefile.am2
3 files changed, 80 insertions, 11 deletions
diff --git a/src/lacconnection.c b/src/lacconnection.c
index 3913a5b..abd8f5b 100644
--- a/src/lacconnection.c
+++ b/src/lacconnection.c
@@ -166,8 +166,10 @@ emit_events_idle (LacConnection *connection)
{
if (!g_queue_is_empty (connection->pending_events))
{
+ lac_connection_ref (connection);
+
g_idle_add (
- emit_events_idle_handler, lac_connection_ref (connection));
+ emit_events_idle_handler, connection);
}
}
diff --git a/src/lactlsconnection.c b/src/lactlsconnection.c
index a5d3aa8..93335ff 100644
--- a/src/lactlsconnection.c
+++ b/src/lactlsconnection.c
@@ -31,6 +31,7 @@ struct _LacTlsConnection
gpointer data;
LacByteQueue * buffer;
+ LacByteQueue * unwritten;
gnutls_anon_client_credentials_t anoncred;
gnutls_session_t session;
@@ -39,6 +40,59 @@ struct _LacTlsConnection
};
static void
+emit_error (LacTlsConnection *tls,
+ GError *err)
+{
+ LacConnectionEvent error_event;
+
+ error_event.type = LAC_CONNECTION_EVENT_ERROR;
+ error_event.error.err = err;
+
+ tls->callback (tls, &error_event);
+
+ g_error_free (err);
+}
+
+static void
+do_writes (LacTlsConnection *connection)
+{
+ gsize n_available;
+ const gchar *buffer;
+ gsize n_written;
+ GError *err = NULL;
+
+ if (connection->need_handshake)
+ return;
+
+ buffer = lac_byte_queue_peek (connection->unwritten, &n_available);
+ do
+ {
+ n_written = gnutls_record_send (connection->session,
+ buffer, n_available);
+ if (n_written < 0)
+ {
+ if (n_written != GNUTLS_E_INTERRUPTED &&
+ n_written != GNUTLS_E_AGAIN)
+ {
+ err = (GError *)0x01; /* FIXME - make a new error */
+ }
+
+ n_written = 0;
+ }
+
+ lac_byte_queue_delete_head (connection->unwritten, n_written);
+ }
+ while (n_written > 0);
+
+ if (err)
+ {
+ emit_error (connection, err);
+
+ lac_connection_close (connection->tcp_connection);
+ }
+}
+
+static void
tcp_callback (LacConnection *connection,
const LacConnectionEvent *event)
{
@@ -55,8 +109,8 @@ tcp_callback (LacConnection *connection,
case LAC_CONNECTION_EVENT_READ:
/* add data to buffer */
lac_byte_queue_append (tls->buffer, event->read.data, event->read.len);
-
- if (tls->need_handshake)
+
+ if (tls->need_handshake)
{
if (gnutls_handshake (tls->session) == 0)
{
@@ -65,6 +119,11 @@ tcp_callback (LacConnection *connection,
}
}
+ /* Writing sometimes requires data to be available for reading
+ * from the TCP connection
+ */
+ do_writes (tls);
+
if (!tls->need_handshake)
{
LacByteQueue *queue;
@@ -111,14 +170,8 @@ tcp_callback (LacConnection *connection,
if (err)
{
- LacConnectionEvent error_event;
-
- error_event.type = LAC_CONNECTION_EVENT_ERROR;
- error_event.error.err = err;
-
- tls->callback (tls, &error_event);
-
- g_error_free (err);
+ emit_error (tls, err);
+
lac_connection_close (tls->tcp_connection);
}
@@ -182,6 +235,8 @@ lac_tls_connection_new (const LacAddress *address,
tls->need_handshake = TRUE;
tls->callback = callback;
tls->data = data;
+ tls->buffer = lac_byte_queue_new ();
+ tls->unwritten = lac_byte_queue_new ();
gnutls_global_init ();
gnutls_anon_allocate_client_credentials (&tls->anoncred);
@@ -198,3 +253,13 @@ lac_tls_connection_new (const LacAddress *address,
return tls;
}
+
+void
+lac_tls_connection_write (LacTlsConnection *tls,
+ const gchar *data,
+ guint len)
+{
+ lac_byte_queue_append (tls->unwritten, data, len);
+
+ do_writes (tls);
+}
diff --git a/tests/Makefile.am b/tests/Makefile.am
index eb9c277..ccf8b77 100755
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -10,6 +10,7 @@ TESTPROGRAMS = \
connection-test \
connection2-test \
udp-test \
+ tls-test \
watch-test \
lacwget
@@ -33,6 +34,7 @@ connection_test_LDADD = $(top_builddir)/src/liblac-1.la
connection2_test_LDADD = $(top_builddir)/src/liblac-1.la
http_test_LDADD = $(top_builddir)/src/liblac-1.la
udp_test_LDADD = $(top_builddir)/src/liblac-1.la
+tls_test_LDADD = $(top_builddir)/src/liblac-1.la
watch_test_LDADD = $(top_builddir)/src/liblac-1.la
lacwget_LDADD = $(top_builddir)/src/liblac-1.la $(MODULES_XML_LIBS)
lacwget_CFLAGS = $(MODULES_XML_CFLAGS)