gnutls-commit
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[SCM] GNU gnutls branch, master, updated. gnutls_2_11_6-361-ga736f12


From: Nikos Mavrogiannopoulos
Subject: [SCM] GNU gnutls branch, master, updated. gnutls_2_11_6-361-ga736f12
Date: Sun, 03 Apr 2011 21:42:54 +0000

This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "GNU gnutls".

http://git.savannah.gnu.org/cgit/gnutls.git/commit/?id=a736f12ec8ae65636c87bee1df779f2d8c628da9

The branch, master has been updated
       via  a736f12ec8ae65636c87bee1df779f2d8c628da9 (commit)
       via  52b816623848d54934b7d4c8795ec6be1eaf618e (commit)
      from  2e097f644f3fd5d8db757834118c14bf5aec03b7 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit a736f12ec8ae65636c87bee1df779f2d8c628da9
Author: Nikos Mavrogiannopoulos <address@hidden>
Date:   Sun Apr 3 23:42:13 2011 +0200

    Added support for non-blocking DTLS.
    Added mini-eagain-dtls to test its operation.
    Improved mini-eagain.

commit 52b816623848d54934b7d4c8795ec6be1eaf618e
Author: Nikos Mavrogiannopoulos <address@hidden>
Date:   Sun Apr 3 22:27:12 2011 +0200

    gcrypt.h is not really needed. Reported by David Reiser.

-----------------------------------------------------------------------

Summary of changes:
 .gitignore                                  |    3 +
 lib/gnutls_buffers.c                        |   31 ++++--
 lib/gnutls_dtls.c                           |  107 ++++++++++++++---
 lib/gnutls_int.h                            |   20 +++-
 lib/gnutls_state.c                          |    8 ++
 lib/includes/gnutls/gnutls.h.in             |    2 +
 lib/nettle/init.c                           |    1 -
 lib/system.h                                |   17 +++-
 tests/Makefile.am                           |    4 +-
 tests/eagain-common.h                       |  144 ++++++++++++++++++++++
 tests/{mini-eagain.c => mini-eagain-dtls.c} |  177 +++++++--------------------
 tests/mini-eagain.c                         |  169 ++++++-------------------
 tests/utils.c                               |    2 +-
 13 files changed, 391 insertions(+), 294 deletions(-)
 create mode 100644 tests/eagain-common.h
 copy tests/{mini-eagain.c => mini-eagain-dtls.c} (60%)

diff --git a/.gitignore b/.gitignore
index d286453..4b94e31 100644
--- a/.gitignore
+++ b/.gitignore
@@ -412,6 +412,8 @@ src/psktool
 src/srptool
 stamp-h1
 tags
+tests/rng-fork
+tests/mini-eagain-dtls
 tests/*/out
 tests/Makefile
 tests/Makefile.in
@@ -446,6 +448,7 @@ tests/mpi
 tests/netconf-psk
 tests/nul-in-x509-names
 tests/openpgp-auth
+tests/openpgp-auth2
 tests/openpgp-certs/Makefile
 tests/openpgp-certs/Makefile.in
 tests/openpgp-keyring
diff --git a/lib/gnutls_buffers.c b/lib/gnutls_buffers.c
index 778af8d..39657a0 100644
--- a/lib/gnutls_buffers.c
+++ b/lib/gnutls_buffers.c
@@ -54,6 +54,7 @@
 #include <system.h>
 #include <gnutls_constate.h> /* gnutls_epoch_get */
 #include <errno.h>
+#include <system.h>
 
 #ifndef EAGAIN
 #define EAGAIN EWOULDBLOCK
@@ -61,7 +62,7 @@
 
 /* this is the maximum number of messages allowed to queue.
  */
-#define MAX_QUEUE 16
+#define MAX_QUEUE 32
 
 /* Buffers received packets of type APPLICATION DATA and
  * HANDSHAKE DATA.
@@ -553,7 +554,7 @@ _gnutls_io_write_flush (gnutls_session_t session)
       tosend += msg.size;
 
       /* we buffer up to MAX_QUEUE messages */
-      if (i >= sizeof (iovec) / sizeof (iovec[0]))
+      if (i >= MAX_QUEUE)
         {
           gnutls_assert ();
           return GNUTLS_E_INTERNAL_ERROR;
@@ -676,7 +677,6 @@ _gnutls_handshake_io_write_flush (gnutls_session_t session)
     }
 
   return _gnutls_io_write_flush (session);
-
 }
 
 
@@ -914,7 +914,7 @@ handshake_buffer_st* recv_buf = 
session->internals.handshake_recv_buffer;
     {
       if (session->internals.handshake_recv_buffer_size == 0 ||
         (session->internals.dtls.hsk_read_seq != 
recv_buf[LAST_ELEMENT].sequence))
-        return gnutls_assert_val(GNUTLS_E_AGAIN);
+        goto timeout;
 
       if (htype != recv_buf[LAST_ELEMENT].htype)
         {
@@ -932,7 +932,7 @@ handshake_buffer_st* recv_buf = 
session->internals.handshake_recv_buffer;
           return 0;
         }
       else
-        return gnutls_assert_val(GNUTLS_E_AGAIN);
+        goto timeout;
     }
   else /* TLS */
     {
@@ -949,7 +949,18 @@ handshake_buffer_st* recv_buf = 
session->internals.handshake_recv_buffer;
           return 0;
         }
       else
