]> git.ipfire.org Git - thirdparty/gnutls.git/commitdiff
updates in heartbeat support
authorNikos Mavrogiannopoulos <nmav@gnutls.org>
Thu, 20 Sep 2012 21:36:00 +0000 (23:36 +0200)
committerNikos Mavrogiannopoulos <nmav@gnutls.org>
Thu, 20 Sep 2012 21:37:13 +0000 (23:37 +0200)
lib/ext/heartbeat.c
lib/gnutls_record.c
src/common.c
src/serv.c
src/socket.c
src/udp-serv.c

index d27b94f1bde80f5b8519a4d138a8b2ce74d75801..88dd9896872941755b69e42ce72b341912a89060 100644 (file)
@@ -96,13 +96,13 @@ gnutls_heartbeat_allowed (gnutls_session_t session, unsigned int type)
 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);
 }
 
 /*-
@@ -148,7 +148,7 @@ heartbeat_send_data (gnutls_session_t session, const void *data,
   _gnutls_record_log ("REC[%p]: HB sent: %d\n", session, ret);
 
   _gnutls_buffer_clear (&response);
-  return gnutls_assert_val (ret);
+  return ret;
 }
 
 /**
@@ -172,13 +172,13 @@ gnutls_heartbeat_ping (gnutls_session_t session, size_t data_size,
                        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)
     {
@@ -195,8 +195,8 @@ gnutls_heartbeat_ping (gnutls_session_t session, size_t data_size,
         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;
@@ -317,7 +317,7 @@ _gnutls_heartbeat_handle (gnutls_session_t session, mbuffer_st * bufel)
       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:
 
@@ -335,7 +335,7 @@ _gnutls_heartbeat_handle (gnutls_session_t session, mbuffer_st * bufel)
 
       _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",
index 9f91f3d15c93c91e4bcab54a06ae24ea6a54ca0a..79b49040300cdeafe797e478eb0c0d1917ce4c93 100644 (file)
@@ -508,7 +508,6 @@ check_buffers (gnutls_session_t session, content_type_t type,
 {
   if ((type == GNUTLS_APPLICATION_DATA ||
        type == GNUTLS_HANDSHAKE ||
-       type == GNUTLS_HEARTBEAT ||
        type == GNUTLS_CHANGE_CIPHER_SPEC)
       && _gnutls_record_buffer_get_size (session) > 0)
     {
@@ -591,7 +590,6 @@ record_add_to_buffers (gnutls_session_t session,
   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);
@@ -1161,7 +1159,7 @@ cleanup:
   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))
@@ -1198,10 +1196,8 @@ _gnutls_recv_int (gnutls_session_t session, content_type_t type,
 {
   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)
     {
index 4b21e22c7a3464e3bdc58d3b36bc48f72c4f395e..2bccedc8c68f8f668d33de9f1645f5a442673225 100644 (file)
@@ -1042,6 +1042,8 @@ print_list (const char *priorities, int verbose)
 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] == '*')
   {
@@ -1051,7 +1053,19 @@ int check_command(gnutls_session_t session, const char* str)
          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;
       }
   }
index b1e5a4992ad2a0815d20113b69011994531a13b5..d3dc35043e7d3974bd7b47ef5cc06f73a59a055f 100644 (file)
@@ -1342,6 +1342,10 @@ tcp_server (const char *name, int port)
               {
                 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 */
@@ -1376,10 +1380,7 @@ tcp_server (const char *name, int port)
                       {
                         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);
index b33f6bc58b72f1b032e0894ae27da6d915afa885..c50488528dbe97a0051ca668541a80e037492796 100644 (file)
@@ -50,15 +50,16 @@ socket_recv (const socket_st * socket, void *buffer, int buffer_size)
   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
       {
index 478435fa4b2b7ecaf9140c7012af72bb34bc8c71..08d2677a881737aa94a4097013334af9a956a58d 100644 (file)
@@ -144,9 +144,13 @@ void udp_server(const char* name, int port, int mtu)
 
         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)
               {