X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=crypto%2Fbio%2Fbss_dgram.c;h=0975856d59aa40bb0fc3e1e4744092f4be324828;hb=03dc77e07bf0f60a39872946405f1188daad3604;hp=5eade50d7c794afc81e61ba8528cd7b576721beb;hpb=fc52ac9028b9492fb086ba35a3352ea46e03ecfc;p=oweals%2Fopenssl.git diff --git a/crypto/bio/bss_dgram.c b/crypto/bio/bss_dgram.c index 5eade50d7c..0975856d59 100644 --- a/crypto/bio/bss_dgram.c +++ b/crypto/bio/bss_dgram.c @@ -169,6 +169,7 @@ typedef struct bio_dgram_data_st { unsigned int mtu; struct timeval next_timeout; struct timeval socket_timeout; + unsigned int peekmode; } bio_dgram_data; # ifndef OPENSSL_NO_SCTP @@ -221,17 +222,11 @@ BIO *BIO_new_dgram(int fd, int close_flag) static int dgram_new(BIO *bi) { - bio_dgram_data *data = NULL; + bio_dgram_data *data = OPENSSL_zalloc(sizeof(*data)); - bi->init = 0; - bi->num = 0; - data = OPENSSL_malloc(sizeof(*data)); if (data == NULL) return 0; - memset(data, 0, sizeof(*data)); bi->ptr = data; - - bi->flags = 0; return (1); } @@ -373,6 +368,7 @@ static int dgram_read(BIO *b, char *out, int outl) { int ret = 0; bio_dgram_data *data = (bio_dgram_data *)b->ptr; + int flags = 0; struct { /* @@ -398,7 +394,9 @@ static int dgram_read(BIO *b, char *out, int outl) clear_socket_error(); memset(&sa.peer, 0, sizeof(sa.peer)); dgram_adjust_rcv_timeout(b); - ret = recvfrom(b->num, out, outl, 0, &sa.peer.sa, (void *)&sa.len); + if (data->peekmode) + flags = MSG_PEEK; + ret = recvfrom(b->num, out, outl, flags, &sa.peer.sa, (void *)&sa.len); if (sizeof(sa.len.i) != sizeof(sa.len.s) && sa.len.i == 0) { OPENSSL_assert(sa.len.s <= sizeof(sa.peer)); sa.len.i = (int)sa.len.s; @@ -514,10 +512,8 @@ static long dgram_ctrl(BIO *b, int cmd, long num, void *ptr) switch (cmd) { case BIO_CTRL_RESET: num = 0; - case BIO_C_FILE_SEEK: ret = 0; break; - case BIO_C_FILE_TELL: case BIO_CTRL_INFO: ret = 0; break; @@ -882,7 +878,7 @@ static long dgram_ctrl(BIO *b, int cmd, long num, void *ptr) perror("setsockopt"); ret = -1; } -# elif defined(OPENSSL_SYS_LINUX) && defined(IP_MTUDISCOVER) +# elif defined(OPENSSL_SYS_LINUX) && defined(IP_MTU_DISCOVER) && defined (IP_PMTUDISC_PROBE) if ((sockopt_val = num ? IP_PMTUDISC_PROBE : IP_PMTUDISC_DONT), (ret = setsockopt(b->num, IPPROTO_IP, IP_MTU_DISCOVER, &sockopt_val, sizeof(sockopt_val))) < 0) { @@ -929,6 +925,9 @@ static long dgram_ctrl(BIO *b, int cmd, long num, void *ptr) case BIO_CTRL_DGRAM_GET_MTU_OVERHEAD: ret = dgram_get_mtu_overhead(data); break; + case BIO_CTRL_DGRAM_SET_PEEK_MODE: + data->peekmode = (unsigned int)num; + break; default: ret = 0; break; @@ -997,16 +996,13 @@ BIO *BIO_new_dgram_sctp(int fd, int close_flag) * connected socket won't use it. */ sockopt_len = (socklen_t) (sizeof(sctp_assoc_t) + 256 * sizeof(uint8_t)); - authchunks = OPENSSL_malloc(sockopt_len); - if (!authchunks) { + authchunks = OPENSSL_zalloc(sockopt_len); + if (authchunks == NULL) { BIO_vfree(bio); return (NULL); } - memset(authchunks, 0, sockopt_len); - ret = - getsockopt(fd, IPPROTO_SCTP, SCTP_LOCAL_AUTH_CHUNKS, authchunks, + ret = getsockopt(fd, IPPROTO_SCTP, SCTP_LOCAL_AUTH_CHUNKS, authchunks, &sockopt_len); - if (ret < 0) { OPENSSL_free(authchunks); BIO_vfree(bio); @@ -1086,10 +1082,9 @@ static int dgram_sctp_new(BIO *bi) bi->init = 0; bi->num = 0; - data = OPENSSL_malloc(sizeof(*data)); + data = OPENSSL_zalloc(sizeof(*data)); if (data == NULL) return 0; - memset(data, 0, sizeof(*data)); # ifdef SCTP_PR_SCTP_NONE data->prinfo.pr_policy = SCTP_PR_SCTP_NONE; # endif @@ -1219,9 +1214,13 @@ static int dgram_sctp_read(BIO *b, char *out, int outl) * it can be sent now. */ if (data->saved_message.length > 0) { - dgram_sctp_write(data->saved_message.bio, + 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; @@ -1335,7 +1334,7 @@ static int dgram_sctp_read(BIO *b, char *out, int outl) optlen = (socklen_t) (sizeof(sctp_assoc_t) + 256 * sizeof(uint8_t)); authchunks = OPENSSL_malloc(optlen); - if (!authchunks) { + if (authchunks == NULL) { BIOerr(BIO_F_DGRAM_SCTP_READ, ERR_R_MALLOC_FAILURE); return -1; } @@ -1366,6 +1365,14 @@ static int dgram_sctp_read(BIO *b, char *out, int outl) return (ret); } +/* + * dgram_sctp_write - send message on SCTP socket + * @b: BIO to write to + * @in: data to send + * @inl: amount of bytes in @in to send + * + * Returns -1 on error or the sent amount of bytes on success + */ static int dgram_sctp_write(BIO *b, const char *in, int inl) { int ret; @@ -1404,18 +1411,24 @@ static int dgram_sctp_write(BIO *b, const char *in, int inl) * 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. */ - if (data->save_shutdown && !BIO_dgram_sctp_wait_for_dry(b)) { - char *tmp; - data->saved_message.bio = b; - if ((tmp = OPENSSL_malloc(inl)) == NULL) { - BIOerr(BIO_F_DGRAM_SCTP_WRITE, ERR_R_MALLOC_FAILURE); + if (data->save_shutdown) { + ret = BIO_dgram_sctp_wait_for_dry(b); + if (ret < 0) { 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; + 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; + } } iov[0].iov_base = (char *)in; @@ -1733,6 +1746,19 @@ int BIO_dgram_sctp_notification_cb(BIO *b, return 0; } +/* + * BIO_dgram_sctp_wait_for_dry - Wait for SCTP SENDER_DRY event + * @b: The BIO to check for the dry event + * + * Wait until the peer confirms all packets have been received, and so that + * our kernel doesn't have anything to send anymore. This is only received by + * the peer's kernel, not the application. + * + * Returns: + * -1 on error + * 0 when not dry yet + * 1 when dry + */ int BIO_dgram_sctp_wait_for_dry(BIO *b) { int is_dry = 0;