-        return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
+        return gnutls_assert_val(GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE);
+    }
+
+timeout:
+  if (time(0)-session->internals.dtls.handshake_start_time > 
session->internals.dtls.total_timeout/1000) 
+    return gnutls_assert_val(GNUTLS_E_TIMEDOUT);
+  else
+    {
+      if (session->internals.dtls.blocking != 0)
+        millisleep(50);
+        
+      return gnutls_assert_val(GNUTLS_E_AGAIN);
     }
 }
 
@@ -1108,7 +1119,7 @@ next:
       while(session->internals.handshake_recv_buffer_size > 0 &&
         recv_buf[LAST_ELEMENT].sequence < session->internals.dtls.hsk_read_seq)
         {
-          _gnutls_audit_log("Discarded replayed handshake packet with sequence 
%d\n", tmp.sequence);
+          _gnutls_audit_log("Discarded replayed handshake packet with sequence 
%d\n", recv_buf[LAST_ELEMENT].sequence);
           _gnutls_handshake_buffer_clear(&recv_buf[LAST_ELEMENT]);
           session->internals.handshake_recv_buffer_size--;
         }
@@ -1128,8 +1139,10 @@ _gnutls_handshake_io_recv_int (gnutls_session_t session,
   int ret;
 
   ret = get_last_packet(session, htype, hsk);
-  if (ret >= 0)
-    return ret;
+  if (ret != GNUTLS_E_AGAIN && ret != GNUTLS_E_INTERRUPTED && ret != 
GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
+    {
+      return gnutls_assert_val(ret);
+    }
 
   /* try using the already existing records before
    * trying to receive.
diff --git a/lib/gnutls_dtls.c b/lib/gnutls_dtls.c
index 076be8c..89dc066 100644
--- a/lib/gnutls_dtls.c
+++ b/lib/gnutls_dtls.c
@@ -1,7 +1,8 @@
 /*
- * Copyright (C) 2009 Free Software Foundation (copyright assignement pending)
+ * Copyright (C) 2009,2011 Free Software Foundation
  *
- * Author: Jonathan Bastien-Filiatrault
+ * Authors: Jonathan Bastien-Filiatrault
+ *          Nikos Mavrogiannopoulos
  *
  * This file is part of GNUTLS.
  *
@@ -155,6 +156,10 @@ time_t now = time(0);
 
 }
 
+#define UPDATE_TIMER \
+      session->internals.dtls.actual_retrans_timeout *= 2; \
+      session->internals.dtls.actual_retrans_timeout %= MAX_DTLS_TIMEOUT
+
 /* This function transmits the flight that has been previously
  * buffered.
  *
@@ -170,13 +175,52 @@ int ret;
   mbuffer_head_st *const send_buffer =
     &session->internals.handshake_send_buffer;
   mbuffer_st *cur;
-  unsigned int total_timeout = 0;
-  unsigned int timeout = session->internals.dtls.retrans_timeout;
   gnutls_handshake_description_t last_type = 0;
+  time_t now = time(0);
+
+  /* If we have already sent a flight and we are operating in a 
+   * non blocking way, check if it is time to retransmit or just
+   * return.
+   */
+  if (session->internals.dtls.flight_init != 0 && 
session->internals.dtls.blocking == 0)
+    {
+      /* just in case previous run was interrupted */
+      ret = _gnutls_io_write_flush (session);
+
+      if (session->internals.dtls.last_flight == 0)
+        {
+          /* check for ACK */
+          ret = _gnutls_io_check_recv(session, 0);
+          if (ret == GNUTLS_E_TIMEDOUT)
+            {
+              /* if no retransmission is required yet just return 
+               */
+              if (now-session->internals.dtls.handshake_start_time < 
session->internals.dtls.actual_retrans_timeout)
+                {
+                  session->internals.dtls.handshake_last_call = now;
+                  goto nb_timeout;
+                }
+            }
+          else /* received ack */
+            {
+              ret = 0;
+              goto cleanup;
+            }
+        }
+      else
+        return ret;
+    }
+
 
   do 
     {
-      _gnutls_dtls_log ("DTLS[%p]: Start of flight transmission.\n", session);
+      if (now-session->internals.dtls.handshake_start_time >= 
session->internals.dtls.total_timeout/1000) 
+        {
+          ret = gnutls_assert_val(GNUTLS_E_TIMEDOUT);
+          goto cleanup;
+        }
+
+      _gnutls_dtls_log ("DTLS[%p]: %sstart of flight transmission.\n", 
session,  (session->internals.dtls.flight_init == 0)?"":"re-");
 
       for (cur = send_buffer->head;
            cur != NULL; cur = cur->next)
@@ -185,12 +229,32 @@ int ret;
           last_type = cur->htype;
         }
 
+      if (session->internals.dtls.flight_init == 0)
+        {
+          session->internals.dtls.flight_init = 1;
+          session->internals.dtls.handshake_last_call = now;
+          session->internals.dtls.actual_retrans_timeout = 
session->internals.dtls.retrans_timeout;
+
+          if (last_type == GNUTLS_HANDSHAKE_FINISHED && 
_dtls_is_async(session))
+            {
+              /* we cannot do anything here. We just return 0 and
+               * if a retransmission occurs because peer didn't receive it
+               * we rely on the record layer calling this function again.
+               */
+              session->internals.dtls.last_flight = 1;
+            }
+          else
+            session->internals.dtls.last_flight = 0;
+
+
+        }
+
       ret = _gnutls_io_write_flush (session);
       if (ret < 0)
         return gnutls_assert_val(ret);
 
       /* last message in handshake -> no ack */
-      if (last_type == GNUTLS_HANDSHAKE_FINISHED && _dtls_is_async(session))
+      if (session->internals.dtls.last_flight != 0)
         {
           /* we cannot do anything here. We just return 0 and
            * if a retransmission occurs because peer didn't receive it
@@ -200,17 +264,21 @@ int ret;
         }
       else /* all other messages -> implicit ack (receive of next flight) */
         {
-          ret = _gnutls_io_check_recv(session, timeout);
+          if (session->internals.dtls.blocking != 0)
+            ret = _gnutls_io_check_recv(session, 
session->internals.dtls.actual_retrans_timeout);
+          else
+            {
+              ret = _gnutls_io_check_recv(session, 0);
+              if (ret == GNUTLS_E_TIMEDOUT)
+                {
+                  UPDATE_TIMER;
+                  goto nb_timeout;
+                }
+            }
         }
 
-      total_timeout += timeout;
-      timeout *= 2;
-      timeout %= MAX_DTLS_TIMEOUT;
-
-      if (total_timeout >= session->internals.dtls.total_timeout) {
-        ret = gnutls_assert_val(GNUTLS_E_TIMEDOUT);
-        goto cleanup;
-      }
+      UPDATE_TIMER;
+      now = time(0);
     } while(ret == GNUTLS_E_TIMEDOUT);
 
   if (ret < 0)
@@ -219,15 +287,20 @@ int ret;
       goto cleanup;
     }
 
-  _gnutls_dtls_log ("DTLS[%p]: End of flight transmission.\n", session);
   ret = 0;
 
 cleanup:
+  _gnutls_dtls_log ("DTLS[%p]: End of flight transmission.\n", session);
+
+  session->internals.dtls.flight_init = 0;
   drop_usage_count(session, send_buffer);
   _mbuffer_head_clear(send_buffer);
 
   /* SENDING -> WAITING state transition */
   return ret;
+
+nb_timeout:
+    return GNUTLS_E_AGAIN;
 }
 
 #define window_table session->internals.dtls.record_sw
@@ -352,7 +425,7 @@ int i, offset = 0;
 void gnutls_dtls_set_timeouts (gnutls_session_t session, unsigned int 
retrans_timeout,
   unsigned int total_timeout)
 {
-  session->internals.dtls.retrans_timeout  = retrans_timeout;
+  session->internals.dtls.retrans_timeout = retrans_timeout;
   session->internals.dtls.total_timeout  = total_timeout;
 }
 
diff --git a/lib/gnutls_int.h b/lib/gnutls_int.h
index c44b9ca..b11df42 100644
--- a/lib/gnutls_int.h
+++ b/lib/gnutls_int.h
@@ -581,17 +581,30 @@ typedef struct
 
   /* For DTLS handshake fragmentation and reassembly. */
   uint16_t hsk_write_seq;
-  int hsk_read_seq;
+  unsigned int hsk_read_seq;
   uint16_t mtu;
 
+  /* a flight transmission is in process */
+  unsigned int flight_init:1;
+  /* whether this is the last flight in the protocol  */
+  unsigned int last_flight:1;
   unsigned int retrans_timeout;
   unsigned int total_timeout;
 
   unsigned int hsk_hello_verify_requests;
   
   uint64_t record_sw[DTLS_RECORD_WINDOW_SIZE];
-  int record_sw_size;
-  
+  unsigned int record_sw_size;
+
+  /* non blocking stuff variables */
+  unsigned int blocking:1;
+  /* starting time of current handshake */
+  time_t handshake_start_time;
+  /* time in seconds of the last handshake call */
+  time_t handshake_last_call;
+  /* The actual retrans_timeout for the next message (e.g. doubled or so) */
+  unsigned int actual_retrans_timeout;
+
   /* timers to handle async handshake after gnutls_handshake()
    * has terminated. Required to handle retransmissions.
    */
@@ -850,7 +863,6 @@ struct gnutls_session_int
 };
 
 
-
 /* functions 
  */
 void _gnutls_set_current_version (gnutls_session_t session,
diff --git a/lib/gnutls_state.c b/lib/gnutls_state.c
index b268971..f14927d 100644
--- a/lib/gnutls_state.c
+++ b/lib/gnutls_state.c
@@ -258,6 +258,7 @@ _gnutls_handshake_internal_state_init (gnutls_session_t 
session)
   
   session->internals.dtls.hsk_read_seq = 0;
   session->internals.dtls.hsk_write_seq = 0;
+  session->internals.dtls.handshake_start_time = time(0);
 }
 
 void
@@ -380,6 +381,13 @@ gnutls_init (gnutls_session_t * session, unsigned int 
flags)
 
       (*session)->internals.dtls.record_sw_size = 0;
     }
