gnutls_early_cipher_get: Added
gnutls_early_prf_hash_get: Added
+** guile: Writes to a session record port no longer throw an exception upon
+ GNUTLS_E_AGAIN or GNUTLS_E_INTERRUPTED.
+
* Version 3.7.1 (released 2021-03-10)
** libgnutls: Fixed potential use-after-free in sending "key_share"
c_result = gnutls_record_send (c_session, (char *) data + c_sent,
size - c_sent);
if (EXPECT_FALSE (c_result < 0))
- scm_gnutls_error (c_result, FUNC_NAME);
+ {
+ if (c_result != GNUTLS_E_AGAIN && c_result != GNUTLS_E_INTERRUPTED)
+ scm_gnutls_error (c_result, FUNC_NAME);
+ }
else
c_sent += c_result;
}
#undef FUNC_NAME
/* Return the file descriptor that backs PORT. This function is called upon a
- blocking read--i.e., 'read_from_session_record_port' returned -1. */
+ blocking read--i.e., 'read_from_session_record_port' or
+ 'write_to_session_record_port' returned -1. */
static int
session_record_port_fd (SCM port)
{
c_session = scm_to_gnutls_session (session, 1, FUNC_NAME);
data = (char *) SCM_BYTEVECTOR_CONTENTS (src) + start;
- result = gnutls_record_send (c_session, data, count);
+ do
+ result = gnutls_record_send (c_session, data, count);
+ while (result == GNUTLS_E_INTERRUPTED
+ || (result == GNUTLS_E_AGAIN
+ && !SCM_GNUTLS_SESSION_TRANSPORT_IS_FD (c_session)));
+
+ if (result == GNUTLS_E_AGAIN
+ && SCM_GNUTLS_SESSION_TRANSPORT_IS_FD (c_session))
+ /* Tell Guile that reading would block. */
+ return (size_t) -1;
if (EXPECT_FALSE (result < 0))
scm_gnutls_error (result, FUNC_NAME);