Fixed memory leak due to incorrect freeing of DTLS reassembly bit mask
[openssl.git] / ssl / d1_lib.c
index d372a61bea3bbc07ce2135ba03d14d712b4801ab..a593c7859e772c83c9fb929136695aa6ee6334c8 100644 (file)
@@ -62,7 +62,7 @@
 #include <openssl/objects.h>
 #include "ssl_locl.h"
 
-#if defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_VMS)
+#if defined(OPENSSL_SYS_VMS)
 #include <sys/timeb.h>
 #endif
 
@@ -187,24 +187,25 @@ static void dtls1_clear_queues(SSL *s)
     while( (item = pqueue_pop(s->d1->buffered_messages)) != NULL)
         {
         frag = (hm_fragment *)item->data;
-        OPENSSL_free(frag->fragment);
-        OPENSSL_free(frag);
+        dtls1_hm_fragment_free(frag);
         pitem_free(item);
         }
 
     while ( (item = pqueue_pop(s->d1->sent_messages)) != NULL)
         {
         frag = (hm_fragment *)item->data;
-        OPENSSL_free(frag->fragment);
-        OPENSSL_free(frag);
+        dtls1_hm_fragment_free(frag);
         pitem_free(item);
         }
 
        while ( (item = pqueue_pop(s->d1->buffered_app_data.q)) != NULL)
                {
-               frag = (hm_fragment *)item->data;
-               OPENSSL_free(frag->fragment);
-               OPENSSL_free(frag);
+               rdata = (DTLS1_RECORD_DATA *) item->data;
+               if (rdata->rbuf.buf)
+                       {
+                       OPENSSL_free(rdata->rbuf.buf);
+                       }
+               OPENSSL_free(item->data);
                pitem_free(item);
                }
        }
@@ -291,6 +292,25 @@ long dtls1_ctrl(SSL *s, int cmd, long larg, void *parg)
        case DTLS_CTRL_LISTEN:
                ret = dtls1_listen(s, parg);
                break;
+       case SSL_CTRL_CHECK_PROTO_VERSION:
+               /* For library-internal use; checks that the current protocol
+                * is the highest enabled version (according to s->ctx->method,
+                * as version negotiation may have changed s->method). */
+               if (s->version == s->ctx->method->version)
+                       return 1;
+               /* Apparently we're using a version-flexible SSL_METHOD
+                * (not at its highest protocol version). */
+               if (s->ctx->method->version == DTLS_method()->version)
+                       {
+#if DTLS_MAX_VERSION != DTLS1_2_VERSION
+#  error Code needs update for DTLS_method() support beyond DTLS1_2_VERSION.
+#endif
+                       if (!(s->options & SSL_OP_NO_DTLSv1_2))
+                               return s->version == DTLS1_2_VERSION;
+                       if (!(s->options & SSL_OP_NO_DTLSv1))
+                               return s->version == DTLS1_VERSION;
+                       }
+               return 0; /* Unexpected state; fail closed. */
 
        default:
                ret = ssl3_ctrl(s, cmd, larg, parg);
@@ -481,11 +501,19 @@ int dtls1_handle_timeout(SSL *s)
 
 static void get_current_time(struct timeval *t)
 {
-#ifdef OPENSSL_SYS_WIN32
-       struct _timeb tb;
-       _ftime(&tb);
-       t->tv_sec = (long)tb.time;
-       t->tv_usec = (long)tb.millitm * 1000;
+#if defined(_WIN32)
+       SYSTEMTIME st;
+       union { unsigned __int64 ul; FILETIME ft; } now;
+
+       GetSystemTime(&st);
+       SystemTimeToFileTime(&st,&now.ft);
+#ifdef __MINGW32__
+       now.ul -= 116444736000000000ULL;
+#else
+       now.ul -= 116444736000000000UI64;       /* re-bias to 1/1/1970 */
+#endif
+       t->tv_sec  = (long)(now.ul/10000000);
+       t->tv_usec = ((int)(now.ul%10000000))/10;
 #elif defined(OPENSSL_SYS_VMS)
        struct timeb tb;
        ftime(&tb);