session->internals.rsend_state = RECORD_SEND_KEY_UPDATE_3;
FALLTHROUGH;
case RECORD_SEND_KEY_UPDATE_3:
- ret = _gnutls_send_int(session, GNUTLS_APPLICATION_DATA,
- -1, EPOCH_WRITE_CURRENT,
- session->internals.record_key_update_buffer.data,
- session->internals.record_key_update_buffer.length,
- MBUFFER_FLUSH);
+ if (IS_KTLS_ENABLED(session, GNUTLS_KTLS_SEND)) {
+ return _gnutls_ktls_send(session,
+ session->internals.record_key_update_buffer.data,
+ session->internals.record_key_update_buffer.length);
+ } else {
+ ret = _gnutls_send_int(session, GNUTLS_APPLICATION_DATA,
+ -1, EPOCH_WRITE_CURRENT,
+ session->internals.record_key_update_buffer.data,
+ session->internals.record_key_update_buffer.length,
+ MBUFFER_FLUSH);
+ }
_gnutls_buffer_clear(&session->internals.record_key_update_buffer);
session->internals.rsend_state = RECORD_SEND_NORMAL;
if (ret < 0)
return gnutls_assert_val(0);
/* When using this, the outgoing handshake messages should
- * also be handled manually */
- if (!session->internals.h_read_func)
+ * also be handled manually unless KTLS is enabled exclusively
+ * in GNUTLS_KTLS_RECV mode in which case the outgoing messages
+ * are handled by GnuTLS.
+ */
+ if (!session->internals.h_read_func && !IS_KTLS_ENABLED(session, GNUTLS_KTLS_RECV))
return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
if (session->internals.initial_negotiation_completed) {
default:
assert(0);
}
+ // set callback for sending handshake messages
+ gnutls_handshake_set_read_function(session,
+ _gnutls_ktls_send_handshake_msg);
}
return in;
return data_size;
}
+int _gnutls_ktls_send_handshake_msg(gnutls_session_t session,
+ gnutls_record_encryption_level_t level,
+ gnutls_handshake_description_t htype,
+ const void *data, size_t data_size)
+{
+ return _gnutls_ktls_send_control_msg(session, GNUTLS_HANDSHAKE,
+ data, data_size);
+}
+
int _gnutls_ktls_recv_control_msg(gnutls_session_t session,
unsigned char *record_type, void *data, size_t data_size)
{
return gnutls_assert_val(GNUTLS_E_UNIMPLEMENTED_FEATURE);
}
+int _gnutls_ktls_send_handshake_msg(gnutls_session_t session,
+ gnutls_record_encryption_level_t level,
+ gnutls_handshake_description_t htype,
+ const void *data, size_t data_size)
+{
+ (void)level;
+ return gnutls_assert_val(GNUTLS_E_UNIMPLEMENTED_FEATURE);
+}
+
int _gnutls_ktls_recv_int(gnutls_session_t session, content_type_t type,
void *data, size_t data_size) {
return gnutls_assert_val(GNUTLS_E_UNIMPLEMENTED_FEATURE);
ssize_t _gnutls_ktls_send_file(gnutls_session_t session, int fd,
off_t *offset, size_t count);
+int _gnutls_ktls_send_handshake_msg(gnutls_session_t session,
+ gnutls_record_encryption_level_t level,
+ gnutls_handshake_description_t htype,
+ const void *data, size_t data_size);
+
int _gnutls_ktls_send_control_msg(gnutls_session_t session, unsigned char record_type,
const void *data, size_t data_size);
#define _gnutls_ktls_send(x, y, z) _gnutls_ktls_send_control_msg(x, GNUTLS_APPLICATION_DATA, y, z);