diff options
author | Matt Caswell <matt@openssl.org> | 2017-04-21 16:56:06 +0100 |
---|---|---|
committer | Matt Caswell <matt@openssl.org> | 2017-04-25 14:04:13 +0100 |
commit | b651a05d261530923c4d1f8f464a91c50602d3ea (patch) | |
tree | 61bd6950c6f88e1da6a4319e45cdaa4d0b472bb1 /crypto | |
parent | 22ae579bea93c0a426bacb764783e0e2cf35c14c (diff) |
Fix problem with SCTP close_notify alerts
In SCTP the code was only allowing a send of a close_notify alert if the
socket is dry. If the socket isn't dry then it was attempting to save away
the close_notify alert to resend later when it is dry and then it returned
success. However because the application then thinks that the close_notify
alert has been successfully sent it never re-enters the DTLS code to
actually resend the alert. A much simpler solution is to just fail with a
retryable error in the event that the socket isn't dry. That way the
application knows to retry sending the close_notify alert.
Reviewed-by: Richard Levitte <levitte@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/3287)
Diffstat (limited to 'crypto')
-rw-r--r-- | crypto/bio/bss_dgram.c | 43 |
1 files changed, 6 insertions, 37 deletions
diff --git a/crypto/bio/bss_dgram.c b/crypto/bio/bss_dgram.c index 6dfcc9ba7b..81730abe44 100644 --- a/crypto/bio/bss_dgram.c +++ b/crypto/bio/bss_dgram.c @@ -130,7 +130,6 @@ typedef struct bio_dgram_sctp_data_st { int ccs_sent; int save_shutdown; int peer_auth_tested; - bio_dgram_sctp_save_message saved_message; } bio_dgram_sctp_data; # endif @@ -962,10 +961,8 @@ static int dgram_sctp_free(BIO *a) return 0; data = (bio_dgram_sctp_data *) a->ptr; - if (data != NULL) { - OPENSSL_free(data->saved_message.data); + if (data != NULL) OPENSSL_free(data); - } return (1); } @@ -1067,22 +1064,6 @@ static int dgram_sctp_read(BIO *b, char *out, int outl) struct sctp_event_subscribe event; socklen_t eventsize; # endif - /* - * If a message has been delayed until the socket is dry, - * it can be sent now. - */ - if (data->saved_message.length > 0) { - i = dgram_sctp_write(data->saved_message.bio, - data->saved_message.data, - data->saved_message.length); - if (i < 0) { - ret = i; - break; - } - OPENSSL_free(data->saved_message.data); - data->saved_message.data = NULL; - data->saved_message.length = 0; - } /* disable sender dry event */ # ifdef SCTP_EVENT @@ -1265,27 +1246,15 @@ static int dgram_sctp_write(BIO *b, const char *in, int inl) sinfo = &handshake_sinfo; } - /* - * If we have to send a shutdown alert message and the socket is not dry - * yet, we have to save it and send it as soon as the socket gets dry. - */ + /* We can only send a shutdown alert if the socket is dry */ if (data->save_shutdown) { ret = BIO_dgram_sctp_wait_for_dry(b); - if (ret < 0) { + if (ret < 0) return -1; - } if (ret == 0) { - char *tmp; - data->saved_message.bio = b; - if ((tmp = OPENSSL_malloc(inl)) == NULL) { - BIOerr(BIO_F_DGRAM_SCTP_WRITE, ERR_R_MALLOC_FAILURE); - return -1; - } - OPENSSL_free(data->saved_message.data); - data->saved_message.data = tmp; - memcpy(data->saved_message.data, in, inl); - data->saved_message.length = inl; - return inl; + BIO_clear_retry_flags(b); + BIO_set_retry_write(b); + return -1; } } |