]> git.ipfire.org Git - thirdparty/gnutls.git/commitdiff
Added gnutls_record_recv_seq() that can return the sequence number
authorNikos Mavrogiannopoulos <nmav@gnutls.org>
Mon, 21 Feb 2011 23:01:57 +0000 (00:01 +0100)
committerNikos Mavrogiannopoulos <nmav@gnutls.org>
Mon, 21 Feb 2011 23:02:36 +0000 (00:02 +0100)
of the record packet, in addition to data.

lib/gnutls_buffers.c
lib/gnutls_handshake.c
lib/gnutls_record.c
lib/gnutls_record.h
lib/includes/gnutls/gnutls.h.in
lib/libgnutls.map
src/udp-serv.c

index 9a44af76d490cf29980344598f23c59f649b333c..33c6c6661e719868e3fc8e76a39636c780e0012e 100644 (file)
@@ -977,7 +977,7 @@ _gnutls_handshake_io_recv_int (gnutls_session_t session,
   while (left > 0)
     {
       dsize = ptr_size - left;
-      i = _gnutls_recv_int (session, type, htype, &ptr[dsize], left);
+      i = _gnutls_recv_int (session, type, htype, &ptr[dsize], left, NULL);
       if (i < 0)
         {
 
index 2d0aec7878800c23c0ff985ac5062bb5462c0c38..e8c427ff4bb9d57eca420295bfef3a7883eeb37a 100644 (file)
@@ -3112,7 +3112,7 @@ _gnutls_recv_handshake_final (gnutls_session_t session, int init)
     {
     case STATE0:
     case STATE30:
-      ret = _gnutls_recv_int (session, GNUTLS_CHANGE_CIPHER_SPEC, -1, &ch, 1);
+      ret = _gnutls_recv_int (session, GNUTLS_CHANGE_CIPHER_SPEC, -1, &ch, 1, NULL);
       STATE = STATE30;
       if (ret <= 0)
         {
index 84c1b4b32b1d32cf9176fc251740f225be05e562..3f6ea81e9ab49a0e7ea6bbc48fd1cf63d43ec6a0 100644 (file)
@@ -245,7 +245,7 @@ gnutls_bye (gnutls_session_t session, gnutls_close_request_t how)
           do
             {
               _gnutls_io_clear_peeked_data (session);
-              ret = _gnutls_recv_int (session, GNUTLS_ALERT, -1, NULL, 0);
+              ret = _gnutls_recv_int (session, GNUTLS_ALERT, -1, NULL, 0, NULL);
             }
           while (ret == GNUTLS_E_GOT_APPLICATION_DATA);
 
@@ -354,7 +354,7 @@ ssize_t
 _gnutls_send_int (gnutls_session_t session, content_type_t type,
                   gnutls_handshake_description_t htype,
                   unsigned int epoch_rel, const void *_data,
-                  size_t sizeofdata, unsigned int mflags)
+                  size_t data_size, unsigned int mflags)
 {
   mbuffer_st *bufel;
   size_t cipher_size;
@@ -387,7 +387,7 @@ _gnutls_send_int (gnutls_session_t session, content_type_t type,
    * ok, and means to resume.
    */
   if (session->internals.record_send_buffer.byte_length == 0 &&
-      (sizeofdata == 0 && _data == NULL))
+      (data_size == 0 && _data == NULL))
     {
       gnutls_assert ();
       return GNUTLS_E_INVALID_REQUEST;
@@ -414,12 +414,12 @@ _gnutls_send_int (gnutls_session_t session, content_type_t type,
 
   _gnutls_record_log
     ("REC[%p]: Preparing Packet %s(%d) with length: %d\n", session,
-     _gnutls_packet2str (type), type, (int) sizeofdata);
+     _gnutls_packet2str (type), type, (int) data_size);
 
-  if (sizeofdata > MAX_RECORD_SEND_SIZE(session))
+  if (data_size > MAX_RECORD_SEND_SIZE(session))
     data2send_size = MAX_RECORD_SEND_SIZE(session);
   else
-    data2send_size = sizeofdata;
+    data2send_size = data_size;
 
   /* Only encrypt if we don't have data to send 
    * from the previous run. - probably interrupted.
@@ -536,7 +536,7 @@ check_recv_type (content_type_t recv_type)
  */
 static int
 check_buffers (gnutls_session_t session, content_type_t type,
-               opaque * data, int sizeofdata)
+               opaque * data, int data_size)
 {
   if ((type == GNUTLS_APPLICATION_DATA ||
        type == GNUTLS_HANDSHAKE ||
@@ -544,7 +544,7 @@ check_buffers (gnutls_session_t session, content_type_t type,
       && _gnutls_record_buffer_get_size (type, session) > 0)
     {
       int ret, ret2;
-      ret = _gnutls_record_buffer_get (type, session, data, sizeofdata);
+      ret = _gnutls_record_buffer_get (type, session, data, data_size);
       if (ret < 0)
         {
           gnutls_assert ();
@@ -962,7 +962,7 @@ int ret;
 ssize_t
 _gnutls_recv_int (gnutls_session_t session, content_type_t type,
                   gnutls_handshake_description_t htype,
-                  opaque * data, size_t data_size)
+                  opaque * data, size_t data_size, void* seq)
 {
   uint64 *packet_sequence;
   uint8_t *ciphertext;
@@ -1032,6 +1032,8 @@ begin:
   else
     packet_sequence = &record_state->sequence_number;
 
+  if (seq)
+    memcpy(seq, packet_sequence, 8);
 
   /* Read the packet data and insert it to record_recv_buffer.
    */
@@ -1231,7 +1233,7 @@ recv_error:
  * gnutls_record_send:
  * @session: is a #gnutls_session_t structure.
  * @data: contains the data to send
- * @sizeofdata: is the length of the data
+ * @data_size: is the length of the data
  *
  * This function has the similar semantics with send().  The only
  * difference is that it accepts a GnuTLS session, and uses different
@@ -1251,16 +1253,16 @@ recv_error:
  * size. cf. gnutls_record_get_direction().
  *
  * Returns: the number of bytes sent, or a negative error code.  The
- *   number of bytes sent might be less than @sizeofdata.  The maximum
+ *   number of bytes sent might be less than @data_size.  The maximum
  *   number of bytes this function can send in a single call depends
  *   on the negotiated maximum record size.
   **/
 ssize_t
 gnutls_record_send (gnutls_session_t session, const void *data,
-                    size_t sizeofdata)
+                    size_t data_size)
 {
   return _gnutls_send_int (session, GNUTLS_APPLICATION_DATA, -1,
-                           EPOCH_WRITE_CURRENT, data, sizeofdata,
+                           EPOCH_WRITE_CURRENT, data, data_size,
                            MBUFFER_FLUSH);
 }
 
@@ -1268,7 +1270,7 @@ gnutls_record_send (gnutls_session_t session, const void *data,
  * gnutls_record_recv:
  * @session: is a #gnutls_session_t structure.
  * @data: the buffer that the data will be read into
- * @sizeofdata: the number of requested bytes
+ * @data_size: the number of requested bytes
  *
  * This function has the similar semantics with recv().  The only
  * difference is that it accepts a GnuTLS session, and uses different
@@ -1292,11 +1294,34 @@ gnutls_record_send (gnutls_session_t session, const void *data,
  *
  * Returns: the number of bytes received and zero on EOF.  A negative
  *   error code is returned in case of an error.  The number of bytes
- *   received might be less than @sizeofdata.
+ *   received might be less than @data_size.
+ **/
+ssize_t
+gnutls_record_recv (gnutls_session_t session, void *data, size_t data_size)
+{
+  return _gnutls_recv_int (session, GNUTLS_APPLICATION_DATA, -1, data,
+                           data_size, NULL);
+}
+
+/**
+ * gnutls_record_recv_seq:
+ * @session: is a #gnutls_session_t structure.
+ * @data: the buffer that the data will be read into
+ * @data_size: the number of requested bytes
+ * @seq: is the packet's 64-bit sequence number.
+ *
+ * This function is the same as gnutls_record_recv(), except that
+ * it returns in addition to data, the sequence number of the data.
+ * This is useful in DTLS.
+ *
+ * Returns: the number of bytes received and zero on EOF.  A negative
+ *   error code is returned in case of an error.  The number of bytes
+ *   received might be less than @data_size.
  **/
 ssize_t
-gnutls_record_recv (gnutls_session_t session, void *data, size_t sizeofdata)
+gnutls_record_recv_seq (gnutls_session_t session, void *data, size_t data_size,
+  unsigned char seq[8])
 {
   return _gnutls_recv_int (session, GNUTLS_APPLICATION_DATA, -1, data,
-                           sizeofdata);
+                           data_size, seq);
 }
index b24b390c501bd0248876fbbb38f77b0f31f151d8..f41347170487c3328c16f7147a24d41932aaf614 100644 (file)
@@ -35,6 +35,6 @@ ssize_t _gnutls_send_int (gnutls_session_t session, content_type_t type,
                           size_t sizeofdata, unsigned int mflags);
 ssize_t _gnutls_recv_int (gnutls_session_t session, content_type_t type,
                           gnutls_handshake_description_t, opaque * data,
-                          size_t sizeofdata);
+                          size_t sizeofdata, void* seq);
 
 #endif
index ebe09bd63f15b97a7ef0230a6520d04fb31b6052..d3e9d877af534407853ce0356ef1933fde55ea47 100644 (file)
@@ -787,6 +787,8 @@ extern "C"
                               size_t sizeofdata);
 #define gnutls_read gnutls_record_recv
 #define gnutls_write gnutls_record_send
+  ssize_t gnutls_record_recv_seq (gnutls_session_t session, void *data, size_t data_size,
+    unsigned char seq[8]);
 
   void gnutls_session_enable_compatibility_mode (gnutls_session_t session);
 
index 90ba4b54954a352dc416235bcdc59b01b437a670..978a2a5c81867626fbb62f963eb3bed8e5fc76d7 100644 (file)
@@ -703,6 +703,7 @@ GNUTLS_3_0_0 {
        gnutls_transport_set_pull_timeout_function;
        gnutls_dtls_get_mtu;
        gnutls_dtls_set_mtu;
+        gnutls_record_recv_seq;
 } GNUTLS_2_12;
 
 GNUTLS_PRIVATE {
index 284348325b76ffea146d0786cda255808b443d65..a5ba6e4d88cb0368c3d1f464b964f0d24b2f0caa 100644 (file)
@@ -29,6 +29,7 @@ int udp_server(const char* name, int port)
     char buffer[MAX_BUFFER];
     priv_data_st priv;
     gnutls_session_t session;
+    unsigned char sequence[8];
 
     ret = listen_socket (name, port, SOCK_DGRAM);
     if (ret < 0)
@@ -77,7 +78,10 @@ int udp_server(const char* name, int port)
 
         for(;;)
           {
-            ret = gnutls_record_recv(session, buffer, MAX_BUFFER);
+            do {
+              ret = gnutls_record_recv_seq(session, buffer, MAX_BUFFER, sequence);
+            } while(ret == GNUTLS_E_AGAIN || ret == GNUTLS_E_INTERRUPTED);
+
             if (ret < 0)
               {
                 fprintf(stderr, "Error in recv(): %s\n", gnutls_strerror(ret));
@@ -89,7 +93,8 @@ int udp_server(const char* name, int port)
                 break;
               }
             buffer[ret] = 0;
-            printf("received[%d]: %s\n", ret, buffer);
+            printf("received[%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x]: %s\n", sequence[0], sequence[1], sequence[2],
+              sequence[3], sequence[4], sequence[5], sequence[6], sequence[7], buffer);
 
             /* reply back */
             ret = gnutls_record_send(session, buffer, ret);