The SSL_OP_NO_QUERY_MTU option is supposed to stop the mtu from being
[openssl.git] / ssl / d1_lib.c
index b739153309f0fe9b8cb69ea18a9f07dac9e002f1..09268b87903e341055e2ccf03080364705962a93 100644 (file)
@@ -72,8 +72,8 @@ static int dtls1_handshake_write(SSL *s);
 const char dtls1_version_str[]="DTLSv1" OPENSSL_VERSION_PTEXT;
 int dtls1_listen(SSL *s, struct sockaddr *client);
 
-SSL3_ENC_METHOD DTLSv1_enc_data={
-    dtls1_enc,
+const SSL3_ENC_METHOD DTLSv1_enc_data={
+       tls1_enc,
        tls1_mac,
        tls1_setup_key_block,
        tls1_generate_master_secret,
@@ -91,6 +91,26 @@ SSL3_ENC_METHOD DTLSv1_enc_data={
        dtls1_handshake_write   
        };
 
+const SSL3_ENC_METHOD DTLSv1_2_enc_data={
+       tls1_enc,
+       tls1_mac,
+       tls1_setup_key_block,
+       tls1_generate_master_secret,
+       tls1_change_cipher_state,
+       tls1_final_finish_mac,
+       TLS1_FINISH_MAC_LENGTH,
+       tls1_cert_verify_mac,
+       TLS_MD_CLIENT_FINISH_CONST,TLS_MD_CLIENT_FINISH_CONST_SIZE,
+       TLS_MD_SERVER_FINISH_CONST,TLS_MD_SERVER_FINISH_CONST_SIZE,
+       tls1_alert_code,
+       tls1_export_keying_material,
+       SSL_ENC_FLAG_DTLS|SSL_ENC_FLAG_EXPLICIT_IV|SSL_ENC_FLAG_SIGALGS
+               |SSL_ENC_FLAG_SHA256_PRF|SSL_ENC_FLAG_TLS1_2_CIPHERS,
+       DTLS1_HM_HEADER_LENGTH,
+       dtls1_set_handshake_header,
+       dtls1_handshake_write   
+       };
+
 long dtls1_default_timeout(void)
        {
        /* 2 hours, the 24 hours mentioned in the DTLSv1 spec
@@ -167,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);
                }
        }
@@ -202,6 +223,7 @@ void dtls1_free(SSL *s)
        pqueue_free(s->d1->buffered_app_data.q);
 
        OPENSSL_free(s->d1);
+       s->d1 = NULL;
        }
 
 void dtls1_clear(SSL *s)
@@ -246,8 +268,10 @@ void dtls1_clear(SSL *s)
        ssl3_clear(s);
        if (s->options & SSL_OP_CISCO_ANYCONNECT)
                s->version=DTLS1_BAD_VER;
+       else if (s->method->version == DTLS_ANY_VERSION)
+               s->version=DTLS1_2_VERSION;
        else
-               s->version=DTLS1_VERSION;
+               s->version=s->method->version;
        }
 
 long dtls1_ctrl(SSL *s, int cmd, long larg, void *parg)
@@ -268,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);
@@ -410,7 +453,8 @@ int dtls1_check_timeout_num(SSL *s)
        s->d1->timeout.num_alerts++;
 
        /* Reduce MTU after 2 unsuccessful retransmissions */
-       if (s->d1->timeout.num_alerts > 2)
+       if (s->d1->timeout.num_alerts > 2
+                       && !(SSL_get_options(s) & SSL_OP_NO_QUERY_MTU))
                {
                s->d1->mtu = BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_GET_FALLBACK_MTU, 0, NULL);               
                }
@@ -464,7 +508,11 @@ static void get_current_time(struct timeval *t)
 
        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)
@@ -505,5 +553,3 @@ static int dtls1_handshake_write(SSL *s)
        {
        return dtls1_do_write(s, SSL3_RT_HANDSHAKE);
        }
-       
-