1*8fb009dcSAndroid Build Coastguard Worker /*
2*8fb009dcSAndroid Build Coastguard Worker * DTLS implementation written by Nagendra Modadugu
3*8fb009dcSAndroid Build Coastguard Worker * ([email protected]) for the OpenSSL project 2005.
4*8fb009dcSAndroid Build Coastguard Worker */
5*8fb009dcSAndroid Build Coastguard Worker /* ====================================================================
6*8fb009dcSAndroid Build Coastguard Worker * Copyright (c) 1999-2005 The OpenSSL Project. All rights reserved.
7*8fb009dcSAndroid Build Coastguard Worker *
8*8fb009dcSAndroid Build Coastguard Worker * Redistribution and use in source and binary forms, with or without
9*8fb009dcSAndroid Build Coastguard Worker * modification, are permitted provided that the following conditions
10*8fb009dcSAndroid Build Coastguard Worker * are met:
11*8fb009dcSAndroid Build Coastguard Worker *
12*8fb009dcSAndroid Build Coastguard Worker * 1. Redistributions of source code must retain the above copyright
13*8fb009dcSAndroid Build Coastguard Worker * notice, this list of conditions and the following disclaimer.
14*8fb009dcSAndroid Build Coastguard Worker *
15*8fb009dcSAndroid Build Coastguard Worker * 2. Redistributions in binary form must reproduce the above copyright
16*8fb009dcSAndroid Build Coastguard Worker * notice, this list of conditions and the following disclaimer in
17*8fb009dcSAndroid Build Coastguard Worker * the documentation and/or other materials provided with the
18*8fb009dcSAndroid Build Coastguard Worker * distribution.
19*8fb009dcSAndroid Build Coastguard Worker *
20*8fb009dcSAndroid Build Coastguard Worker * 3. All advertising materials mentioning features or use of this
21*8fb009dcSAndroid Build Coastguard Worker * software must display the following acknowledgment:
22*8fb009dcSAndroid Build Coastguard Worker * "This product includes software developed by the OpenSSL Project
23*8fb009dcSAndroid Build Coastguard Worker * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
24*8fb009dcSAndroid Build Coastguard Worker *
25*8fb009dcSAndroid Build Coastguard Worker * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
26*8fb009dcSAndroid Build Coastguard Worker * endorse or promote products derived from this software without
27*8fb009dcSAndroid Build Coastguard Worker * prior written permission. For written permission, please contact
28*8fb009dcSAndroid Build Coastguard Worker * [email protected].
29*8fb009dcSAndroid Build Coastguard Worker *
30*8fb009dcSAndroid Build Coastguard Worker * 5. Products derived from this software may not be called "OpenSSL"
31*8fb009dcSAndroid Build Coastguard Worker * nor may "OpenSSL" appear in their names without prior written
32*8fb009dcSAndroid Build Coastguard Worker * permission of the OpenSSL Project.
33*8fb009dcSAndroid Build Coastguard Worker *
34*8fb009dcSAndroid Build Coastguard Worker * 6. Redistributions of any form whatsoever must retain the following
35*8fb009dcSAndroid Build Coastguard Worker * acknowledgment:
36*8fb009dcSAndroid Build Coastguard Worker * "This product includes software developed by the OpenSSL Project
37*8fb009dcSAndroid Build Coastguard Worker * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
38*8fb009dcSAndroid Build Coastguard Worker *
39*8fb009dcSAndroid Build Coastguard Worker * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
40*8fb009dcSAndroid Build Coastguard Worker * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41*8fb009dcSAndroid Build Coastguard Worker * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42*8fb009dcSAndroid Build Coastguard Worker * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
43*8fb009dcSAndroid Build Coastguard Worker * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44*8fb009dcSAndroid Build Coastguard Worker * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45*8fb009dcSAndroid Build Coastguard Worker * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46*8fb009dcSAndroid Build Coastguard Worker * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47*8fb009dcSAndroid Build Coastguard Worker * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48*8fb009dcSAndroid Build Coastguard Worker * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49*8fb009dcSAndroid Build Coastguard Worker * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50*8fb009dcSAndroid Build Coastguard Worker * OF THE POSSIBILITY OF SUCH DAMAGE.
51*8fb009dcSAndroid Build Coastguard Worker * ====================================================================
52*8fb009dcSAndroid Build Coastguard Worker *
53*8fb009dcSAndroid Build Coastguard Worker * This product includes cryptographic software written by Eric Young
54*8fb009dcSAndroid Build Coastguard Worker * ([email protected]). This product includes software written by Tim
55*8fb009dcSAndroid Build Coastguard Worker * Hudson ([email protected]). */
56*8fb009dcSAndroid Build Coastguard Worker
57*8fb009dcSAndroid Build Coastguard Worker #include <openssl/ssl.h>
58*8fb009dcSAndroid Build Coastguard Worker
59*8fb009dcSAndroid Build Coastguard Worker #include <assert.h>
60*8fb009dcSAndroid Build Coastguard Worker #include <limits.h>
61*8fb009dcSAndroid Build Coastguard Worker #include <string.h>
62*8fb009dcSAndroid Build Coastguard Worker
63*8fb009dcSAndroid Build Coastguard Worker #include <openssl/err.h>
64*8fb009dcSAndroid Build Coastguard Worker #include <openssl/mem.h>
65*8fb009dcSAndroid Build Coastguard Worker #include <openssl/nid.h>
66*8fb009dcSAndroid Build Coastguard Worker
67*8fb009dcSAndroid Build Coastguard Worker #include "../crypto/internal.h"
68*8fb009dcSAndroid Build Coastguard Worker #include "internal.h"
69*8fb009dcSAndroid Build Coastguard Worker
70*8fb009dcSAndroid Build Coastguard Worker
71*8fb009dcSAndroid Build Coastguard Worker BSSL_NAMESPACE_BEGIN
72*8fb009dcSAndroid Build Coastguard Worker
73*8fb009dcSAndroid Build Coastguard Worker // DTLS1_MTU_TIMEOUTS is the maximum number of timeouts to expire
74*8fb009dcSAndroid Build Coastguard Worker // before starting to decrease the MTU.
75*8fb009dcSAndroid Build Coastguard Worker #define DTLS1_MTU_TIMEOUTS 2
76*8fb009dcSAndroid Build Coastguard Worker
77*8fb009dcSAndroid Build Coastguard Worker // DTLS1_MAX_TIMEOUTS is the maximum number of timeouts to expire
78*8fb009dcSAndroid Build Coastguard Worker // before failing the DTLS handshake.
79*8fb009dcSAndroid Build Coastguard Worker #define DTLS1_MAX_TIMEOUTS 12
80*8fb009dcSAndroid Build Coastguard Worker
DTLS1_STATE()81*8fb009dcSAndroid Build Coastguard Worker DTLS1_STATE::DTLS1_STATE()
82*8fb009dcSAndroid Build Coastguard Worker : has_change_cipher_spec(false),
83*8fb009dcSAndroid Build Coastguard Worker outgoing_messages_complete(false),
84*8fb009dcSAndroid Build Coastguard Worker flight_has_reply(false) {}
85*8fb009dcSAndroid Build Coastguard Worker
~DTLS1_STATE()86*8fb009dcSAndroid Build Coastguard Worker DTLS1_STATE::~DTLS1_STATE() {}
87*8fb009dcSAndroid Build Coastguard Worker
dtls1_new(SSL * ssl)88*8fb009dcSAndroid Build Coastguard Worker bool dtls1_new(SSL *ssl) {
89*8fb009dcSAndroid Build Coastguard Worker if (!tls_new(ssl)) {
90*8fb009dcSAndroid Build Coastguard Worker return false;
91*8fb009dcSAndroid Build Coastguard Worker }
92*8fb009dcSAndroid Build Coastguard Worker UniquePtr<DTLS1_STATE> d1 = MakeUnique<DTLS1_STATE>();
93*8fb009dcSAndroid Build Coastguard Worker if (!d1) {
94*8fb009dcSAndroid Build Coastguard Worker tls_free(ssl);
95*8fb009dcSAndroid Build Coastguard Worker return false;
96*8fb009dcSAndroid Build Coastguard Worker }
97*8fb009dcSAndroid Build Coastguard Worker
98*8fb009dcSAndroid Build Coastguard Worker ssl->d1 = d1.release();
99*8fb009dcSAndroid Build Coastguard Worker
100*8fb009dcSAndroid Build Coastguard Worker // Set the version to the highest supported version.
101*8fb009dcSAndroid Build Coastguard Worker //
102*8fb009dcSAndroid Build Coastguard Worker // TODO(davidben): Move this field into |s3|, have it store the normalized
103*8fb009dcSAndroid Build Coastguard Worker // protocol version, and implement this pre-negotiation quirk in |SSL_version|
104*8fb009dcSAndroid Build Coastguard Worker // at the API boundary rather than in internal state.
105*8fb009dcSAndroid Build Coastguard Worker ssl->version = DTLS1_2_VERSION;
106*8fb009dcSAndroid Build Coastguard Worker return true;
107*8fb009dcSAndroid Build Coastguard Worker }
108*8fb009dcSAndroid Build Coastguard Worker
dtls1_free(SSL * ssl)109*8fb009dcSAndroid Build Coastguard Worker void dtls1_free(SSL *ssl) {
110*8fb009dcSAndroid Build Coastguard Worker tls_free(ssl);
111*8fb009dcSAndroid Build Coastguard Worker
112*8fb009dcSAndroid Build Coastguard Worker if (ssl == NULL) {
113*8fb009dcSAndroid Build Coastguard Worker return;
114*8fb009dcSAndroid Build Coastguard Worker }
115*8fb009dcSAndroid Build Coastguard Worker
116*8fb009dcSAndroid Build Coastguard Worker Delete(ssl->d1);
117*8fb009dcSAndroid Build Coastguard Worker ssl->d1 = NULL;
118*8fb009dcSAndroid Build Coastguard Worker }
119*8fb009dcSAndroid Build Coastguard Worker
dtls1_start_timer(SSL * ssl)120*8fb009dcSAndroid Build Coastguard Worker void dtls1_start_timer(SSL *ssl) {
121*8fb009dcSAndroid Build Coastguard Worker // If timer is not set, initialize duration (by default, 1 second)
122*8fb009dcSAndroid Build Coastguard Worker if (ssl->d1->next_timeout.tv_sec == 0 && ssl->d1->next_timeout.tv_usec == 0) {
123*8fb009dcSAndroid Build Coastguard Worker ssl->d1->timeout_duration_ms = ssl->initial_timeout_duration_ms;
124*8fb009dcSAndroid Build Coastguard Worker }
125*8fb009dcSAndroid Build Coastguard Worker
126*8fb009dcSAndroid Build Coastguard Worker // Set timeout to current time
127*8fb009dcSAndroid Build Coastguard Worker ssl_get_current_time(ssl, &ssl->d1->next_timeout);
128*8fb009dcSAndroid Build Coastguard Worker
129*8fb009dcSAndroid Build Coastguard Worker // Add duration to current time
130*8fb009dcSAndroid Build Coastguard Worker ssl->d1->next_timeout.tv_sec += ssl->d1->timeout_duration_ms / 1000;
131*8fb009dcSAndroid Build Coastguard Worker ssl->d1->next_timeout.tv_usec += (ssl->d1->timeout_duration_ms % 1000) * 1000;
132*8fb009dcSAndroid Build Coastguard Worker if (ssl->d1->next_timeout.tv_usec >= 1000000) {
133*8fb009dcSAndroid Build Coastguard Worker ssl->d1->next_timeout.tv_sec++;
134*8fb009dcSAndroid Build Coastguard Worker ssl->d1->next_timeout.tv_usec -= 1000000;
135*8fb009dcSAndroid Build Coastguard Worker }
136*8fb009dcSAndroid Build Coastguard Worker }
137*8fb009dcSAndroid Build Coastguard Worker
dtls1_is_timer_expired(SSL * ssl)138*8fb009dcSAndroid Build Coastguard Worker bool dtls1_is_timer_expired(SSL *ssl) {
139*8fb009dcSAndroid Build Coastguard Worker struct timeval timeleft;
140*8fb009dcSAndroid Build Coastguard Worker
141*8fb009dcSAndroid Build Coastguard Worker // Get time left until timeout, return false if no timer running
142*8fb009dcSAndroid Build Coastguard Worker if (!DTLSv1_get_timeout(ssl, &timeleft)) {
143*8fb009dcSAndroid Build Coastguard Worker return false;
144*8fb009dcSAndroid Build Coastguard Worker }
145*8fb009dcSAndroid Build Coastguard Worker
146*8fb009dcSAndroid Build Coastguard Worker // Return false if timer is not expired yet
147*8fb009dcSAndroid Build Coastguard Worker if (timeleft.tv_sec > 0 || timeleft.tv_usec > 0) {
148*8fb009dcSAndroid Build Coastguard Worker return false;
149*8fb009dcSAndroid Build Coastguard Worker }
150*8fb009dcSAndroid Build Coastguard Worker
151*8fb009dcSAndroid Build Coastguard Worker // Timer expired, so return true
152*8fb009dcSAndroid Build Coastguard Worker return true;
153*8fb009dcSAndroid Build Coastguard Worker }
154*8fb009dcSAndroid Build Coastguard Worker
dtls1_double_timeout(SSL * ssl)155*8fb009dcSAndroid Build Coastguard Worker static void dtls1_double_timeout(SSL *ssl) {
156*8fb009dcSAndroid Build Coastguard Worker ssl->d1->timeout_duration_ms *= 2;
157*8fb009dcSAndroid Build Coastguard Worker if (ssl->d1->timeout_duration_ms > 60000) {
158*8fb009dcSAndroid Build Coastguard Worker ssl->d1->timeout_duration_ms = 60000;
159*8fb009dcSAndroid Build Coastguard Worker }
160*8fb009dcSAndroid Build Coastguard Worker }
161*8fb009dcSAndroid Build Coastguard Worker
dtls1_stop_timer(SSL * ssl)162*8fb009dcSAndroid Build Coastguard Worker void dtls1_stop_timer(SSL *ssl) {
163*8fb009dcSAndroid Build Coastguard Worker ssl->d1->num_timeouts = 0;
164*8fb009dcSAndroid Build Coastguard Worker OPENSSL_memset(&ssl->d1->next_timeout, 0, sizeof(ssl->d1->next_timeout));
165*8fb009dcSAndroid Build Coastguard Worker ssl->d1->timeout_duration_ms = ssl->initial_timeout_duration_ms;
166*8fb009dcSAndroid Build Coastguard Worker }
167*8fb009dcSAndroid Build Coastguard Worker
dtls1_check_timeout_num(SSL * ssl)168*8fb009dcSAndroid Build Coastguard Worker bool dtls1_check_timeout_num(SSL *ssl) {
169*8fb009dcSAndroid Build Coastguard Worker ssl->d1->num_timeouts++;
170*8fb009dcSAndroid Build Coastguard Worker
171*8fb009dcSAndroid Build Coastguard Worker // Reduce MTU after 2 unsuccessful retransmissions
172*8fb009dcSAndroid Build Coastguard Worker if (ssl->d1->num_timeouts > DTLS1_MTU_TIMEOUTS &&
173*8fb009dcSAndroid Build Coastguard Worker !(SSL_get_options(ssl) & SSL_OP_NO_QUERY_MTU)) {
174*8fb009dcSAndroid Build Coastguard Worker long mtu =
175*8fb009dcSAndroid Build Coastguard Worker BIO_ctrl(ssl->wbio.get(), BIO_CTRL_DGRAM_GET_FALLBACK_MTU, 0, nullptr);
176*8fb009dcSAndroid Build Coastguard Worker if (mtu >= 0 && mtu <= (1 << 30) && (unsigned)mtu >= dtls1_min_mtu()) {
177*8fb009dcSAndroid Build Coastguard Worker ssl->d1->mtu = (unsigned)mtu;
178*8fb009dcSAndroid Build Coastguard Worker }
179*8fb009dcSAndroid Build Coastguard Worker }
180*8fb009dcSAndroid Build Coastguard Worker
181*8fb009dcSAndroid Build Coastguard Worker if (ssl->d1->num_timeouts > DTLS1_MAX_TIMEOUTS) {
182*8fb009dcSAndroid Build Coastguard Worker // fail the connection, enough alerts have been sent
183*8fb009dcSAndroid Build Coastguard Worker OPENSSL_PUT_ERROR(SSL, SSL_R_READ_TIMEOUT_EXPIRED);
184*8fb009dcSAndroid Build Coastguard Worker return false;
185*8fb009dcSAndroid Build Coastguard Worker }
186*8fb009dcSAndroid Build Coastguard Worker
187*8fb009dcSAndroid Build Coastguard Worker return true;
188*8fb009dcSAndroid Build Coastguard Worker }
189*8fb009dcSAndroid Build Coastguard Worker
190*8fb009dcSAndroid Build Coastguard Worker BSSL_NAMESPACE_END
191*8fb009dcSAndroid Build Coastguard Worker
192*8fb009dcSAndroid Build Coastguard Worker using namespace bssl;
193*8fb009dcSAndroid Build Coastguard Worker
DTLSv1_set_initial_timeout_duration(SSL * ssl,unsigned int duration_ms)194*8fb009dcSAndroid Build Coastguard Worker void DTLSv1_set_initial_timeout_duration(SSL *ssl, unsigned int duration_ms) {
195*8fb009dcSAndroid Build Coastguard Worker ssl->initial_timeout_duration_ms = duration_ms;
196*8fb009dcSAndroid Build Coastguard Worker }
197*8fb009dcSAndroid Build Coastguard Worker
DTLSv1_get_timeout(const SSL * ssl,struct timeval * out)198*8fb009dcSAndroid Build Coastguard Worker int DTLSv1_get_timeout(const SSL *ssl, struct timeval *out) {
199*8fb009dcSAndroid Build Coastguard Worker if (!SSL_is_dtls(ssl)) {
200*8fb009dcSAndroid Build Coastguard Worker return 0;
201*8fb009dcSAndroid Build Coastguard Worker }
202*8fb009dcSAndroid Build Coastguard Worker
203*8fb009dcSAndroid Build Coastguard Worker // If no timeout is set, just return 0.
204*8fb009dcSAndroid Build Coastguard Worker if (ssl->d1->next_timeout.tv_sec == 0 && ssl->d1->next_timeout.tv_usec == 0) {
205*8fb009dcSAndroid Build Coastguard Worker return 0;
206*8fb009dcSAndroid Build Coastguard Worker }
207*8fb009dcSAndroid Build Coastguard Worker
208*8fb009dcSAndroid Build Coastguard Worker struct OPENSSL_timeval timenow;
209*8fb009dcSAndroid Build Coastguard Worker ssl_get_current_time(ssl, &timenow);
210*8fb009dcSAndroid Build Coastguard Worker
211*8fb009dcSAndroid Build Coastguard Worker // If timer already expired, set remaining time to 0.
212*8fb009dcSAndroid Build Coastguard Worker if (ssl->d1->next_timeout.tv_sec < timenow.tv_sec ||
213*8fb009dcSAndroid Build Coastguard Worker (ssl->d1->next_timeout.tv_sec == timenow.tv_sec &&
214*8fb009dcSAndroid Build Coastguard Worker ssl->d1->next_timeout.tv_usec <= timenow.tv_usec)) {
215*8fb009dcSAndroid Build Coastguard Worker OPENSSL_memset(out, 0, sizeof(*out));
216*8fb009dcSAndroid Build Coastguard Worker return 1;
217*8fb009dcSAndroid Build Coastguard Worker }
218*8fb009dcSAndroid Build Coastguard Worker
219*8fb009dcSAndroid Build Coastguard Worker // Calculate time left until timer expires.
220*8fb009dcSAndroid Build Coastguard Worker struct OPENSSL_timeval ret;
221*8fb009dcSAndroid Build Coastguard Worker OPENSSL_memcpy(&ret, &ssl->d1->next_timeout, sizeof(ret));
222*8fb009dcSAndroid Build Coastguard Worker ret.tv_sec -= timenow.tv_sec;
223*8fb009dcSAndroid Build Coastguard Worker if (ret.tv_usec >= timenow.tv_usec) {
224*8fb009dcSAndroid Build Coastguard Worker ret.tv_usec -= timenow.tv_usec;
225*8fb009dcSAndroid Build Coastguard Worker } else {
226*8fb009dcSAndroid Build Coastguard Worker ret.tv_usec = 1000000 + ret.tv_usec - timenow.tv_usec;
227*8fb009dcSAndroid Build Coastguard Worker ret.tv_sec--;
228*8fb009dcSAndroid Build Coastguard Worker }
229*8fb009dcSAndroid Build Coastguard Worker
230*8fb009dcSAndroid Build Coastguard Worker // If remaining time is less than 15 ms, set it to 0 to prevent issues
231*8fb009dcSAndroid Build Coastguard Worker // because of small divergences with socket timeouts.
232*8fb009dcSAndroid Build Coastguard Worker if (ret.tv_sec == 0 && ret.tv_usec < 15000) {
233*8fb009dcSAndroid Build Coastguard Worker OPENSSL_memset(&ret, 0, sizeof(ret));
234*8fb009dcSAndroid Build Coastguard Worker }
235*8fb009dcSAndroid Build Coastguard Worker
236*8fb009dcSAndroid Build Coastguard Worker // Clamp the result in case of overflow.
237*8fb009dcSAndroid Build Coastguard Worker if (ret.tv_sec > INT_MAX) {
238*8fb009dcSAndroid Build Coastguard Worker assert(0);
239*8fb009dcSAndroid Build Coastguard Worker out->tv_sec = INT_MAX;
240*8fb009dcSAndroid Build Coastguard Worker } else {
241*8fb009dcSAndroid Build Coastguard Worker out->tv_sec = ret.tv_sec;
242*8fb009dcSAndroid Build Coastguard Worker }
243*8fb009dcSAndroid Build Coastguard Worker
244*8fb009dcSAndroid Build Coastguard Worker out->tv_usec = ret.tv_usec;
245*8fb009dcSAndroid Build Coastguard Worker return 1;
246*8fb009dcSAndroid Build Coastguard Worker }
247*8fb009dcSAndroid Build Coastguard Worker
DTLSv1_handle_timeout(SSL * ssl)248*8fb009dcSAndroid Build Coastguard Worker int DTLSv1_handle_timeout(SSL *ssl) {
249*8fb009dcSAndroid Build Coastguard Worker ssl_reset_error_state(ssl);
250*8fb009dcSAndroid Build Coastguard Worker
251*8fb009dcSAndroid Build Coastguard Worker if (!SSL_is_dtls(ssl)) {
252*8fb009dcSAndroid Build Coastguard Worker OPENSSL_PUT_ERROR(SSL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
253*8fb009dcSAndroid Build Coastguard Worker return -1;
254*8fb009dcSAndroid Build Coastguard Worker }
255*8fb009dcSAndroid Build Coastguard Worker
256*8fb009dcSAndroid Build Coastguard Worker // If no timer is expired, don't do anything.
257*8fb009dcSAndroid Build Coastguard Worker if (!dtls1_is_timer_expired(ssl)) {
258*8fb009dcSAndroid Build Coastguard Worker return 0;
259*8fb009dcSAndroid Build Coastguard Worker }
260*8fb009dcSAndroid Build Coastguard Worker
261*8fb009dcSAndroid Build Coastguard Worker if (!dtls1_check_timeout_num(ssl)) {
262*8fb009dcSAndroid Build Coastguard Worker return -1;
263*8fb009dcSAndroid Build Coastguard Worker }
264*8fb009dcSAndroid Build Coastguard Worker
265*8fb009dcSAndroid Build Coastguard Worker dtls1_double_timeout(ssl);
266*8fb009dcSAndroid Build Coastguard Worker dtls1_start_timer(ssl);
267*8fb009dcSAndroid Build Coastguard Worker return dtls1_retransmit_outgoing_messages(ssl);
268*8fb009dcSAndroid Build Coastguard Worker }
269