@@ -51,6 +51,14 @@ Possible IO enable options:
5151 * HAVE_HTTP_CLIENT: Enables HTTP client API's default: off
5252 (unless HAVE_OCSP or HAVE_CRL_IO defined)
5353 * HAVE_IO_TIMEOUT: Enables support for connect timeout default: off
54+ *
55+ * DTLS_RECEIVEFROM_NO_TIMEOUT_ON_INVALID_PEER: This flag has effect only if
56+ * ASN_NO_TIME is enabled. If enabled invalid peers messages are ignored
57+ * indefinetely. If not enabled EmbedReceiveFrom will return timeout after
58+ * DTLS_RECEIVEFROM_MAX_INVALID_PEER number of packets from invalid peers. When
59+ * enabled, without a timer, EmbedReceivefrom can't check if the timeout is
60+ * expired and it may never return under a continous flow of invalid packets.
61+ * default: off
5462 */
5563
5664
@@ -59,6 +67,11 @@ Possible IO enable options:
5967 but they'll still need SetCallback xxx() at end of file
6068*/
6169
70+ #if defined(NO_ASN_TIME ) && !defined(DTLS_RECEIVEFROM_NO_TIMEOUT_ON_INVALID_PEER ) \
71+ && !defined(DTLS_RECEIVEFROM_MAX_INVALID_PEER )
72+ #define DTLS_RECEIVEFROM_MAX_INVALID_PEER 10
73+ #endif
74+
6275#if defined(USE_WOLFSSL_IO ) || defined(HAVE_HTTP_CLIENT )
6376
6477/* Translates return codes returned from
@@ -400,6 +413,11 @@ int EmbedReceiveFrom(WOLFSSL *ssl, char *buf, int sz, void *ctx)
400413 SOCKADDR_S lclPeer ;
401414 SOCKADDR_S * peer ;
402415 XSOCKLENT peerSz = 0 ;
416+ #ifndef NO_ASN_TIME
417+ word32 start = 0 ;
418+ #elif !defined(DTLS_RECEIVEFROM_NO_TIMEOUT_ON_INVALID_PEER )
419+ word32 invalidPeerPackets = 0 ;
420+ #endif
403421
404422 WOLFSSL_ENTER ("EmbedReceiveFrom" );
405423
@@ -438,10 +456,26 @@ int EmbedReceiveFrom(WOLFSSL *ssl, char *buf, int sz, void *ctx)
438456 }
439457#endif /* WOLFSSL_DTLS13 */
440458
441- if (!doDtlsTimeout )
442- dtls_timeout = 0 ;
459+ do {
460+
461+ if (!doDtlsTimeout ) {
462+ dtls_timeout = 0 ;
463+ }
464+ else {
465+ #ifndef NO_ASN_TIME
466+ if (start == 0 ) {
467+ start = LowResTimer ();
468+ }
469+ else {
470+ dtls_timeout -= LowResTimer () - start ;
471+ start = LowResTimer ();
472+ if (dtls_timeout < 0 || dtls_timeout > DTLS_TIMEOUT_MAX )
473+ return WOLFSSL_CBIO_ERR_TIMEOUT ;
474+ }
475+ #endif
476+ }
443477
444- if (!wolfSSL_get_using_nonblock (ssl )) {
478+ if (!wolfSSL_get_using_nonblock (ssl )) {
445479 #ifdef USE_WINDOWS_API
446480 DWORD timeout = dtls_timeout * 1000 ;
447481 #ifdef WOLFSSL_DTLS13
@@ -464,87 +498,101 @@ int EmbedReceiveFrom(WOLFSSL *ssl, char *buf, int sz, void *ctx)
464498 #endif /* WOLFSSL_DTLS13 */
465499 timeout .tv_sec = dtls_timeout ;
466500 #endif
467- if (setsockopt (sd , SOL_SOCKET , SO_RCVTIMEO , (char * )& timeout ,
468- sizeof (timeout )) != 0 ) {
501+ if (setsockopt (sd , SOL_SOCKET , SO_RCVTIMEO , (char * )& timeout ,
502+ sizeof (timeout )) != 0 ) {
469503 WOLFSSL_MSG ("setsockopt rcvtimeo failed" );
504+ }
470505 }
471- }
472506#ifndef NO_ASN_TIME
473- else if (IsSCR (ssl )) {
474- if (ssl -> dtls_start_timeout &&
475- LowResTimer () - ssl -> dtls_start_timeout > (word32 )dtls_timeout ) {
476- ssl -> dtls_start_timeout = 0 ;
477- return WOLFSSL_CBIO_ERR_TIMEOUT ;
478- }
479- else if (!ssl -> dtls_start_timeout ) {
480- ssl -> dtls_start_timeout = LowResTimer ();
507+ else if (IsSCR (ssl )) {
508+ if (ssl -> dtls_start_timeout &&
509+ LowResTimer () - ssl -> dtls_start_timeout >
510+ (word32 )dtls_timeout ) {
511+ ssl -> dtls_start_timeout = 0 ;
512+ return WOLFSSL_CBIO_ERR_TIMEOUT ;
513+ }
514+ else if (!ssl -> dtls_start_timeout ) {
515+ ssl -> dtls_start_timeout = LowResTimer ();
516+ }
481517 }
482- }
483518#endif /* !NO_ASN_TIME */
484519
485- recvd = (int )DTLS_RECVFROM_FUNCTION (sd , buf , sz , ssl -> rflags ,
486- (SOCKADDR * )peer , peer != NULL ? & peerSz : NULL );
520+ recvd = (int )DTLS_RECVFROM_FUNCTION (sd , buf , sz , ssl -> rflags ,
521+ (SOCKADDR * )peer , peer != NULL ? & peerSz : NULL );
487522
488- /* From the RECV(2) man page
489- * The returned address is truncated if the buffer provided is too small; in
490- * this case, addrlen will return a value greater than was supplied to the
491- * call.
492- */
493- if (dtlsCtx -> connected ) {
494- /* No need to sanitize the value of peerSz */
495- }
496- else if (dtlsCtx -> userSet ) {
497- /* Truncate peer size */
498- if (peerSz > (XSOCKLENT )sizeof (lclPeer ))
499- peerSz = (XSOCKLENT )sizeof (lclPeer );
500- }
501- else {
502- /* Truncate peer size */
503- if (peerSz > (XSOCKLENT )dtlsCtx -> peer .bufSz )
504- peerSz = (XSOCKLENT )dtlsCtx -> peer .bufSz ;
505- }
523+ /* From the RECV(2) man page
524+ * The returned address is truncated if the buffer provided is too
525+ * small; in this case, addrlen will return a value greater than was
526+ * supplied to the call.
527+ */
528+ if (dtlsCtx -> connected ) {
529+ /* No need to sanitize the value of peerSz */
530+ }
531+ else if (dtlsCtx -> userSet ) {
532+ /* Truncate peer size */
533+ if (peerSz > (XSOCKLENT )sizeof (lclPeer ))
534+ peerSz = (XSOCKLENT )sizeof (lclPeer );
535+ }
536+ else {
537+ /* Truncate peer size */
538+ if (peerSz > (XSOCKLENT )dtlsCtx -> peer .bufSz )
539+ peerSz = (XSOCKLENT )dtlsCtx -> peer .bufSz ;
540+ }
506541
507- recvd = TranslateReturnCode (recvd , sd );
542+ recvd = TranslateReturnCode (recvd , sd );
508543
509- if (recvd < 0 ) {
510- WOLFSSL_MSG ("Embed Receive From error" );
511- recvd = TranslateIoError (recvd );
512- if (recvd == WOLFSSL_CBIO_ERR_WANT_READ &&
513- !wolfSSL_dtls_get_using_nonblock (ssl )) {
514- recvd = WOLFSSL_CBIO_ERR_TIMEOUT ;
544+ if (recvd < 0 ) {
545+ WOLFSSL_MSG ("Embed Receive From error" );
546+ recvd = TranslateIoError (recvd );
547+ if (recvd == WOLFSSL_CBIO_ERR_WANT_READ &&
548+ !wolfSSL_dtls_get_using_nonblock (ssl )) {
549+ recvd = WOLFSSL_CBIO_ERR_TIMEOUT ;
550+ }
551+ return recvd ;
515552 }
516- return recvd ;
517- }
518- else if (recvd == 0 ) {
519- if (!isDGramSock (sd )) {
520- /* Closed TCP connection */
521- recvd = WOLFSSL_CBIO_ERR_CONN_CLOSE ;
553+ else if (recvd == 0 ) {
554+ if (!isDGramSock (sd )) {
555+ /* Closed TCP connection */
556+ recvd = WOLFSSL_CBIO_ERR_CONN_CLOSE ;
557+ }
558+ else {
559+ WOLFSSL_MSG ("Ignoring 0-length datagram" );
560+ continue ;
561+ }
562+ return recvd ;
522563 }
523- else {
524- WOLFSSL_MSG ("Ignoring 0-length datagram" );
564+ else if (dtlsCtx -> connected ) {
565+ /* Nothing to do */
566+ }
567+ else if (dtlsCtx -> userSet ) {
568+ /* Check we received the packet from the correct peer */
569+ if (dtlsCtx -> peer .sz > 0 &&
570+ (peerSz != (XSOCKLENT )dtlsCtx -> peer .sz ||
571+ !sockAddrEqual (peer , peerSz , (SOCKADDR_S * )dtlsCtx -> peer .sa ,
572+ dtlsCtx -> peer .sz ))) {
573+ WOLFSSL_MSG (" Ignored packet from invalid peer" );
574+ #if defined(NO_ASN_TIME ) && \
575+ !defined(DTLS_RECEIVEFROM_NO_TIMEOUT_ON_INVALID_PEER )
576+ if (doDtlsTimeout ) {
577+ invalidPeerPackets ++ ;
578+ if (invalidPeerPackets > DTLS_RECEIVEFROM_MAX_INVALID_PEER )
579+ return wolfSSL_dtls_get_using_nonblock (ssl )
580+ ? WOLFSSL_CBIO_ERR_WANT_READ
581+ : WOLFSSL_CBIO_ERR_TIMEOUT ;
582+ }
583+ #endif /* NO_ASN_TIME && !DTLS_RECEIVEFROM_NO_TIMEOUT_ON_INVALID_PEER */
584+ continue ;
585+ }
525586 }
526- return recvd ;
527- }
528- else if (dtlsCtx -> connected ) {
529- /* Nothing to do */
530- }
531- else if (dtlsCtx -> userSet ) {
532- /* Check we received the packet from the correct peer */
533- if (dtlsCtx -> peer .sz > 0 &&
534- (peerSz != (XSOCKLENT )dtlsCtx -> peer .sz ||
535- !sockAddrEqual (peer , peerSz , (SOCKADDR_S * )dtlsCtx -> peer .sa ,
536- dtlsCtx -> peer .sz ))) {
537- WOLFSSL_MSG (" Ignored packet from invalid peer" );
538- return WOLFSSL_CBIO_ERR_WANT_READ ;
587+ else {
588+ /* Store size of saved address */
589+ dtlsCtx -> peer .sz = peerSz ;
539590 }
540- }
541- else {
542- /* Store size of saved address */
543- dtlsCtx -> peer .sz = peerSz ;
544- }
545591#ifndef NO_ASN_TIME
546- ssl -> dtls_start_timeout = 0 ;
592+ ssl -> dtls_start_timeout = 0 ;
547593#endif /* !NO_ASN_TIME */
594+ break ;
595+ } while (1 );
548596
549597 return recvd ;
550598}
0 commit comments