+  else
+    (*session)->internals.transport = GNUTLS_STREAM;
+  
+  if (flags & GNUTLS_NONBLOCK)
+    (*session)->internals.dtls.blocking = 0;
+  else
+    (*session)->internals.dtls.blocking = 1;
 
   return 0;
 }
diff --git a/lib/includes/gnutls/gnutls.h.in b/lib/includes/gnutls/gnutls.h.in
index 674ca60..8210021 100644
--- a/lib/includes/gnutls/gnutls.h.in
+++ b/lib/includes/gnutls/gnutls.h.in
@@ -284,12 +284,14 @@ extern "C"
    * @GNUTLS_SERVER: Connection end is a server.
    * @GNUTLS_CLIENT: Connection end is a client.
    * @GNUTLS_DATAGRAM: Connection is datagram oriented (DTLS).
+   * @GNUTLS_NONBLOCK: Connection should not block (DTLS).
    *
    * Enumeration of different TLS connection end types.
    */
 #define GNUTLS_SERVER 1
 #define GNUTLS_CLIENT (1<<1)
 #define GNUTLS_DATAGRAM (1<<2)
+#define GNUTLS_NONBLOCK (1<<3)
 
   /**
    * gnutls_alert_level_t:
diff --git a/lib/nettle/init.c b/lib/nettle/init.c
index 446083c..14c3715 100644
--- a/lib/nettle/init.c
+++ b/lib/nettle/init.c
@@ -26,7 +26,6 @@
 #include <gnutls_errors.h>
 #include <gnutls_num.h>
 #include <gnutls_mpi.h>
-#include <gcrypt.h>
 
 /* Functions that refer to the initialization of the libgcrypt library.
  */
