From: Marcel Holtmann Date: Sun, 7 Nov 2010 09:10:43 +0000 (+0100) Subject: Add support for handling non-blocking GnuTLS channels X-Git-Tag: 0.64~91 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=388cc83fb1569cab0df137c154374622b23569a9;p=platform%2Fupstream%2Fconnman.git Add support for handling non-blocking GnuTLS channels --- diff --git a/gweb/giognutls.c b/gweb/giognutls.c index e55a8fd..e6c1bde 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,