summaryrefslogtreecommitdiff
path: root/gweb/giognutls.c
diff options
context:
space:
mode:
authorMarcel Holtmann <marcel@holtmann.org>2010-11-07 10:10:43 +0100
committerMarcel Holtmann <marcel@holtmann.org>2010-11-07 10:10:43 +0100
commit388cc83fb1569cab0df137c154374622b23569a9 (patch)
treeb180e48b36c36a092dd4bd6531cfe6bdcd912aaa /gweb/giognutls.c
parenta762ae978a9c215a1b2be1c2f6607e2d5c78e174 (diff)
downloadconnman-388cc83fb1569cab0df137c154374622b23569a9.tar.gz
connman-388cc83fb1569cab0df137c154374622b23569a9.tar.bz2
connman-388cc83fb1569cab0df137c154374622b23569a9.zip
Add support for handling non-blocking GnuTLS channels
Diffstat (limited to 'gweb/giognutls.c')
-rw-r--r--gweb/giognutls.c40
1 files changed, 33 insertions, 7 deletions
diff --git a/gweb/giognutls.c b/gweb/giognutls.c
index e55a8fdb..e6c1bde3 100644
--- a/gweb/giognutls.c
+++ b/gweb/giognutls.c
@@ -61,19 +61,33 @@ static inline void g_io_gnutls_global_init(void)
gnutls_global_init();
}
-static GIOStatus check_handshake(GIOChannel *channel, GError **error)
+static GIOStatus check_handshake(GIOChannel *channel, GError **err)
{
GIOGnuTLSChannel *gnutls_channel = (GIOGnuTLSChannel *) channel;
- int err;
+ int result;
DBG("channel %p", channel);
+again:
if (gnutls_channel->established == TRUE)
return G_IO_STATUS_NORMAL;
- err = gnutls_handshake(gnutls_channel->session);
- if (err < 0)
- return G_IO_STATUS_AGAIN;
+ result = gnutls_handshake(gnutls_channel->session);
+
+ if (result == GNUTLS_E_INTERRUPTED || result == GNUTLS_E_AGAIN) {
+ GIOFlags flags = g_io_channel_get_flags(channel);
+
+ if (flags & G_IO_FLAG_NONBLOCK)
+ return G_IO_STATUS_AGAIN;
+
+ goto again;
+ }
+
+ if (result < 0) {
+ g_set_error(err, G_IO_CHANNEL_ERROR,
+ G_IO_CHANNEL_ERROR_FAILED, "Handshake failed");
+ return G_IO_STATUS_ERROR;
+ }
gnutls_channel->established = TRUE;
@@ -107,8 +121,14 @@ again:
goto again;
}
- if (result == GNUTLS_E_INTERRUPTED || result == GNUTLS_E_AGAIN)
+ if (result == GNUTLS_E_INTERRUPTED || result == GNUTLS_E_AGAIN) {
+ GIOFlags flags = g_io_channel_get_flags(channel);
+
+ if (flags & G_IO_FLAG_NONBLOCK)
+ return G_IO_STATUS_AGAIN;
+
goto again;
+ }
if (result == GNUTLS_E_UNEXPECTED_PACKET_LENGTH)
return G_IO_STATUS_EOF;
@@ -149,8 +169,14 @@ again:
goto again;
}
- if (result == GNUTLS_E_INTERRUPTED || result == GNUTLS_E_AGAIN)
+ if (result == GNUTLS_E_INTERRUPTED || result == GNUTLS_E_AGAIN) {
+ GIOFlags flags = g_io_channel_get_flags(channel);
+
+ if (flags & G_IO_FLAG_NONBLOCK)
+ return G_IO_STATUS_AGAIN;
+
goto again;
+ }
if (result < 0) {
g_set_error(err, G_IO_CHANNEL_ERROR,