summaryrefslogtreecommitdiffstats
path: root/crypto
diff options
context:
space:
mode:
authorMatt Caswell <matt@openssl.org>2017-04-21 16:56:06 +0100
committerMatt Caswell <matt@openssl.org>2017-04-25 14:04:13 +0100
commitb651a05d261530923c4d1f8f464a91c50602d3ea (patch)
tree61bd6950c6f88e1da6a4319e45cdaa4d0b472bb1 /crypto
parent22ae579bea93c0a426bacb764783e0e2cf35c14c (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.c43
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;
}
}