xref: /openbsd/lib/libssl/d1_lib.c (revision c9675a23)
1*c9675a23Stb /* $OpenBSD: d1_lib.c,v 1.64 2022/11/26 16:08:55 tb Exp $ */
25650a0e1Sdjm /*
35650a0e1Sdjm  * DTLS implementation written by Nagendra Modadugu
45650a0e1Sdjm  * (nagendra@cs.stanford.edu) for the OpenSSL project 2005.
55650a0e1Sdjm  */
65650a0e1Sdjm /* ====================================================================
75650a0e1Sdjm  * Copyright (c) 1999-2005 The OpenSSL Project.  All rights reserved.
85650a0e1Sdjm  *
95650a0e1Sdjm  * Redistribution and use in source and binary forms, with or without
105650a0e1Sdjm  * modification, are permitted provided that the following conditions
115650a0e1Sdjm  * are met:
125650a0e1Sdjm  *
135650a0e1Sdjm  * 1. Redistributions of source code must retain the above copyright
145650a0e1Sdjm  *    notice, this list of conditions and the following disclaimer.
155650a0e1Sdjm  *
165650a0e1Sdjm  * 2. Redistributions in binary form must reproduce the above copyright
175650a0e1Sdjm  *    notice, this list of conditions and the following disclaimer in
185650a0e1Sdjm  *    the documentation and/or other materials provided with the
195650a0e1Sdjm  *    distribution.
205650a0e1Sdjm  *
215650a0e1Sdjm  * 3. All advertising materials mentioning features or use of this
225650a0e1Sdjm  *    software must display the following acknowledgment:
235650a0e1Sdjm  *    "This product includes software developed by the OpenSSL Project
245650a0e1Sdjm  *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
255650a0e1Sdjm  *
265650a0e1Sdjm  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
275650a0e1Sdjm  *    endorse or promote products derived from this software without
285650a0e1Sdjm  *    prior written permission. For written permission, please contact
295650a0e1Sdjm  *    openssl-core@OpenSSL.org.
305650a0e1Sdjm  *
315650a0e1Sdjm  * 5. Products derived from this software may not be called "OpenSSL"
325650a0e1Sdjm  *    nor may "OpenSSL" appear in their names without prior written
335650a0e1Sdjm  *    permission of the OpenSSL Project.
345650a0e1Sdjm  *
355650a0e1Sdjm  * 6. Redistributions of any form whatsoever must retain the following
365650a0e1Sdjm  *    acknowledgment:
375650a0e1Sdjm  *    "This product includes software developed by the OpenSSL Project
385650a0e1Sdjm  *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
395650a0e1Sdjm  *
405650a0e1Sdjm  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
415650a0e1Sdjm  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
425650a0e1Sdjm  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
435650a0e1Sdjm  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
445650a0e1Sdjm  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
455650a0e1Sdjm  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
465650a0e1Sdjm  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
475650a0e1Sdjm  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
485650a0e1Sdjm  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
495650a0e1Sdjm  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
505650a0e1Sdjm  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
515650a0e1Sdjm  * OF THE POSSIBILITY OF SUCH DAMAGE.
525650a0e1Sdjm  * ====================================================================
535650a0e1Sdjm  *
545650a0e1Sdjm  * This product includes cryptographic software written by Eric Young
555650a0e1Sdjm  * (eay@cryptsoft.com).  This product includes software written by Tim
565650a0e1Sdjm  * Hudson (tjh@cryptsoft.com).
575650a0e1Sdjm  *
585650a0e1Sdjm  */
595650a0e1Sdjm 
60c6f33ed0Sderaadt #include <sys/types.h>
610579501cSmpi #include <sys/socket.h>
62217902d8Sbcook #include <sys/time.h>
630579501cSmpi 
640579501cSmpi #include <netinet/in.h>
650579501cSmpi 
665650a0e1Sdjm #include <stdio.h>
67c5899dbcSjsing 
685650a0e1Sdjm #include <openssl/objects.h>
6946859c4aSjsing 
70*c9675a23Stb #include "dtls_local.h"
7146859c4aSjsing #include "pqueue.h"
72*c9675a23Stb #include "ssl_local.h"
735650a0e1Sdjm 
7455a1a82cSjsing void dtls1_hm_fragment_free(hm_fragment *frag);
7555a1a82cSjsing 
76fca6a006Sguenther static int dtls1_listen(SSL *s, struct sockaddr *client);
775650a0e1Sdjm 
784a47b859Sjsing int
dtls1_new(SSL * s)794a47b859Sjsing dtls1_new(SSL *s)
805650a0e1Sdjm {
814a47b859Sjsing 	if (!ssl3_new(s))
829f8f562aSjsing 		goto err;
835650a0e1Sdjm 
849f8f562aSjsing 	if ((s->d1 = calloc(1, sizeof(*s->d1))) == NULL)
859f8f562aSjsing 		goto err;
865650a0e1Sdjm 
87f19d9718Sjsing 	if ((s->d1->unprocessed_rcds.q = pqueue_new()) == NULL)
889f8f562aSjsing 		goto err;
89f19d9718Sjsing 	if ((s->d1->buffered_messages = pqueue_new()) == NULL)
909f8f562aSjsing 		goto err;
919f8f562aSjsing 	if ((s->d1->sent_messages = pqueue_new()) == NULL)
929f8f562aSjsing 		goto err;
93f19d9718Sjsing 	if ((s->d1->buffered_app_data.q = pqueue_new()) == NULL)
949f8f562aSjsing 		goto err;
955650a0e1Sdjm 
969f8f562aSjsing 	if (s->server)
97f19d9718Sjsing 		s->d1->cookie_len = sizeof(s->d1->cookie);
985650a0e1Sdjm 
996ba40c14Sjsing 	s->method->ssl_clear(s);
1005650a0e1Sdjm 	return (1);
1019f8f562aSjsing 
1029f8f562aSjsing  err:
1039f8f562aSjsing 	dtls1_free(s);
1049f8f562aSjsing 	return (0);
1055650a0e1Sdjm }
1065650a0e1Sdjm 
1074a47b859Sjsing static void
dtls1_drain_rcontents(pqueue queue)108ee4250f6Sjsing dtls1_drain_rcontents(pqueue queue)
109ee4250f6Sjsing {
110ee4250f6Sjsing 	DTLS1_RCONTENT_DATA_INTERNAL *rdata;
111ee4250f6Sjsing 	pitem *item;
112ee4250f6Sjsing 
113ee4250f6Sjsing 	if (queue == NULL)
114ee4250f6Sjsing 		return;
115ee4250f6Sjsing 
116ee4250f6Sjsing 	while ((item = pqueue_pop(queue)) != NULL) {
117ee4250f6Sjsing 		rdata = (DTLS1_RCONTENT_DATA_INTERNAL *)item->data;
118ee4250f6Sjsing 		tls_content_free(rdata->rcontent);
119ee4250f6Sjsing 		free(item->data);
120ee4250f6Sjsing 		pitem_free(item);
121ee4250f6Sjsing 	}
122ee4250f6Sjsing }
123ee4250f6Sjsing 
124ee4250f6Sjsing static void
dtls1_drain_records(pqueue queue)1259215d666Stb dtls1_drain_records(pqueue queue)
1265650a0e1Sdjm {
1279215d666Stb 	pitem *item;
1286182911eSjsing 	DTLS1_RECORD_DATA_INTERNAL *rdata;
1295650a0e1Sdjm 
1309215d666Stb 	if (queue == NULL)
1319215d666Stb 		return;
1329215d666Stb 
1339215d666Stb 	while ((item = pqueue_pop(queue)) != NULL) {
1346182911eSjsing 		rdata = (DTLS1_RECORD_DATA_INTERNAL *)item->data;
135435f94b7Sjsing 		ssl3_release_buffer(&rdata->rbuf);
1366f3a6cb1Sbeck 		free(item->data);
1375650a0e1Sdjm 		pitem_free(item);
1385650a0e1Sdjm 	}
1395650a0e1Sdjm }
1405650a0e1Sdjm 
1419215d666Stb static void
dtls1_drain_fragments(pqueue queue)1429215d666Stb dtls1_drain_fragments(pqueue queue)
1439215d666Stb {
1449215d666Stb 	pitem *item;
1459215d666Stb 
1469215d666Stb 	if (queue == NULL)
1479215d666Stb 		return;
1489215d666Stb 
1499215d666Stb 	while ((item = pqueue_pop(queue)) != NULL) {
15055a1a82cSjsing 		dtls1_hm_fragment_free(item->data);
1515650a0e1Sdjm 		pitem_free(item);
1525650a0e1Sdjm 	}
1535650a0e1Sdjm }
1540579501cSmpi 
1559215d666Stb static void
dtls1_clear_queues(SSL * s)1569215d666Stb dtls1_clear_queues(SSL *s)
1579215d666Stb {
158f19d9718Sjsing 	dtls1_drain_records(s->d1->unprocessed_rcds.q);
159f19d9718Sjsing 	dtls1_drain_fragments(s->d1->buffered_messages);
1609215d666Stb 	dtls1_drain_fragments(s->d1->sent_messages);
161ee4250f6Sjsing 	dtls1_drain_rcontents(s->d1->buffered_app_data.q);
1620579501cSmpi }
1630579501cSmpi 
1644a47b859Sjsing void
dtls1_free(SSL * s)1654a47b859Sjsing dtls1_free(SSL *s)
1660579501cSmpi {
167dd39d9ddSdoug 	if (s == NULL)
168dd39d9ddSdoug 		return;
169dd39d9ddSdoug 
1700579501cSmpi 	ssl3_free(s);
1710579501cSmpi 
172ea21f82aStb 	if (s->d1 == NULL)
173ea21f82aStb 		return;
174ea21f82aStb 
1750579501cSmpi 	dtls1_clear_queues(s);
1760579501cSmpi 
177f19d9718Sjsing 	pqueue_free(s->d1->unprocessed_rcds.q);
178f19d9718Sjsing 	pqueue_free(s->d1->buffered_messages);
1799a0dbe41Sdjm 	pqueue_free(s->d1->sent_messages);
180f19d9718Sjsing 	pqueue_free(s->d1->buffered_app_data.q);
1815650a0e1Sdjm 
1828f2be08bSjsing 	freezero(s->d1, sizeof(*s->d1));
1830579501cSmpi 	s->d1 = NULL;
1845650a0e1Sdjm }
1855650a0e1Sdjm 
1864a47b859Sjsing void
dtls1_clear(SSL * s)1874a47b859Sjsing dtls1_clear(SSL *s)
1885650a0e1Sdjm {
1890579501cSmpi 	pqueue unprocessed_rcds;
1900579501cSmpi 	pqueue buffered_messages;
1910579501cSmpi 	pqueue sent_messages;
1920579501cSmpi 	pqueue buffered_app_data;
1930579501cSmpi 	unsigned int mtu;
1940579501cSmpi 
1954a47b859Sjsing 	if (s->d1) {
196f19d9718Sjsing 		unprocessed_rcds = s->d1->unprocessed_rcds.q;
197f19d9718Sjsing 		buffered_messages = s->d1->buffered_messages;
1980579501cSmpi 		sent_messages = s->d1->sent_messages;
199f19d9718Sjsing 		buffered_app_data = s->d1->buffered_app_data.q;
200f19d9718Sjsing 		mtu = s->d1->mtu;
2010579501cSmpi 
2020579501cSmpi 		dtls1_clear_queues(s);
2030579501cSmpi 
2048462f404Sjsing 		memset(s->d1, 0, sizeof(*s->d1));
2050579501cSmpi 
206f19d9718Sjsing 		s->d1->unprocessed_rcds.epoch =
2076f7f653bSjsing 		    tls12_record_layer_read_epoch(s->rl) + 1;
20812a1eb2dSjsing 
2094a47b859Sjsing 		if (s->server) {
210f19d9718Sjsing 			s->d1->cookie_len = sizeof(s->d1->cookie);
2110579501cSmpi 		}
2120579501cSmpi 
2134a47b859Sjsing 		if (SSL_get_options(s) & SSL_OP_NO_QUERY_MTU) {
214f19d9718Sjsing 			s->d1->mtu = mtu;
2150579501cSmpi 		}
2160579501cSmpi 
217f19d9718Sjsing 		s->d1->unprocessed_rcds.q = unprocessed_rcds;
218f19d9718Sjsing 		s->d1->buffered_messages = buffered_messages;
2190579501cSmpi 		s->d1->sent_messages = sent_messages;
220f19d9718Sjsing 		s->d1->buffered_app_data.q = buffered_app_data;
2210579501cSmpi 	}
2220579501cSmpi 
2235650a0e1Sdjm 	ssl3_clear(s);
2247489cb3dSjsing 
2255650a0e1Sdjm 	s->version = DTLS1_VERSION;
2265650a0e1Sdjm }
2275650a0e1Sdjm 
2284a47b859Sjsing long
dtls1_ctrl(SSL * s,int cmd,long larg,void * parg)2294a47b859Sjsing dtls1_ctrl(SSL *s, int cmd, long larg, void *parg)
2300579501cSmpi {
2310579501cSmpi 	int ret = 0;
2320579501cSmpi 
2334a47b859Sjsing 	switch (cmd) {
2340579501cSmpi 	case DTLS_CTRL_GET_TIMEOUT:
2354a47b859Sjsing 		if (dtls1_get_timeout(s, (struct timeval*) parg) != NULL) {
2360579501cSmpi 			ret = 1;
2370579501cSmpi 		}
2380579501cSmpi 		break;
2390579501cSmpi 	case DTLS_CTRL_HANDLE_TIMEOUT:
2400579501cSmpi 		ret = dtls1_handle_timeout(s);
2410579501cSmpi 		break;
2420579501cSmpi 	case DTLS_CTRL_LISTEN:
2430579501cSmpi 		ret = dtls1_listen(s, parg);
2440579501cSmpi 		break;
2450579501cSmpi 
2460579501cSmpi 	default:
2470579501cSmpi 		ret = ssl3_ctrl(s, cmd, larg, parg);
2480579501cSmpi 		break;
2490579501cSmpi 	}
2500579501cSmpi 	return (ret);
2510579501cSmpi }
2520579501cSmpi 
2535650a0e1Sdjm /*
2545650a0e1Sdjm  * As it's impossible to use stream ciphers in "datagram" mode, this
2555650a0e1Sdjm  * simple filter is designed to disengage them in DTLS. Unfortunately
2565650a0e1Sdjm  * there is no universal way to identify stream SSL_CIPHER, so we have
2575650a0e1Sdjm  * to explicitly list their SSL_* codes. Currently RC4 is the only one
2585650a0e1Sdjm  * available, but if new ones emerge, they will have to be added...
2595650a0e1Sdjm  */
260dbea66cdSguenther const SSL_CIPHER *
dtls1_get_cipher(unsigned int u)261dbea66cdSguenther dtls1_get_cipher(unsigned int u)
2625650a0e1Sdjm {
26335328106Sjsing 	const SSL_CIPHER *cipher;
2645650a0e1Sdjm 
26535328106Sjsing 	if ((cipher = ssl3_get_cipher(u)) == NULL)
2665650a0e1Sdjm 		return NULL;
2675650a0e1Sdjm 
26835328106Sjsing 	if (cipher->algorithm_enc == SSL_RC4)
26935328106Sjsing 		return NULL;
27035328106Sjsing 
27135328106Sjsing 	return cipher;
2725650a0e1Sdjm }
2730579501cSmpi 
2744a47b859Sjsing void
dtls1_start_timer(SSL * s)2754a47b859Sjsing dtls1_start_timer(SSL *s)
2760579501cSmpi {
2770579501cSmpi 
2780579501cSmpi 	/* If timer is not set, initialize duration with 1 second */
2794a47b859Sjsing 	if (s->d1->next_timeout.tv_sec == 0 && s->d1->next_timeout.tv_usec == 0) {
2800579501cSmpi 		s->d1->timeout_duration = 1;
2810579501cSmpi 	}
2820579501cSmpi 
2830579501cSmpi 	/* Set timeout to current time */
28433e311cfSderaadt 	gettimeofday(&(s->d1->next_timeout), NULL);
2850579501cSmpi 
2860579501cSmpi 	/* Add duration to current time */
2870579501cSmpi 	s->d1->next_timeout.tv_sec += s->d1->timeout_duration;
288b09c1e06Sderaadt 	BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT, 0,
289f7271532Sbeck 	    &s->d1->next_timeout);
2900579501cSmpi }
2910579501cSmpi 
2924a47b859Sjsing struct timeval*
dtls1_get_timeout(SSL * s,struct timeval * timeleft)293b09c1e06Sderaadt dtls1_get_timeout(SSL *s, struct timeval* timeleft)
294b09c1e06Sderaadt {
2950579501cSmpi 	struct timeval timenow;
2960579501cSmpi 
2970579501cSmpi 	/* If no timeout is set, just return NULL */
2984a47b859Sjsing 	if (s->d1->next_timeout.tv_sec == 0 && s->d1->next_timeout.tv_usec == 0) {
2990579501cSmpi 		return NULL;
3000579501cSmpi 	}
3010579501cSmpi 
3020579501cSmpi 	/* Get current time */
30333e311cfSderaadt 	gettimeofday(&timenow, NULL);
3040579501cSmpi 
3050579501cSmpi 	/* If timer already expired, set remaining time to 0 */
3060579501cSmpi 	if (s->d1->next_timeout.tv_sec < timenow.tv_sec ||
3070579501cSmpi 	    (s->d1->next_timeout.tv_sec == timenow.tv_sec &&
3084a47b859Sjsing 	     s->d1->next_timeout.tv_usec <= timenow.tv_usec)) {
3090579501cSmpi 		memset(timeleft, 0, sizeof(struct timeval));
3100579501cSmpi 		return timeleft;
3110579501cSmpi 	}
3120579501cSmpi 
3130579501cSmpi 	/* Calculate time left until timer expires */
3140579501cSmpi 	memcpy(timeleft, &(s->d1->next_timeout), sizeof(struct timeval));
3150579501cSmpi 	timeleft->tv_sec -= timenow.tv_sec;
3160579501cSmpi 	timeleft->tv_usec -= timenow.tv_usec;
3174a47b859Sjsing 	if (timeleft->tv_usec < 0) {
3180579501cSmpi 		timeleft->tv_sec--;
3190579501cSmpi 		timeleft->tv_usec += 1000000;
3200579501cSmpi 	}
3210579501cSmpi 
3220579501cSmpi 	/* If remaining time is less than 15 ms, set it to 0
3230579501cSmpi 	 * to prevent issues because of small devergences with
3240579501cSmpi 	 * socket timeouts.
3250579501cSmpi 	 */
3264a47b859Sjsing 	if (timeleft->tv_sec == 0 && timeleft->tv_usec < 15000) {
3270579501cSmpi 		memset(timeleft, 0, sizeof(struct timeval));
3280579501cSmpi 	}
3290579501cSmpi 
3300579501cSmpi 
3310579501cSmpi 	return timeleft;
3320579501cSmpi }
3330579501cSmpi 
3344a47b859Sjsing int
dtls1_is_timer_expired(SSL * s)3354a47b859Sjsing dtls1_is_timer_expired(SSL *s)
3360579501cSmpi {
3370579501cSmpi 	struct timeval timeleft;
3380579501cSmpi 
3390579501cSmpi 	/* Get time left until timeout, return false if no timer running */
3404a47b859Sjsing 	if (dtls1_get_timeout(s, &timeleft) == NULL) {
3410579501cSmpi 		return 0;
3420579501cSmpi 	}
3430579501cSmpi 
3440579501cSmpi 	/* Return false if timer is not expired yet */
3454a47b859Sjsing 	if (timeleft.tv_sec > 0 || timeleft.tv_usec > 0) {
3460579501cSmpi 		return 0;
3470579501cSmpi 	}
3480579501cSmpi 
3490579501cSmpi 	/* Timer expired, so return true */
3500579501cSmpi 	return 1;
3510579501cSmpi }
3520579501cSmpi 
3534a47b859Sjsing void
dtls1_double_timeout(SSL * s)3544a47b859Sjsing dtls1_double_timeout(SSL *s)
3550579501cSmpi {
3560579501cSmpi 	s->d1->timeout_duration *= 2;
3570579501cSmpi 	if (s->d1->timeout_duration > 60)
3580579501cSmpi 		s->d1->timeout_duration = 60;
3590579501cSmpi 	dtls1_start_timer(s);
3600579501cSmpi }
3610579501cSmpi 
3624a47b859Sjsing void
dtls1_stop_timer(SSL * s)3634a47b859Sjsing dtls1_stop_timer(SSL *s)
3640579501cSmpi {
3650579501cSmpi 	/* Reset everything */
366f19d9718Sjsing 	memset(&(s->d1->timeout), 0, sizeof(struct dtls1_timeout_st));
3670579501cSmpi 	memset(&(s->d1->next_timeout), 0, sizeof(struct timeval));
3680579501cSmpi 	s->d1->timeout_duration = 1;
369b09c1e06Sderaadt 	BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT, 0,
370b09c1e06Sderaadt 	    &(s->d1->next_timeout));
3710579501cSmpi 	/* Clear retransmission buffer */
3720579501cSmpi 	dtls1_clear_record_buffer(s);
3730579501cSmpi }
3740579501cSmpi 
3754a47b859Sjsing int
dtls1_check_timeout_num(SSL * s)3764a47b859Sjsing dtls1_check_timeout_num(SSL *s)
3770579501cSmpi {
378f19d9718Sjsing 	s->d1->timeout.num_alerts++;
3790579501cSmpi 
3800579501cSmpi 	/* Reduce MTU after 2 unsuccessful retransmissions */
381f19d9718Sjsing 	if (s->d1->timeout.num_alerts > 2) {
382f19d9718Sjsing 		s->d1->mtu = BIO_ctrl(SSL_get_wbio(s),
383b09c1e06Sderaadt 		    BIO_CTRL_DGRAM_GET_FALLBACK_MTU, 0, NULL);
3844a47b859Sjsing 
3850579501cSmpi 	}
3860579501cSmpi 
387f19d9718Sjsing 	if (s->d1->timeout.num_alerts > DTLS1_TMO_ALERT_COUNT) {
3880579501cSmpi 		/* fail the connection, enough alerts have been sent */
389c9d7abb7Sbeck 		SSLerror(s, SSL_R_READ_TIMEOUT_EXPIRED);
3900579501cSmpi 		return -1;
3910579501cSmpi 	}
3920579501cSmpi 
3930579501cSmpi 	return 0;
3940579501cSmpi }
3950579501cSmpi 
3964a47b859Sjsing int
dtls1_handle_timeout(SSL * s)3974a47b859Sjsing dtls1_handle_timeout(SSL *s)
3980579501cSmpi {
3990579501cSmpi 	/* if no timer is expired, don't do anything */
4004a47b859Sjsing 	if (!dtls1_is_timer_expired(s)) {
4010579501cSmpi 		return 0;
4020579501cSmpi 	}
4030579501cSmpi 
4040579501cSmpi 	dtls1_double_timeout(s);
4050579501cSmpi 
4060579501cSmpi 	if (dtls1_check_timeout_num(s) < 0)
4070579501cSmpi 		return -1;
4080579501cSmpi 
409f19d9718Sjsing 	s->d1->timeout.read_timeouts++;
410f19d9718Sjsing 	if (s->d1->timeout.read_timeouts > DTLS1_TMO_READ_COUNT) {
411f19d9718Sjsing 		s->d1->timeout.read_timeouts = 1;
4120579501cSmpi 	}
4130579501cSmpi 
4140579501cSmpi 	dtls1_start_timer(s);
4150579501cSmpi 	return dtls1_retransmit_buffered_messages(s);
4160579501cSmpi }
4170579501cSmpi 
4184a47b859Sjsing int
dtls1_listen(SSL * s,struct sockaddr * client)4194a47b859Sjsing dtls1_listen(SSL *s, struct sockaddr *client)
4200579501cSmpi {
4210579501cSmpi 	int ret;
4220579501cSmpi 
4233e1f01a5Stedu 	/* Ensure there is no state left over from a previous invocation */
4243e1f01a5Stedu 	SSL_clear(s);
4253e1f01a5Stedu 
4260579501cSmpi 	SSL_set_options(s, SSL_OP_COOKIE_EXCHANGE);
427f19d9718Sjsing 	s->d1->listen = 1;
4280579501cSmpi 
4290579501cSmpi 	ret = SSL_accept(s);
4304a47b859Sjsing 	if (ret <= 0)
4314a47b859Sjsing 		return ret;
4320579501cSmpi 
4330579501cSmpi 	(void)BIO_dgram_get_peer(SSL_get_rbio(s), client);
4340579501cSmpi 	return 1;
4350579501cSmpi }
436