summaryrefslogtreecommitdiffstats
path: root/crypto/bio/bss_dgram.c
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 11:13:39 +0100
commit41b3c9ce2a02195aa7cf74c90b80468354ac708d (patch)
tree35494eaa6ea061272ae5b91f5de361ab4ce5aa3e /crypto/bio/bss_dgram.c
parentaefb925647175a310df73416c9c7253424a65106 (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/3286)
Diffstat (limited to 'crypto/bio/bss_dgram.c')
-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 d3a7b03fba..7ef4281597 100644
--- a/crypto/bio/bss_dgram.c
+++ b/crypto/bio/bss_dgram.c
@@ -135,7 +135,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
@@ -978,10 +977,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);
}
@@ -1083,22 +1080,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
@@ -1281,27 +1262,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;
}
}