1160814Ssimon/* ssl/d1_lib.c */
2280297Sjkim/*
3160814Ssimon * DTLS implementation written by Nagendra Modadugu
4280297Sjkim * (nagendra@cs.stanford.edu) for the OpenSSL project 2005.
5160814Ssimon */
6160814Ssimon/* ====================================================================
7160814Ssimon * Copyright (c) 1999-2005 The OpenSSL Project.  All rights reserved.
8160814Ssimon *
9160814Ssimon * Redistribution and use in source and binary forms, with or without
10160814Ssimon * modification, are permitted provided that the following conditions
11160814Ssimon * are met:
12160814Ssimon *
13160814Ssimon * 1. Redistributions of source code must retain the above copyright
14280297Sjkim *    notice, this list of conditions and the following disclaimer.
15160814Ssimon *
16160814Ssimon * 2. Redistributions in binary form must reproduce the above copyright
17160814Ssimon *    notice, this list of conditions and the following disclaimer in
18160814Ssimon *    the documentation and/or other materials provided with the
19160814Ssimon *    distribution.
20160814Ssimon *
21160814Ssimon * 3. All advertising materials mentioning features or use of this
22160814Ssimon *    software must display the following acknowledgment:
23160814Ssimon *    "This product includes software developed by the OpenSSL Project
24160814Ssimon *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
25160814Ssimon *
26160814Ssimon * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
27160814Ssimon *    endorse or promote products derived from this software without
28160814Ssimon *    prior written permission. For written permission, please contact
29160814Ssimon *    openssl-core@OpenSSL.org.
30160814Ssimon *
31160814Ssimon * 5. Products derived from this software may not be called "OpenSSL"
32160814Ssimon *    nor may "OpenSSL" appear in their names without prior written
33160814Ssimon *    permission of the OpenSSL Project.
34160814Ssimon *
35160814Ssimon * 6. Redistributions of any form whatsoever must retain the following
36160814Ssimon *    acknowledgment:
37160814Ssimon *    "This product includes software developed by the OpenSSL Project
38160814Ssimon *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
39160814Ssimon *
40160814Ssimon * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
41160814Ssimon * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
42160814Ssimon * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
43160814Ssimon * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
44160814Ssimon * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
45160814Ssimon * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
46160814Ssimon * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
47160814Ssimon * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48160814Ssimon * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
49160814Ssimon * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
50160814Ssimon * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
51160814Ssimon * OF THE POSSIBILITY OF SUCH DAMAGE.
52160814Ssimon * ====================================================================
53160814Ssimon *
54160814Ssimon * This product includes cryptographic software written by Eric Young
55160814Ssimon * (eay@cryptsoft.com).  This product includes software written by Tim
56160814Ssimon * Hudson (tjh@cryptsoft.com).
57160814Ssimon *
58160814Ssimon */
59160814Ssimon
60160814Ssimon#include <stdio.h>
61205128Ssimon#define USE_SOCKETS
62160814Ssimon#include <openssl/objects.h>
63160814Ssimon#include "ssl_locl.h"
64160814Ssimon
65290207Sjkim#if defined(OPENSSL_SYS_VMS)
66280297Sjkim# include <sys/timeb.h>
67205128Ssimon#endif
68205128Ssimon
69205128Ssimonstatic void get_current_time(struct timeval *t);
70290207Sjkimstatic void dtls1_set_handshake_header(SSL *s, int type, unsigned long len);
71290207Sjkimstatic int dtls1_handshake_write(SSL *s);
72280297Sjkimconst char dtls1_version_str[] = "DTLSv1" OPENSSL_VERSION_PTEXT;
73205128Ssimonint dtls1_listen(SSL *s, struct sockaddr *client);
74160814Ssimon
75280297SjkimSSL3_ENC_METHOD DTLSv1_enc_data = {
76290207Sjkim    tls1_enc,
77280297Sjkim    tls1_mac,
78280297Sjkim    tls1_setup_key_block,
79280297Sjkim    tls1_generate_master_secret,
80280297Sjkim    tls1_change_cipher_state,
81280297Sjkim    tls1_final_finish_mac,
82280297Sjkim    TLS1_FINISH_MAC_LENGTH,
83280297Sjkim    tls1_cert_verify_mac,
84280297Sjkim    TLS_MD_CLIENT_FINISH_CONST, TLS_MD_CLIENT_FINISH_CONST_SIZE,
85280297Sjkim    TLS_MD_SERVER_FINISH_CONST, TLS_MD_SERVER_FINISH_CONST_SIZE,
86280297Sjkim    tls1_alert_code,
87280297Sjkim    tls1_export_keying_material,
88290207Sjkim    SSL_ENC_FLAG_DTLS | SSL_ENC_FLAG_EXPLICIT_IV,
89290207Sjkim    DTLS1_HM_HEADER_LENGTH,
90290207Sjkim    dtls1_set_handshake_header,
91290207Sjkim    dtls1_handshake_write
92280297Sjkim};
93160814Ssimon
94290207SjkimSSL3_ENC_METHOD DTLSv1_2_enc_data = {
95290207Sjkim    tls1_enc,
96290207Sjkim    tls1_mac,
97290207Sjkim    tls1_setup_key_block,
98290207Sjkim    tls1_generate_master_secret,
99290207Sjkim    tls1_change_cipher_state,
100290207Sjkim    tls1_final_finish_mac,
101290207Sjkim    TLS1_FINISH_MAC_LENGTH,
102290207Sjkim    tls1_cert_verify_mac,
103290207Sjkim    TLS_MD_CLIENT_FINISH_CONST, TLS_MD_CLIENT_FINISH_CONST_SIZE,
104290207Sjkim    TLS_MD_SERVER_FINISH_CONST, TLS_MD_SERVER_FINISH_CONST_SIZE,
105290207Sjkim    tls1_alert_code,
106290207Sjkim    tls1_export_keying_material,
107290207Sjkim    SSL_ENC_FLAG_DTLS | SSL_ENC_FLAG_EXPLICIT_IV | SSL_ENC_FLAG_SIGALGS
108290207Sjkim        | SSL_ENC_FLAG_SHA256_PRF | SSL_ENC_FLAG_TLS1_2_CIPHERS,
109290207Sjkim    DTLS1_HM_HEADER_LENGTH,
110290207Sjkim    dtls1_set_handshake_header,
111290207Sjkim    dtls1_handshake_write
112290207Sjkim};
113290207Sjkim
114160814Ssimonlong dtls1_default_timeout(void)
115280297Sjkim{
116280297Sjkim    /*
117280297Sjkim     * 2 hours, the 24 hours mentioned in the DTLSv1 spec is way too long for
118280297Sjkim     * http, the cache would over fill
119280297Sjkim     */
120280297Sjkim    return (60 * 60 * 2);
121280297Sjkim}
122160814Ssimon
123160814Ssimonint dtls1_new(SSL *s)
124280297Sjkim{
125280297Sjkim    DTLS1_STATE *d1;
126160814Ssimon
127280297Sjkim    if (!ssl3_new(s))
128280297Sjkim        return (0);
129331638Sjkim    if ((d1 = OPENSSL_malloc(sizeof(*d1))) == NULL)
130280297Sjkim        return (0);
131331638Sjkim    memset(d1, 0, sizeof(*d1));
132160814Ssimon
133280297Sjkim    /* d1->handshake_epoch=0; */
134160814Ssimon
135280297Sjkim    d1->unprocessed_rcds.q = pqueue_new();
136280297Sjkim    d1->processed_rcds.q = pqueue_new();
137280297Sjkim    d1->buffered_messages = pqueue_new();
138280297Sjkim    d1->sent_messages = pqueue_new();
139280297Sjkim    d1->buffered_app_data.q = pqueue_new();
140160814Ssimon
141280297Sjkim    if (s->server) {
142280297Sjkim        d1->cookie_len = sizeof(s->d1->cookie);
143280297Sjkim    }
144160814Ssimon
145280297Sjkim    d1->link_mtu = 0;
146280297Sjkim    d1->mtu = 0;
147276861Sjkim
148280297Sjkim    if (!d1->unprocessed_rcds.q || !d1->processed_rcds.q
149280297Sjkim        || !d1->buffered_messages || !d1->sent_messages
150280297Sjkim        || !d1->buffered_app_data.q) {
151280297Sjkim        if (d1->unprocessed_rcds.q)
152280297Sjkim            pqueue_free(d1->unprocessed_rcds.q);
153280297Sjkim        if (d1->processed_rcds.q)
154280297Sjkim            pqueue_free(d1->processed_rcds.q);
155280297Sjkim        if (d1->buffered_messages)
156280297Sjkim            pqueue_free(d1->buffered_messages);
157280297Sjkim        if (d1->sent_messages)
158280297Sjkim            pqueue_free(d1->sent_messages);
159280297Sjkim        if (d1->buffered_app_data.q)
160280297Sjkim            pqueue_free(d1->buffered_app_data.q);
161280297Sjkim        OPENSSL_free(d1);
162280297Sjkim        return (0);
163280297Sjkim    }
164160814Ssimon
165280297Sjkim    s->d1 = d1;
166280297Sjkim    s->method->ssl_clear(s);
167280297Sjkim    return (1);
168280297Sjkim}
169160814Ssimon
170237657Sjkimstatic void dtls1_clear_queues(SSL *s)
171280297Sjkim{
172160814Ssimon    pitem *item = NULL;
173280297Sjkim    DTLS1_RECORD_DATA *rdata;
174160814Ssimon
175280297Sjkim    while ((item = pqueue_pop(s->d1->unprocessed_rcds.q)) != NULL) {
176280297Sjkim        rdata = (DTLS1_RECORD_DATA *)item->data;
177280297Sjkim        if (rdata->rbuf.buf) {
178280297Sjkim            OPENSSL_free(rdata->rbuf.buf);
179280297Sjkim        }
180160814Ssimon        OPENSSL_free(item->data);
181160814Ssimon        pitem_free(item);
182280297Sjkim    }
183280297Sjkim
184280297Sjkim    while ((item = pqueue_pop(s->d1->processed_rcds.q)) != NULL) {
185280297Sjkim        rdata = (DTLS1_RECORD_DATA *)item->data;
186280297Sjkim        if (rdata->rbuf.buf) {
187280297Sjkim            OPENSSL_free(rdata->rbuf.buf);
188160814Ssimon        }
189160814Ssimon        OPENSSL_free(item->data);
190160814Ssimon        pitem_free(item);
191280297Sjkim    }
192160814Ssimon
193306195Sjkim    while ((item = pqueue_pop(s->d1->buffered_app_data.q)) != NULL) {
194306195Sjkim        rdata = (DTLS1_RECORD_DATA *)item->data;
195306195Sjkim        if (rdata->rbuf.buf) {
196306195Sjkim            OPENSSL_free(rdata->rbuf.buf);
197306195Sjkim        }
198306195Sjkim        OPENSSL_free(item->data);
199306195Sjkim        pitem_free(item);
200306195Sjkim    }
201306195Sjkim
202306195Sjkim    dtls1_clear_received_buffer(s);
203306195Sjkim    dtls1_clear_sent_buffer(s);
204306195Sjkim}
205306195Sjkim
206306195Sjkimvoid dtls1_clear_received_buffer(SSL *s)
207306195Sjkim{
208306195Sjkim    pitem *item = NULL;
209306195Sjkim    hm_fragment *frag = NULL;
210306195Sjkim
211280297Sjkim    while ((item = pqueue_pop(s->d1->buffered_messages)) != NULL) {
212160814Ssimon        frag = (hm_fragment *)item->data;
213276861Sjkim        dtls1_hm_fragment_free(frag);
214160814Ssimon        pitem_free(item);
215280297Sjkim    }
216306195Sjkim}
217160814Ssimon
218306195Sjkimvoid dtls1_clear_sent_buffer(SSL *s)
219306195Sjkim{
220306195Sjkim    pitem *item = NULL;
221306195Sjkim    hm_fragment *frag = NULL;
222306195Sjkim
223280297Sjkim    while ((item = pqueue_pop(s->d1->sent_messages)) != NULL) {
224160814Ssimon        frag = (hm_fragment *)item->data;
225276861Sjkim        dtls1_hm_fragment_free(frag);
226160814Ssimon        pitem_free(item);
227280297Sjkim    }
228280297Sjkim}
229160814Ssimon
230306195Sjkim
231237657Sjkimvoid dtls1_free(SSL *s)
232280297Sjkim{
233280297Sjkim    ssl3_free(s);
234237657Sjkim
235280297Sjkim    dtls1_clear_queues(s);
236237657Sjkim
237237657Sjkim    pqueue_free(s->d1->unprocessed_rcds.q);
238237657Sjkim    pqueue_free(s->d1->processed_rcds.q);
239237657Sjkim    pqueue_free(s->d1->buffered_messages);
240280297Sjkim    pqueue_free(s->d1->sent_messages);
241280297Sjkim    pqueue_free(s->d1->buffered_app_data.q);
242160814Ssimon
243280297Sjkim    OPENSSL_free(s->d1);
244280297Sjkim    s->d1 = NULL;
245280297Sjkim}
246160814Ssimon
247160814Ssimonvoid dtls1_clear(SSL *s)
248280297Sjkim{
249237657Sjkim    pqueue unprocessed_rcds;
250237657Sjkim    pqueue processed_rcds;
251237657Sjkim    pqueue buffered_messages;
252280297Sjkim    pqueue sent_messages;
253280297Sjkim    pqueue buffered_app_data;
254280297Sjkim    unsigned int mtu;
255280297Sjkim    unsigned int link_mtu;
256237657Sjkim
257280297Sjkim    if (s->d1) {
258280297Sjkim        unprocessed_rcds = s->d1->unprocessed_rcds.q;
259280297Sjkim        processed_rcds = s->d1->processed_rcds.q;
260280297Sjkim        buffered_messages = s->d1->buffered_messages;
261280297Sjkim        sent_messages = s->d1->sent_messages;
262280297Sjkim        buffered_app_data = s->d1->buffered_app_data.q;
263280297Sjkim        mtu = s->d1->mtu;
264280297Sjkim        link_mtu = s->d1->link_mtu;
265237657Sjkim
266280297Sjkim        dtls1_clear_queues(s);
267237657Sjkim
268280297Sjkim        memset(s->d1, 0, sizeof(*(s->d1)));
269237657Sjkim
270280297Sjkim        if (s->server) {
271280297Sjkim            s->d1->cookie_len = sizeof(s->d1->cookie);
272280297Sjkim        }
273237657Sjkim
274280297Sjkim        if (SSL_get_options(s) & SSL_OP_NO_QUERY_MTU) {
275280297Sjkim            s->d1->mtu = mtu;
276280297Sjkim            s->d1->link_mtu = link_mtu;
277280297Sjkim        }
278237657Sjkim
279280297Sjkim        s->d1->unprocessed_rcds.q = unprocessed_rcds;
280280297Sjkim        s->d1->processed_rcds.q = processed_rcds;
281280297Sjkim        s->d1->buffered_messages = buffered_messages;
282280297Sjkim        s->d1->sent_messages = sent_messages;
283280297Sjkim        s->d1->buffered_app_data.q = buffered_app_data;
284280297Sjkim    }
285237657Sjkim
286280297Sjkim    ssl3_clear(s);
287280297Sjkim    if (s->options & SSL_OP_CISCO_ANYCONNECT)
288290207Sjkim        s->client_version = s->version = DTLS1_BAD_VER;
289290207Sjkim    else if (s->method->version == DTLS_ANY_VERSION)
290290207Sjkim        s->version = DTLS1_2_VERSION;
291280297Sjkim    else
292290207Sjkim        s->version = s->method->version;
293280297Sjkim}
294194206Ssimon
295205128Ssimonlong dtls1_ctrl(SSL *s, int cmd, long larg, void *parg)
296280297Sjkim{
297280297Sjkim    int ret = 0;
298205128Ssimon
299280297Sjkim    switch (cmd) {
300280297Sjkim    case DTLS_CTRL_GET_TIMEOUT:
301280297Sjkim        if (dtls1_get_timeout(s, (struct timeval *)parg) != NULL) {
302280297Sjkim            ret = 1;
303280297Sjkim        }
304280297Sjkim        break;
305280297Sjkim    case DTLS_CTRL_HANDLE_TIMEOUT:
306280297Sjkim        ret = dtls1_handle_timeout(s);
307280297Sjkim        break;
308280297Sjkim    case DTLS_CTRL_LISTEN:
309280297Sjkim        ret = dtls1_listen(s, parg);
310280297Sjkim        break;
311280297Sjkim    case SSL_CTRL_CHECK_PROTO_VERSION:
312280297Sjkim        /*
313280297Sjkim         * For library-internal use; checks that the current protocol is the
314280297Sjkim         * highest enabled version (according to s->ctx->method, as version
315280297Sjkim         * negotiation may have changed s->method).
316280297Sjkim         */
317290207Sjkim        if (s->version == s->ctx->method->version)
318290207Sjkim            return 1;
319280297Sjkim        /*
320290207Sjkim         * Apparently we're using a version-flexible SSL_METHOD (not at its
321290207Sjkim         * highest protocol version).
322280297Sjkim         */
323290207Sjkim        if (s->ctx->method->version == DTLS_method()->version) {
324290207Sjkim#if DTLS_MAX_VERSION != DTLS1_2_VERSION
325290207Sjkim# error Code needs update for DTLS_method() support beyond DTLS1_2_VERSION.
326290207Sjkim#endif
327290207Sjkim            if (!(s->options & SSL_OP_NO_DTLSv1_2))
328290207Sjkim                return s->version == DTLS1_2_VERSION;
329290207Sjkim            if (!(s->options & SSL_OP_NO_DTLSv1))
330290207Sjkim                return s->version == DTLS1_VERSION;
331290207Sjkim        }
332290207Sjkim        return 0;               /* Unexpected state; fail closed. */
333280297Sjkim    case DTLS_CTRL_SET_LINK_MTU:
334280297Sjkim        if (larg < (long)dtls1_link_min_mtu())
335280297Sjkim            return 0;
336280297Sjkim        s->d1->link_mtu = larg;
337280297Sjkim        return 1;
338280297Sjkim    case DTLS_CTRL_GET_LINK_MIN_MTU:
339280297Sjkim        return (long)dtls1_link_min_mtu();
340280297Sjkim    case SSL_CTRL_SET_MTU:
341280297Sjkim        /*
342280297Sjkim         *  We may not have a BIO set yet so can't call dtls1_min_mtu()
343280297Sjkim         *  We'll have to make do with dtls1_link_min_mtu() and max overhead
344280297Sjkim         */
345280297Sjkim        if (larg < (long)dtls1_link_min_mtu() - DTLS1_MAX_MTU_OVERHEAD)
346280297Sjkim            return 0;
347280297Sjkim        s->d1->mtu = larg;
348280297Sjkim        return larg;
349280297Sjkim    default:
350280297Sjkim        ret = ssl3_ctrl(s, cmd, larg, parg);
351280297Sjkim        break;
352280297Sjkim    }
353280297Sjkim    return (ret);
354280297Sjkim}
355205128Ssimon
356194206Ssimon/*
357194206Ssimon * As it's impossible to use stream ciphers in "datagram" mode, this
358194206Ssimon * simple filter is designed to disengage them in DTLS. Unfortunately
359194206Ssimon * there is no universal way to identify stream SSL_CIPHER, so we have
360194206Ssimon * to explicitly list their SSL_* codes. Currently RC4 is the only one
361194206Ssimon * available, but if new ones emerge, they will have to be added...
362194206Ssimon */
363238405Sjkimconst SSL_CIPHER *dtls1_get_cipher(unsigned int u)
364280297Sjkim{
365280297Sjkim    const SSL_CIPHER *ciph = ssl3_get_cipher(u);
366194206Ssimon
367280297Sjkim    if (ciph != NULL) {
368280297Sjkim        if (ciph->algorithm_enc == SSL_RC4)
369280297Sjkim            return NULL;
370280297Sjkim    }
371194206Ssimon
372280297Sjkim    return ciph;
373280297Sjkim}
374205128Ssimon
375205128Ssimonvoid dtls1_start_timer(SSL *s)
376280297Sjkim{
377238405Sjkim#ifndef OPENSSL_NO_SCTP
378280297Sjkim    /* Disable timer for SCTP */
379280297Sjkim    if (BIO_dgram_is_sctp(SSL_get_wbio(s))) {
380280297Sjkim        memset(&(s->d1->next_timeout), 0, sizeof(struct timeval));
381280297Sjkim        return;
382280297Sjkim    }
383238405Sjkim#endif
384238405Sjkim
385280297Sjkim    /* If timer is not set, initialize duration with 1 second */
386280297Sjkim    if (s->d1->next_timeout.tv_sec == 0 && s->d1->next_timeout.tv_usec == 0) {
387280297Sjkim        s->d1->timeout_duration = 1;
388280297Sjkim    }
389205128Ssimon
390280297Sjkim    /* Set timeout to current time */
391280297Sjkim    get_current_time(&(s->d1->next_timeout));
392205128Ssimon
393280297Sjkim    /* Add duration to current time */
394280297Sjkim    s->d1->next_timeout.tv_sec += s->d1->timeout_duration;
395280297Sjkim    BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT, 0,
396280297Sjkim             &(s->d1->next_timeout));
397280297Sjkim}
398205128Ssimon
399280297Sjkimstruct timeval *dtls1_get_timeout(SSL *s, struct timeval *timeleft)
400280297Sjkim{
401280297Sjkim    struct timeval timenow;
402205128Ssimon
403280297Sjkim    /* If no timeout is set, just return NULL */
404280297Sjkim    if (s->d1->next_timeout.tv_sec == 0 && s->d1->next_timeout.tv_usec == 0) {
405280297Sjkim        return NULL;
406280297Sjkim    }
407205128Ssimon
408280297Sjkim    /* Get current time */
409280297Sjkim    get_current_time(&timenow);
410205128Ssimon
411280297Sjkim    /* If timer already expired, set remaining time to 0 */
412280297Sjkim    if (s->d1->next_timeout.tv_sec < timenow.tv_sec ||
413280297Sjkim        (s->d1->next_timeout.tv_sec == timenow.tv_sec &&
414280297Sjkim         s->d1->next_timeout.tv_usec <= timenow.tv_usec)) {
415280297Sjkim        memset(timeleft, 0, sizeof(struct timeval));
416280297Sjkim        return timeleft;
417280297Sjkim    }
418205128Ssimon
419280297Sjkim    /* Calculate time left until timer expires */
420280297Sjkim    memcpy(timeleft, &(s->d1->next_timeout), sizeof(struct timeval));
421280297Sjkim    timeleft->tv_sec -= timenow.tv_sec;
422280297Sjkim    timeleft->tv_usec -= timenow.tv_usec;
423280297Sjkim    if (timeleft->tv_usec < 0) {
424280297Sjkim        timeleft->tv_sec--;
425280297Sjkim        timeleft->tv_usec += 1000000;
426280297Sjkim    }
427215697Ssimon
428280297Sjkim    /*
429280297Sjkim     * If remaining time is less than 15 ms, set it to 0 to prevent issues
430280297Sjkim     * because of small devergences with socket timeouts.
431280297Sjkim     */
432280297Sjkim    if (timeleft->tv_sec == 0 && timeleft->tv_usec < 15000) {
433280297Sjkim        memset(timeleft, 0, sizeof(struct timeval));
434280297Sjkim    }
435205128Ssimon
436280297Sjkim    return timeleft;
437280297Sjkim}
438280297Sjkim
439205128Ssimonint dtls1_is_timer_expired(SSL *s)
440280297Sjkim{
441280297Sjkim    struct timeval timeleft;
442205128Ssimon
443280297Sjkim    /* Get time left until timeout, return false if no timer running */
444280297Sjkim    if (dtls1_get_timeout(s, &timeleft) == NULL) {
445280297Sjkim        return 0;
446280297Sjkim    }
447205128Ssimon
448280297Sjkim    /* Return false if timer is not expired yet */
449280297Sjkim    if (timeleft.tv_sec > 0 || timeleft.tv_usec > 0) {
450280297Sjkim        return 0;
451280297Sjkim    }
452205128Ssimon
453280297Sjkim    /* Timer expired, so return true */
454280297Sjkim    return 1;
455280297Sjkim}
456205128Ssimon
457205128Ssimonvoid dtls1_double_timeout(SSL *s)
458280297Sjkim{
459280297Sjkim    s->d1->timeout_duration *= 2;
460280297Sjkim    if (s->d1->timeout_duration > 60)
461280297Sjkim        s->d1->timeout_duration = 60;
462280297Sjkim    dtls1_start_timer(s);
463280297Sjkim}
464205128Ssimon
465205128Ssimonvoid dtls1_stop_timer(SSL *s)
466280297Sjkim{
467280297Sjkim    /* Reset everything */
468280297Sjkim    memset(&(s->d1->timeout), 0, sizeof(struct dtls1_timeout_st));
469280297Sjkim    memset(&(s->d1->next_timeout), 0, sizeof(struct timeval));
470280297Sjkim    s->d1->timeout_duration = 1;
471280297Sjkim    BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT, 0,
472280297Sjkim             &(s->d1->next_timeout));
473280297Sjkim    /* Clear retransmission buffer */
474306195Sjkim    dtls1_clear_sent_buffer(s);
475280297Sjkim}
476205128Ssimon
477237657Sjkimint dtls1_check_timeout_num(SSL *s)
478280297Sjkim{
479280297Sjkim    unsigned int mtu;
480276861Sjkim
481280297Sjkim    s->d1->timeout.num_alerts++;
482205128Ssimon
483280297Sjkim    /* Reduce MTU after 2 unsuccessful retransmissions */
484280297Sjkim    if (s->d1->timeout.num_alerts > 2
485280297Sjkim        && !(SSL_get_options(s) & SSL_OP_NO_QUERY_MTU)) {
486280297Sjkim        mtu =
487280297Sjkim            BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_GET_FALLBACK_MTU, 0,
488280297Sjkim                     NULL);
489280297Sjkim        if (mtu < s->d1->mtu)
490280297Sjkim            s->d1->mtu = mtu;
491280297Sjkim    }
492205128Ssimon
493280297Sjkim    if (s->d1->timeout.num_alerts > DTLS1_TMO_ALERT_COUNT) {
494280297Sjkim        /* fail the connection, enough alerts have been sent */
495280297Sjkim        SSLerr(SSL_F_DTLS1_CHECK_TIMEOUT_NUM, SSL_R_READ_TIMEOUT_EXPIRED);
496280297Sjkim        return -1;
497280297Sjkim    }
498237657Sjkim
499280297Sjkim    return 0;
500280297Sjkim}
501237657Sjkim
502237657Sjkimint dtls1_handle_timeout(SSL *s)
503280297Sjkim{
504280297Sjkim    /* if no timer is expired, don't do anything */
505280297Sjkim    if (!dtls1_is_timer_expired(s)) {
506280297Sjkim        return 0;
507280297Sjkim    }
508205128Ssimon
509280297Sjkim    dtls1_double_timeout(s);
510237657Sjkim
511280297Sjkim    if (dtls1_check_timeout_num(s) < 0)
512280297Sjkim        return -1;
513237657Sjkim
514280297Sjkim    s->d1->timeout.read_timeouts++;
515280297Sjkim    if (s->d1->timeout.read_timeouts > DTLS1_TMO_READ_COUNT) {
516280297Sjkim        s->d1->timeout.read_timeouts = 1;
517280297Sjkim    }
518238405Sjkim#ifndef OPENSSL_NO_HEARTBEATS
519280297Sjkim    if (s->tlsext_hb_pending) {
520280297Sjkim        s->tlsext_hb_pending = 0;
521280297Sjkim        return dtls1_heartbeat(s);
522280297Sjkim    }
523238405Sjkim#endif
524238405Sjkim
525280297Sjkim    dtls1_start_timer(s);
526280297Sjkim    return dtls1_retransmit_buffered_messages(s);
527280297Sjkim}
528205128Ssimon
529205128Ssimonstatic void get_current_time(struct timeval *t)
530205128Ssimon{
531290207Sjkim#if defined(_WIN32)
532290207Sjkim    SYSTEMTIME st;
533290207Sjkim    union {
534290207Sjkim        unsigned __int64 ul;
535290207Sjkim        FILETIME ft;
536290207Sjkim    } now;
537290207Sjkim
538290207Sjkim    GetSystemTime(&st);
539290207Sjkim    SystemTimeToFileTime(&st, &now.ft);
540290207Sjkim# ifdef  __MINGW32__
541290207Sjkim    now.ul -= 116444736000000000ULL;
542290207Sjkim# else
543290207Sjkim    now.ul -= 116444736000000000UI64; /* re-bias to 1/1/1970 */
544290207Sjkim# endif
545290207Sjkim    t->tv_sec = (long)(now.ul / 10000000);
546290207Sjkim    t->tv_usec = ((int)(now.ul % 10000000)) / 10;
547205128Ssimon#elif defined(OPENSSL_SYS_VMS)
548280297Sjkim    struct timeb tb;
549280297Sjkim    ftime(&tb);
550280297Sjkim    t->tv_sec = (long)tb.time;
551280297Sjkim    t->tv_usec = (long)tb.millitm * 1000;
552205128Ssimon#else
553280297Sjkim    gettimeofday(t, NULL);
554205128Ssimon#endif
555205128Ssimon}
556205128Ssimon
557205128Ssimonint dtls1_listen(SSL *s, struct sockaddr *client)
558280297Sjkim{
559280297Sjkim    int ret;
560205128Ssimon
561284283Sjkim    /* Ensure there is no state left over from a previous invocation */
562284283Sjkim    SSL_clear(s);
563284283Sjkim
564280297Sjkim    SSL_set_options(s, SSL_OP_COOKIE_EXCHANGE);
565280297Sjkim    s->d1->listen = 1;
566205128Ssimon
567280297Sjkim    ret = SSL_accept(s);
568280297Sjkim    if (ret <= 0)
569280297Sjkim        return ret;
570280297Sjkim
571280297Sjkim    (void)BIO_dgram_get_peer(SSL_get_rbio(s), client);
572280297Sjkim    return 1;
573280297Sjkim}
574290207Sjkim
575290207Sjkimstatic void dtls1_set_handshake_header(SSL *s, int htype, unsigned long len)
576290207Sjkim{
577290207Sjkim    unsigned char *p = (unsigned char *)s->init_buf->data;
578290207Sjkim    dtls1_set_message_header(s, p, htype, len, 0, len);
579290207Sjkim    s->init_num = (int)len + DTLS1_HM_HEADER_LENGTH;
580290207Sjkim    s->init_off = 0;
581290207Sjkim    /* Buffer the message to handle re-xmits */
582290207Sjkim    dtls1_buffer_message(s, 0);
583290207Sjkim}
584290207Sjkim
585290207Sjkimstatic int dtls1_handshake_write(SSL *s)
586290207Sjkim{
587290207Sjkim    return dtls1_do_write(s, SSL3_RT_HANDSHAKE);
588290207Sjkim}
589