static int
heartbeat_allow_recv (gnutls_session_t session)
{
- return gnutls_heartbeat_allowed(session, 0);
+ return gnutls_heartbeat_allowed(session, GNUTLS_HB_PEER_ALLOWED_TO_SEND);
}
static int
heartbeat_allow_send (gnutls_session_t session)
{
- return gnutls_heartbeat_allowed(session, 1);
+ return gnutls_heartbeat_allowed(session, GNUTLS_HB_LOCAL_ALLOWED_TO_SEND);
}
/*-
_gnutls_record_log ("REC[%p]: HB sent: %d\n", session, ret);
_gnutls_buffer_clear (&response);
- return gnutls_assert_val (ret);
+ return ret;
}
/**
unsigned int max_tries, unsigned int flags)
{
int ret;
- unsigned int retries = 0;
+ unsigned int retries = 1;
if (data_size > MAX_HEARTBEAT_LENGTH)
return gnutls_assert_val (GNUTLS_E_UNEXPECTED_PACKET_LENGTH);
if (!heartbeat_allow_send (session))
- return GNUTLS_E_INVALID_REQUEST;
+ return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
switch(session->internals.hb_state)
{
ret = _gnutls_rnd (GNUTLS_RND_NONCE, session->internals.hb_local_data.data, data_size);
if (ret < 0)
return gnutls_assert_val(ret);
- session->internals.hb_local_data.length = data_size;
+ session->internals.hb_local_data.length = data_size;
session->internals.hb_state = SHB_SEND2;
case SHB_SEND2:
session->internals.hb_timeout = HEARTBEAT_TIMEOUT;
memcpy(session->internals.hb_remote_data.data, msg+3, hb_len);
session->internals.hb_remote_data.length = hb_len;
- return GNUTLS_E_HEARTBEAT_PING_RECEIVED;
+ return gnutls_assert_val(GNUTLS_E_HEARTBEAT_PING_RECEIVED);
case HEARTBEAT_RESPONSE:
_gnutls_buffer_reset (&session->internals.hb_local_data);
- return GNUTLS_E_HEARTBEAT_PONG_RECEIVED;
+ return gnutls_assert_val(GNUTLS_E_HEARTBEAT_PONG_RECEIVED);
default:
_gnutls_record_log
("REC[%p]: HB: received unknown type %u\n",
{
if ((type == GNUTLS_APPLICATION_DATA ||
type == GNUTLS_HANDSHAKE ||
- type == GNUTLS_HEARTBEAT ||
type == GNUTLS_CHANGE_CIPHER_SPEC)
&& _gnutls_record_buffer_get_size (session) > 0)
{
if ((recv->type == type)
&& (type == GNUTLS_APPLICATION_DATA ||
type == GNUTLS_CHANGE_CIPHER_SPEC ||
- type == GNUTLS_HEARTBEAT ||
type == GNUTLS_HANDSHAKE))
{
_gnutls_record_buffer_put (session, type, seq, bufel);
return ret;
recv_error:
- if (ret < 0 && gnutls_error_is_fatal (ret) == 0)
+ if (ret < 0 && (gnutls_error_is_fatal (ret) == 0 || ret == GNUTLS_E_TIMEDOUT))
return ret;
if (IS_DTLS(session))
{
int ret;
- if (type != GNUTLS_ALERT && (data_size == 0 || data == NULL))
- {
- return GNUTLS_E_INVALID_REQUEST;
- }
+ if ((type != GNUTLS_ALERT && type != GNUTLS_HEARTBEAT) && (data_size == 0 || data == NULL))
+ return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
if (session->internals.read_eof != 0)
{
int check_command(gnutls_session_t session, const char* str)
{
size_t len = strnlen(str, 128);
+ int ret;
+
fprintf (stderr, "*** Processing %zu bytes command: %s\n", len, str);
if (len > 2 && str[0] == str[1] && str[0] == '*')
{
gnutls_rehandshake (session);
return 1;
} else if (strncmp(str, "**HEARTBEAT**", sizeof ("**HEARTBEAT**") - 1) == 0) {
- gnutls_heartbeat_ping_rnd (session);
+ ret = gnutls_heartbeat_ping (session, 300, 5, GNUTLS_HEARTBEAT_WAIT);
+ if (ret < 0)
+ {
+ if (ret == GNUTLS_E_INVALID_REQUEST)
+ {
+ fprintf(stderr, "No heartbeat in this session\n");
+ }
+ else
+ {
+ fprintf(stderr, "ping: %s\n", gnutls_strerror(ret));
+ exit(1);
+ }
+ }
return 2;
}
}
{
r = gnutls_record_recv (j->tls_session, buf,
MIN (1024, SMALL_READ_TEST));
+ if (r == GNUTLS_E_HEARTBEAT_PING_RECEIVED)
+ {
+ gnutls_heartbeat_pong(j->tls_session, 0);
+ }
if (r == GNUTLS_E_INTERRUPTED || r == GNUTLS_E_AGAIN)
{
/* do nothing */
{
if (r < 0)
{
- if (GNUTLS_E_HEARTBEAT_PONG_FAILED == r)
- fprintf (stderr,
- "HeartBeat pong failed, ping dropped\n");
- else if (r != GNUTLS_E_UNEXPECTED_PACKET_LENGTH)
+ if (r != GNUTLS_E_UNEXPECTED_PACKET_LENGTH)
{
j->http_state = HTTP_STATE_CLOSING;
check_alert (j->tls_session, r);
int ret;
if (socket->secure)
- do
- {
- ret = gnutls_record_recv (socket->session, buffer, buffer_size);
- if (GNUTLS_E_HEARTBEAT_PONG_FAILED == ret) {
- fprintf (stderr, "HeartBeat pong failed, ping dropped\n");
- ret = GNUTLS_E_AGAIN;
- }
- }
- while (ret == GNUTLS_E_INTERRUPTED || ret == GNUTLS_E_AGAIN);
+ {
+ do
+ {
+ ret = gnutls_record_recv (socket->session, buffer, buffer_size);
+ if (ret == GNUTLS_E_HEARTBEAT_PING_RECEIVED)
+ gnutls_heartbeat_pong(socket->session, 0);
+ }
+ while (ret == GNUTLS_E_INTERRUPTED || ret == GNUTLS_E_AGAIN || ret == GNUTLS_E_HEARTBEAT_PING_RECEIVED);
+
+ }
else
do
{
for(;;)
{
- do {
- ret = gnutls_record_recv_seq(session, buffer, MAX_BUFFER, sequence);
- } while(ret == GNUTLS_E_AGAIN || ret == GNUTLS_E_INTERRUPTED);
+ do
+ {
+ ret = gnutls_record_recv_seq(session, buffer, MAX_BUFFER, sequence);
+ if (ret == GNUTLS_E_HEARTBEAT_PING_RECEIVED)
+ gnutls_heartbeat_pong(session, 0);
+ }
+ while (ret == GNUTLS_E_INTERRUPTED || ret == GNUTLS_E_AGAIN || ret == GNUTLS_E_HEARTBEAT_PING_RECEIVED);
if (ret == GNUTLS_E_REHANDSHAKE)
{