diff --git a/lib/system.h b/lib/system.h
index b1f5565..849090e 100644
--- a/lib/system.h
+++ b/lib/system.h
@@ -4,7 +4,9 @@
 #include <gnutls_int.h>
 
 #ifndef _WIN32
-#include <sys/uio.h>            /* for writev */
+# include <sys/uio.h>            /* for writev */
+#else
+# include <windows.h>            /* for Sleep */
 #endif
 
 int system_errno (gnutls_transport_ptr_t);
@@ -35,4 +37,17 @@ ssize_t system_read_peek (gnutls_transport_ptr_t ptr, void 
*data,
 int _gnutls_atfork (void (*prepare) (void), void (*parent) (void),
                     void (*child) (void));
 
+static inline void millisleep(unsigned int ms)
+{
+#ifdef _WIN32
+  Sleep(ms);
+#else
+struct timespec ts;
+  ts.tv_sec = 0;
+  ts.tv_nsec = ms*1000*1000;
+  
+  nanosleep(&ts, NULL);
+#endif
+}
+
 #endif /* SYSTEM_H */
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 2d5e2d4..cef6bd6 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -27,7 +27,7 @@ if ENABLE_OPENPGP
 SUBDIRS += openpgp-certs
 endif
 
-EXTRA_DIST = libgcrypt.supp
+EXTRA_DIST = libgcrypt.supp eagain-common.h
 
 AM_CFLAGS = $(WARN_CFLAGS) $(WERROR_CFLAGS)
 AM_CPPFLAGS = \
@@ -60,7 +60,7 @@ ctests = simple gc set_pkcs12_cred certder certuniqueid mpi   
                \
        crq_key_id x509sign-verify cve-2009-1415 cve-2009-1416          \
        crq_apis init_roundtrip pkcs12_s2k_pem dn2 mini-eagain          \
        nul-in-x509-names x509_altname pkcs12_encode mini-x509          \
-       mini-x509-rehandshake rng-fork #gendh
+       mini-x509-rehandshake rng-fork mini-eagain-dtls #gendh
 
 if ENABLE_OPENSSL
 ctests +=  openssl
diff --git a/tests/eagain-common.h b/tests/eagain-common.h
new file mode 100644
index 0000000..5fb436e
--- /dev/null
+++ b/tests/eagain-common.h
@@ -0,0 +1,144 @@
+#define min(x,y) ((x)<(y)?(x):(y))
+//#define EAGAIN_DEBUG
+#define RANDOMIZE
+
+static char to_server[64*1024];
+static size_t to_server_len = 0;
+
+static char to_client[64*1024];
+static size_t to_client_len = 0;
+
+#ifdef RANDOMIZE
+#define RETURN_RND_EAGAIN() \
+  static unsigned char rnd = 0; \
+  if (rnd++ % 2 == 0) \
+    { \
+      gnutls_transport_set_global_errno (EAGAIN); \
+      return -1; \
+    }
+#else
+#define RETURN_RND_EAGAIN()
+#endif
+
+static ssize_t
+client_push (gnutls_transport_ptr_t tr, const void *data, size_t len)
+{
+  size_t newlen;
+  RETURN_RND_EAGAIN();
+
+  len = min(len, sizeof(to_server)-to_server_len);
+
+  newlen = to_server_len + len;
+  memcpy (to_server + to_server_len, data, len);
+  to_server_len = newlen;
+#ifdef EAGAIN_DEBUG
+  fprintf(stderr, "eagain: pushed %d bytes to server (avail: %d)\n", (int)len, 
(int)to_server_len);
+#endif
+  return len;
+}
+
+static ssize_t
+client_pull (gnutls_transport_ptr_t tr, void *data, size_t len)
+{
+  RETURN_RND_EAGAIN();
+
+  if (to_client_len == 0)
+    {
+#ifdef EAGAIN_DEBUG
+      fprintf(stderr, "eagain: Not enough data by server (asked for: %d, have: 
%d)\n", (int)len, (int)to_client_len);
+#endif
+      gnutls_transport_set_global_errno (EAGAIN);
+      return -1;
+    }
+
+  len = min(len, to_client_len);
+
+  memcpy (data, to_client, len);
+
+  memmove (to_client, to_client + len, to_client_len - len);
+  to_client_len -= len;
+#ifdef EAGAIN_DEBUG
+  fprintf(stderr, "eagain: pulled %d bytes by client (avail: %d)\n", (int)len, 
(int)to_client_len);
+#endif
+  return len;
+}
+
+static ssize_t
+server_pull (gnutls_transport_ptr_t tr, void *data, size_t len)
+{
+  //success ("server_pull len %d has %d\n", len, to_server_len);
+  RETURN_RND_EAGAIN();
+
+  if (to_server_len == 0)
+    {
+#ifdef EAGAIN_DEBUG
+      fprintf(stderr, "eagain: Not enough data by client (asked for: %d, have: 
%d)\n", (int)len, (int)to_server_len);
+#endif
+      gnutls_transport_set_global_errno (EAGAIN);
+      return -1;
+    }
+
+  len = min(len, to_server_len);
+#ifdef EAGAIN_DEBUG
+  fprintf(stderr, "eagain: pulled %d bytes by server (avail: %d)\n", (int)len, 
(int)to_server_len);
+#endif
+  memcpy (data, to_server, len);
+
+  memmove (to_server, to_server + len, to_server_len - len);
+  to_server_len -= len;
+
+  return len;
+}
+
+static ssize_t
+server_push (gnutls_transport_ptr_t tr, const void *data, size_t len)
+{
+  size_t newlen;
+  RETURN_RND_EAGAIN();
+
+//  hexprint (data, len);
+
+  len = min(len, sizeof(to_client)-to_client_len);
+
+  newlen = to_client_len + len;
+  memcpy (to_client + to_client_len, data, len);
+  to_client_len = newlen;
+#ifdef EAGAIN_DEBUG
+  fprintf(stderr, "eagain: pushed %d bytes to client (avail: %d)\n", (int)len, 
(int)to_client_len);
+#endif
+
+  return len;
+}
+
+/* inline is used to avoid a gcc warning if used in mini-eagain */
+inline static int server_pull_timeout_func(gnutls_transport_ptr_t ptr, 
unsigned int ms)
+{
+int ret;
+
+  if (to_server_len > 0)
+    ret = 1; /* available data */
+  else
+    ret = 0; /* timeout */
+
+#ifdef EAGAIN_DEBUG
+  fprintf(stderr, "eagain: server_pull_timeout: %d\n", ret);
+#endif
+
+  return ret;
+}
+
+inline static int client_pull_timeout_func(gnutls_transport_ptr_t ptr, 
unsigned int ms)
+{
+int ret;
+
+  if (to_client_len > 0)
+    ret = 1;
+  else
+    ret = 0;
+
+#ifdef EAGAIN_DEBUG
+  fprintf(stderr, "eagain: client_pull_timeout: %d\n", ret);
+#endif
+
+  return ret;
+}
diff --git a/tests/mini-eagain.c b/tests/mini-eagain-dtls.c
similarity index 60%
copy from tests/mini-eagain.c
copy to tests/mini-eagain-dtls.c
index 9bb7e2c..0b3ed47 100644
--- a/tests/mini-eagain.c
+++ b/tests/mini-eagain-dtls.c
@@ -30,8 +30,8 @@
 #include <errno.h>
 #include <gnutls/gnutls.h>
 #include <gnutls/crypto.h>
-
 #include "utils.h"
+#include "eagain-common.h"
 
 static void
 tls_log_func (int level, const char *str)
@@ -41,109 +41,6 @@ tls_log_func (int level, const char *str)
 
 static int handshake = 0;
 
-char *to_server;
-size_t to_server_len;
-
-char *to_client;
-size_t to_client_len;
-
-
-static ssize_t
-client_pull (gnutls_transport_ptr_t tr, void *data, size_t len)
-{
-//  success ("client_pull len %d has %d\n", len, to_client_len);
-  static unsigned char rnd = 0;
-
-  if (rnd++ % 2 == 0 || to_client_len < len)
-    {
-      gnutls_transport_set_global_errno (EAGAIN);
-      return -1;
-    }
-
-  memcpy (data, to_client, len);
-
-  memmove (to_client, to_client + len, to_client_len - len);
-  to_client_len -= len;
-
-  return len;
-}
-
-static ssize_t
-client_push (gnutls_transport_ptr_t tr, const void *data, size_t len)
-{
-  char *tmp;
-  size_t newlen = to_server_len + len;
-  static unsigned char rnd = 0;
-
-  if (rnd++ % 2 == 0)
-    {
-      gnutls_transport_set_global_errno (EAGAIN);
-      return -1;
-    }
-
-  tmp = realloc (to_server, newlen);
-  if (!tmp)
-    {
-      fail ("Memory allocation failure...\n");
-      exit (1);
-    }
-  to_server = tmp;
-
-  memcpy (to_server + to_server_len, data, len);
-  to_server_len = newlen;
-
-  return len;
-}
-
-static ssize_t
-server_pull (gnutls_transport_ptr_t tr, void *data, size_t len)
-{
-  //success ("server_pull len %d has %d\n", len, to_server_len);
-  static unsigned char rnd = 0;
-
-  if (rnd++ % 2 == 0 || to_server_len < len)
-    {
-      gnutls_transport_set_global_errno (EAGAIN);
-      return -1;
-    }
-
-  memcpy (data, to_server, len);
-
-  memmove (to_server, to_server + len, to_server_len - len);
-  to_server_len -= len;
-
-  return len;
-}
-
-static ssize_t
-server_push (gnutls_transport_ptr_t tr, const void *data, size_t len)
-{
-  char *tmp;
-  size_t newlen = to_client_len + len;
-  static unsigned char rnd = 0;
-
-  if (rnd++ % 2 == 0)
-    {
-      gnutls_transport_set_global_errno (EAGAIN);
-      return -1;
-    }
-
-//  hexprint (data, len);
-
-  tmp = realloc (to_client, newlen);
-  if (!tmp)
-    {
-      fail ("Memory allocation failure...\n");
-      exit (1);
-    }
-  to_client = tmp;
-
-  memcpy (to_client + to_client_len, data, len);
-  to_client_len = newlen;
-
-  return len;
-}
-
 #define MAX_BUF 1024
 #define MSG "Hello TLS, and hi and how are you and more data here... and 
more... and even more and even more more data..."
 
@@ -155,11 +52,10 @@ doit (void)
   const gnutls_datum_t p3 = { (char *) pkcs3, strlen (pkcs3) };
   static gnutls_dh_params_t dh_params;
   gnutls_session_t server;
-  int sret = GNUTLS_E_AGAIN;
+  int sret, cret;
   /* Client stuff. */
   gnutls_anon_client_credentials_t c_anoncred;
   gnutls_session_t client;
-  int cret = GNUTLS_E_AGAIN;
   /* Need to enable anonymous KX specifically. */
   char buffer[MAX_BUF + 1];
   ssize_t ns;
@@ -176,22 +72,29 @@ doit (void)
   gnutls_dh_params_init (&dh_params);
   gnutls_dh_params_import_pkcs3 (dh_params, &p3, GNUTLS_X509_FMT_PEM);
   gnutls_anon_set_server_dh_params (s_anoncred, dh_params);
-  gnutls_init (&server, GNUTLS_SERVER);
-  gnutls_priority_set_direct (server, 
"NONE:+VERS-TLS-ALL:+CIPHER-ALL:+MAC-ALL:+SIGN-ALL:+COMP-ALL:+ANON-DH", NULL);
+  gnutls_init (&server, GNUTLS_SERVER|GNUTLS_DATAGRAM|GNUTLS_NONBLOCK);
+  ret = gnutls_priority_set_direct (server, 
"NONE:+VERS-DTLS1.0:+CIPHER-ALL:+MAC-ALL:+SIGN-ALL:+COMP-ALL:+ANON-DH", NULL);
+  if (ret < 0)
+    exit(1);
   gnutls_credentials_set (server, GNUTLS_CRD_ANON, s_anoncred);
   gnutls_dh_set_prime_bits (server, 1024);
   gnutls_transport_set_push_function (server, server_push);
   gnutls_transport_set_pull_function (server, server_pull);
+  gnutls_transport_set_pull_timeout_function (server, 
server_pull_timeout_func);
 
   /* Init client */
   gnutls_anon_allocate_client_credentials (&c_anoncred);
-  gnutls_init (&client, GNUTLS_CLIENT);
-  gnutls_priority_set_direct (client, 
"NONE:+VERS-TLS-ALL:+CIPHER-ALL:+MAC-ALL:+SIGN-ALL:+COMP-ALL:+ANON-DH", NULL);
+  gnutls_init (&client, GNUTLS_CLIENT|GNUTLS_DATAGRAM|GNUTLS_NONBLOCK);
+  cret = gnutls_priority_set_direct (client, 
"NONE:+VERS-DTLS1.0:+CIPHER-ALL:+MAC-ALL:+SIGN-ALL:+COMP-ALL:+ANON-DH", NULL);
+  if (cret < 0)
+    exit(1);
   gnutls_credentials_set (client, GNUTLS_CRD_ANON, c_anoncred);
   gnutls_transport_set_push_function (client, client_push);
   gnutls_transport_set_pull_function (client, client_pull);
+  gnutls_transport_set_pull_timeout_function (client, 
client_pull_timeout_func);
 
   handshake = 1;
+  sret = cret = GNUTLS_E_AGAIN;
   do
     {
       if (cret == GNUTLS_E_AGAIN)
@@ -208,37 +111,50 @@ doit (void)
           //success ("server %d: %s\n", sret, gnutls_strerror (sret));
         }
     }
