d1->cookie_len = sizeof(s->d1->cookie);
}
+ d1->link_mtu = 0;
+ d1->mtu = 0;
+
if( ! d1->unprocessed_rcds.q || ! d1->processed_rcds.q
|| ! d1->buffered_messages || ! d1->sent_messages || ! d1->buffered_app_data.q)
{
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);
}
pqueue sent_messages;
pqueue buffered_app_data;
unsigned int mtu;
+ unsigned int link_mtu;
if (s->d1)
{
sent_messages = s->d1->sent_messages;
buffered_app_data = s->d1->buffered_app_data.q;
mtu = s->d1->mtu;
+ link_mtu = s->d1->link_mtu;
dtls1_clear_queues(s);
if (SSL_get_options(s) & SSL_OP_NO_QUERY_MTU)
{
s->d1->mtu = mtu;
+ s->d1->link_mtu = link_mtu;
}
s->d1->unprocessed_rcds.q = unprocessed_rcds;
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. */
+
+ /* Just one protocol version is supported so far;
+ * fail closed if the version is not as expected. */
+ return s->version == DTLS_MAX_VERSION;
+ case DTLS_CTRL_SET_LINK_MTU:
+ if (larg < (long)dtls1_link_min_mtu())
+ return 0;
+ s->d1->link_mtu = larg;
+ return 1;
+ case DTLS_CTRL_GET_LINK_MIN_MTU:
+ return (long)dtls1_link_min_mtu();
+ case SSL_CTRL_SET_MTU:
+ /*
+ * We may not have a BIO set yet so can't call dtls1_min_mtu()
+ * We'll have to make do with dtls1_link_min_mtu() and max overhead
+ */
+ if (larg < (long)dtls1_link_min_mtu() - DTLS1_MAX_MTU_OVERHEAD)
+ return 0;
+ s->d1->mtu = larg;
+ return larg;
default:
ret = ssl3_ctrl(s, cmd, larg, parg);
break;
int dtls1_check_timeout_num(SSL *s)
{
+ unsigned int mtu;
+
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);
+ mtu = BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_GET_FALLBACK_MTU, 0, NULL);
+ if(mtu < s->d1->mtu)
+ s->d1->mtu = mtu;
}
if (s->d1->timeout.num_alerts > DTLS1_TMO_ALERT_COUNT)