diff options
Diffstat (limited to 'protocols/ssl_gnutls.c')
| -rw-r--r-- | protocols/ssl_gnutls.c | 39 | 
1 files changed, 32 insertions, 7 deletions
| diff --git a/protocols/ssl_gnutls.c b/protocols/ssl_gnutls.c index c2eb6906..f2cb3e08 100644 --- a/protocols/ssl_gnutls.c +++ b/protocols/ssl_gnutls.c @@ -37,7 +37,7 @@ static gboolean initialized = FALSE;  struct scd  { -	SslInputFunction func; +	ssl_input_function func;  	gpointer data;  	int fd;  	gboolean established; @@ -50,7 +50,7 @@ struct scd  static void ssl_connected( gpointer data, gint source, GaimInputCondition cond ); -void *ssl_connect( char *host, int port, SslInputFunction func, gpointer data ) +void *ssl_connect( char *host, int port, ssl_input_function func, gpointer data )  {  	struct scd *conn = g_new0( struct scd, 1 ); @@ -110,15 +110,16 @@ static void ssl_handshake( gpointer data, gint source, GaimInputCondition cond )  	int st;  	if( conn->inpa != -1 ) +	{  		gaim_input_remove( conn->inpa ); +		conn->inpa = -1; +	}  	if( ( st = gnutls_handshake( conn->session ) ) < 0 )  	{  		if( st == GNUTLS_E_AGAIN || st == GNUTLS_E_INTERRUPTED )  		{ -			conn->inpa = gaim_input_add( conn->fd, -			                             gnutls_record_get_direction( conn->session ) ? -			                                 GAIM_INPUT_WRITE : GAIM_INPUT_READ, +			conn->inpa = gaim_input_add( conn->fd, ssl_getdirection( conn ),  			                             ssl_handshake, data );  		}  		else @@ -144,31 +145,49 @@ static void ssl_handshake( gpointer data, gint source, GaimInputCondition cond )  int ssl_read( void *conn, char *buf, int len )  { +	int st; +	  	if( !((struct scd*)conn)->established )  	{  		ssl_errno = SSL_NOHANDSHAKE;  		return( -1 );  	} -	return( gnutls_record_recv( ((struct scd*)conn)->session, buf, len ) ); +	st = gnutls_record_recv( ((struct scd*)conn)->session, buf, len ); +	ssl_errno = SSL_OK; +	if( st == GNUTLS_E_AGAIN || st == GNUTLS_E_INTERRUPTED ) +		ssl_errno = SSL_AGAIN; +	 +	return st;  }  int ssl_write( void *conn, const char *buf, int len )  { +	int st; +	  	if( !((struct scd*)conn)->established )  	{  		ssl_errno = SSL_NOHANDSHAKE;  		return( -1 );  	} -	return( gnutls_record_send( ((struct scd*)conn)->session, buf, len ) ); +	st = gnutls_record_send( ((struct scd*)conn)->session, buf, len ); +	 +	ssl_errno = SSL_OK; +	if( st == GNUTLS_E_AGAIN || st == GNUTLS_E_INTERRUPTED ) +		ssl_errno = SSL_AGAIN; +	 +	return st;  }  void ssl_disconnect( void *conn_ )  {  	struct scd *conn = conn_; +	if( conn->inpa != -1 ) +		gaim_input_remove( conn->inpa ); +	  	if( conn->established )  		gnutls_bye( conn->session, GNUTLS_SHUT_WR ); @@ -183,3 +202,9 @@ int ssl_getfd( void *conn )  {  	return( ((struct scd*)conn)->fd );  } + +GaimInputCondition ssl_getdirection( void *conn ) +{ +	return( gnutls_record_get_direction( ((struct scd*)conn)->session ) ? +	        GAIM_INPUT_WRITE : GAIM_INPUT_READ ); +} | 