-  while (cret == GNUTLS_E_AGAIN || sret == GNUTLS_E_AGAIN);
+  while ((cret == GNUTLS_E_AGAIN && gnutls_error_is_fatal(sret)==0) || (sret 
== GNUTLS_E_AGAIN && gnutls_error_is_fatal(cret)==0));
+
+  if (cret < 0 || sret < 0)
+    {
+      fprintf(stderr, "client: %s\n", gnutls_strerror(cret));
+      fprintf(stderr, "server: %s\n", gnutls_strerror(sret));
+      fail("Handshake failed\n");
+      exit(1);
+    }
 
   handshake = 0;
   if (debug)
     success ("Handshake established\n");
 
-  ns = gnutls_record_send (client, MSG, strlen (MSG));
+  do
+    {
+      ret = gnutls_record_send (client, MSG, strlen (MSG));
+    }
+  while(ret == GNUTLS_E_AGAIN);
   //success ("client: sent %d\n", ns);
 
   do
     {
       //success("transferred: %d\n", transferred);
 
-      ret = gnutls_record_recv (server, buffer, MAX_BUF);
+      do
+        {
+          ret = gnutls_record_recv (server, buffer, MAX_BUF);
+        }
+      while(ret == GNUTLS_E_AGAIN);
+
       if (ret == 0)
         fail ("server: didn't receive any data\n");
       else if (ret < 0)
         {
-//      if (debug)
-//          fputs ("#", stdout);
-          if (ret != GNUTLS_E_AGAIN)
-            {
-              fail ("server: error: %s\n", gnutls_strerror (ret));
-              break;
-            }
+          //      if (debug)
+          //          fputs ("#", stdout);
+          fail ("server: error: %s\n", gnutls_strerror (ret));
         }
       else
         {
           transferred += ret;
-//        if (debug)
-//          fputs ("*", stdout);
+            //        if (debug)
+              //          fputs ("*", stdout);
         }
 
       msglen = strlen (MSG);
@@ -248,7 +164,13 @@ doit (void)
         }
       while (ns == GNUTLS_E_AGAIN);
 
