GNUTLS: Improve rb_ssl_read_or_write()
* Set errno to 0 before attempting any read/write operations as it may affect our tests otherwise. * Properly check whether the gnutls_record_recv()/gnutls_record_send() call failed and distinguish between kernel and library errors.
This commit is contained in:
parent
d4e71871c0
commit
0071c423d5
1 changed files with 17 additions and 19 deletions
|
@ -304,32 +304,30 @@ rb_ssl_read_or_write(const int r_or_w, rb_fde_t *const F, void *const rbuf, cons
|
|||
{
|
||||
ssize_t ret;
|
||||
|
||||
errno = 0;
|
||||
|
||||
if(r_or_w == 0)
|
||||
ret = gnutls_record_recv(SSL_P(F), rbuf, count);
|
||||
else
|
||||
ret = gnutls_record_send(SSL_P(F), wbuf, count);
|
||||
|
||||
if(ret < 0)
|
||||
if(ret >= 0)
|
||||
return ret;
|
||||
|
||||
if(ret == GNUTLS_E_AGAIN || (ret == GNUTLS_E_INTERRUPTED && (errno == 0 || rb_ignore_errno(errno))))
|
||||
{
|
||||
switch (ret)
|
||||
{
|
||||
case GNUTLS_E_AGAIN:
|
||||
case GNUTLS_E_INTERRUPTED:
|
||||
if(rb_ignore_errno(errno))
|
||||
{
|
||||
if(gnutls_record_get_direction(*ssl) == 0)
|
||||
return RB_RW_SSL_NEED_READ;
|
||||
else
|
||||
return RB_RW_SSL_NEED_WRITE;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
F->ssl_errno = (unsigned long) -ret;
|
||||
errno = EIO;
|
||||
return RB_RW_IO_ERROR;
|
||||
}
|
||||
if(gnutls_record_get_direction(SSL_P(F)) == 0)
|
||||
return RB_RW_SSL_NEED_READ;
|
||||
else
|
||||
return RB_RW_SSL_NEED_WRITE;
|
||||
}
|
||||
return ret;
|
||||
|
||||
if(ret == GNUTLS_E_INTERRUPTED && errno != 0)
|
||||
return RB_RW_IO_ERROR;
|
||||
|
||||
errno = EIO;
|
||||
F->ssl_errno = (unsigned long) -ret;
|
||||
return RB_RW_SSL_ERROR;
|
||||
}
|
||||
|
||||
ssize_t
|
||||
|
|
Loading…
Reference in a new issue