-      ret = gnutls_record_recv (client, buffer, MAX_BUF);
+      do
+        {
+          ret = gnutls_record_recv (client, buffer, MAX_BUF);
+        }
+      while(ret == GNUTLS_E_AGAIN);
+
+
       if (ret == 0)
         {
           fail ("client: Peer has closed the TLS connection\n");
@@ -257,11 +179,7 @@ doit (void)
         {
           if (debug)
             fputs ("!", stdout);
-          if (ret != GNUTLS_E_AGAIN)
-            {
-              fail ("client: Error: %s\n", gnutls_strerror (ret));
-              break;
-            }
+          fail ("client: Error: %s\n", gnutls_strerror (ret));
         }
       else
         {
@@ -292,9 +210,6 @@ doit (void)
   gnutls_deinit (client);
   gnutls_deinit (server);
 
-  free (to_server);
-  free (to_client);
-
   gnutls_anon_free_client_credentials (c_anoncred);
   gnutls_anon_free_server_credentials (s_anoncred);
 
diff --git a/tests/mini-eagain.c b/tests/mini-eagain.c
index 9bb7e2c..3b2ea29 100644
--- a/tests/mini-eagain.c
+++ b/tests/mini-eagain.c
@@ -32,6 +32,7 @@
 #include <gnutls/crypto.h>
 
 #include "utils.h"
+#include "eagain-common.h"
 
 static void
 tls_log_func (int level, const char *str)
@@ -41,109 +42,6 @@ tls_log_func (int level, const char *str)
 
 static int handshake = 0;
 
-char *to_server;
-size_t to_server_len;
-
-char *to_client;
-size_t to_client_len;
-
-
-static ssize_t
-client_pull (gnutls_transport_ptr_t tr, void *data, size_t len)
-{
-//  success ("client_pull len %d has %d\n", len, to_client_len);
-  static unsigned char rnd = 0;
-
-  if (rnd++ % 2 == 0 || to_client_len < len)
-    {
-      gnutls_transport_set_global_errno (EAGAIN);
-      return -1;
-    }
-
-  memcpy (data, to_client, len);
-
-  memmove (to_client, to_client + len, to_client_len - len);
-  to_client_len -= len;
-
-  return len;
-}
-
-static ssize_t
-client_push (gnutls_transport_ptr_t tr, const void *data, size_t len)
-{
-  char *tmp;
-  size_t newlen = to_server_len + len;
-  static unsigned char rnd = 0;
-
-  if (rnd++ % 2 == 0)
-    {
-      gnutls_transport_set_global_errno (EAGAIN);
-      return -1;
-    }
-
-  tmp = realloc (to_server, newlen);
-  if (!tmp)
-    {
-      fail ("Memory allocation failure...\n");
-      exit (1);
-    }
-  to_server = tmp;
-
-  memcpy (to_server + to_server_len, data, len);
-  to_server_len = newlen;
-
-  return len;
-}
-
-static ssize_t
-server_pull (gnutls_transport_ptr_t tr, void *data, size_t len)
-{
-  //success ("server_pull len %d has %d\n", len, to_server_len);
-  static unsigned char rnd = 0;
-
-  if (rnd++ % 2 == 0 || to_server_len < len)
-    {
-      gnutls_transport_set_global_errno (EAGAIN);
-      return -1;
-    }
-
-  memcpy (data, to_server, len);
-
-  memmove (to_server, to_server + len, to_server_len - len);
-  to_server_len -= len;
-
-  return len;
-}
-
-static ssize_t
-server_push (gnutls_transport_ptr_t tr, const void *data, size_t len)
-{
-  char *tmp;
-  size_t newlen = to_client_len + len;
-  static unsigned char rnd = 0;
-
-  if (rnd++ % 2 == 0)
-    {
-      gnutls_transport_set_global_errno (EAGAIN);
-      return -1;
-    }
-
-//  hexprint (data, len);
-
-  tmp = realloc (to_client, newlen);
-  if (!tmp)
-    {
-      fail ("Memory allocation failure...\n");
-      exit (1);
-    }
-  to_client = tmp;
-
-  memcpy (to_client + to_client_len, data, len);
-  to_client_len = newlen;
-
-  return len;
-}
-
 #define MAX_BUF 1024
 #define MSG "Hello TLS, and hi and how are you and more data here... and 
more... and even more and even more more data..."
 
@@ -155,11 +53,10 @@ doit (void)
   const gnutls_datum_t p3 = { (char *) pkcs3, strlen (pkcs3) };
   static gnutls_dh_params_t dh_params;
   gnutls_session_t server;
-  int sret = GNUTLS_E_AGAIN;
+  int sret, cret;
   /* Client stuff. */
   gnutls_anon_client_credentials_t c_anoncred;
   gnutls_session_t client;
-  int cret = GNUTLS_E_AGAIN;
   /* Need to enable anonymous KX specifically. */
   char buffer[MAX_BUF + 1];
   ssize_t ns;
@@ -169,7 +66,7 @@ doit (void)
   gnutls_global_init ();
   gnutls_global_set_log_function (tls_log_func);
   if (debug)
-    gnutls_global_set_log_level (99);
+    gnutls_global_set_log_level (2);
 
   /* Init server */
   gnutls_anon_allocate_server_credentials (&s_anoncred);
@@ -177,7 +74,9 @@ doit (void)
   gnutls_dh_params_import_pkcs3 (dh_params, &p3, GNUTLS_X509_FMT_PEM);
   gnutls_anon_set_server_dh_params (s_anoncred, dh_params);
   gnutls_init (&server, GNUTLS_SERVER);
-  gnutls_priority_set_direct (server, 
"NONE:+VERS-TLS-ALL:+CIPHER-ALL:+MAC-ALL:+SIGN-ALL:+COMP-ALL:+ANON-DH", NULL);
+  ret = gnutls_priority_set_direct (server, 
"NONE:+VERS-TLS-ALL:+CIPHER-ALL:+MAC-ALL:+SIGN-ALL:+COMP-ALL:+ANON-DH", NULL);
+  if (ret < 0)
+    exit(1);
   gnutls_credentials_set (server, GNUTLS_CRD_ANON, s_anoncred);
   gnutls_dh_set_prime_bits (server, 1024);
   gnutls_transport_set_push_function (server, server_push);
@@ -186,12 +85,15 @@ doit (void)
   /* Init client */
   gnutls_anon_allocate_client_credentials (&c_anoncred);
   gnutls_init (&client, GNUTLS_CLIENT);
-  gnutls_priority_set_direct (client, 
"NONE:+VERS-TLS-ALL:+CIPHER-ALL:+MAC-ALL:+SIGN-ALL:+COMP-ALL:+ANON-DH", NULL);
+  ret = gnutls_priority_set_direct (client, 
"NONE:+VERS-TLS-ALL:+CIPHER-ALL:+MAC-ALL:+SIGN-ALL:+COMP-ALL:+ANON-DH", NULL);
+  if (ret < 0)
+    exit(1);
   gnutls_credentials_set (client, GNUTLS_CRD_ANON, c_anoncred);
   gnutls_transport_set_push_function (client, client_push);
   gnutls_transport_set_pull_function (client, client_pull);
 
   handshake = 1;
+  sret = cret = GNUTLS_E_AGAIN;
   do
     {
       if (cret == GNUTLS_E_AGAIN)
@@ -210,35 +112,48 @@ doit (void)
     }
   while (cret == GNUTLS_E_AGAIN || sret == GNUTLS_E_AGAIN);
 
+  if (cret < 0 || sret < 0)
+    {
+      fprintf(stderr, "client: %s\n", gnutls_strerror(cret));
+      fprintf(stderr, "server: %s\n", gnutls_strerror(sret));
+      fail("Handshake failed\n");
+      exit(1);
+    }
+
   handshake = 0;
   if (debug)
     success ("Handshake established\n");
 
-  ns = gnutls_record_send (client, MSG, strlen (MSG));
+  do
+    {
+      ret = gnutls_record_send (client, MSG, strlen (MSG));
+    }
+  while(ret == GNUTLS_E_AGAIN);
   //success ("client: sent %d\n", ns);
 
   do
     {
       //success("transferred: %d\n", transferred);
 
-      ret = gnutls_record_recv (server, buffer, MAX_BUF);
+      do
+        {
+          ret = gnutls_record_recv (server, buffer, MAX_BUF);
+        }
+      while(ret == GNUTLS_E_AGAIN);
+
       if (ret == 0)
         fail ("server: didn't receive any data\n");
       else if (ret < 0)
         {
-//      if (debug)
-//          fputs ("#", stdout);
-          if (ret != GNUTLS_E_AGAIN)
-            {
-              fail ("server: error: %s\n", gnutls_strerror (ret));
-              break;
-            }
+          //      if (debug)
+          //          fputs ("#", stdout);
+          fail ("server: error: %s\n", gnutls_strerror (ret));
         }
       else
         {
           transferred += ret;
-//        if (debug)
-//          fputs ("*", stdout);
+            //        if (debug)
+              //          fputs ("*", stdout);
         }
 
       msglen = strlen (MSG);
@@ -248,7 +163,12 @@ doit (void)
         }
       while (ns == GNUTLS_E_AGAIN);
 
-      ret = gnutls_record_recv (client, buffer, MAX_BUF);
+      do
+        {
+          ret = gnutls_record_recv (client, buffer, MAX_BUF);
+        }
+      while(ret == GNUTLS_E_AGAIN);
+
       if (ret == 0)
         {
           fail ("client: Peer has closed the TLS connection\n");
@@ -257,11 +177,7 @@ doit (void)
         {
           if (debug)
             fputs ("!", stdout);
-          if (ret != GNUTLS_E_AGAIN)
-            {
-              fail ("client: Error: %s\n", gnutls_strerror (ret));
-              break;
-            }
+          fail ("client: Error: %s\n", gnutls_strerror (ret));
         }
       else
         {
@@ -292,9 +208,6 @@ doit (void)
   gnutls_deinit (client);
   gnutls_deinit (server);
 
-  free (to_server);
-  free (to_client);
-
   gnutls_anon_free_client_credentials (c_anoncred);
   gnutls_anon_free_server_credentials (s_anoncred);
 
diff --git a/tests/utils.c b/tests/utils.c
index 105869c..c8ed853 100644
--- a/tests/utils.c
+++ b/tests/utils.c
@@ -60,7 +60,7 @@ success (const char *format, ...)
   va_list arg_ptr;
 
   va_start (arg_ptr, format);
-  vfprintf (stdout, format, arg_ptr);
+  vfprintf (stderr, format, arg_ptr);
   va_end (arg_ptr);
 }
 


hooks/post-receive
-- 
GNU gnutls



reply via email to

[Prev in Thread] Current Thread [Next in Thread]