X-Git-Url: https://git.openssl.org/gitweb/?p=openssl.git;a=blobdiff_plain;f=ssl%2Fd1_pkt.c;h=d82e0d58273357e5c0b0a5abe7330422b1ec7787;hp=d66ecf5c77c3e3ada8bac1364c118ee2258552af;hb=c103c7e266145dc922115a2c3079776bb8216939;hpb=9e9858d1cf28e39cfd214b5c508188d5016728fd diff --git a/ssl/d1_pkt.c b/ssl/d1_pkt.c index d66ecf5c77..d82e0d5827 100644 --- a/ssl/d1_pkt.c +++ b/ssl/d1_pkt.c @@ -183,13 +183,6 @@ static int satsub64be(const unsigned char *v1, const unsigned char *v2) static int have_handshake_fragment(SSL *s, int type, unsigned char *buf, int len, int peek); -static int dtls1_record_replay_check(SSL *s, DTLS1_BITMAP *bitmap); -static void dtls1_record_bitmap_update(SSL *s, DTLS1_BITMAP *bitmap); -static DTLS1_BITMAP *dtls1_get_bitmap(SSL *s, SSL3_RECORD *rr, - unsigned int *is_next_epoch); -static int dtls1_buffer_record(SSL *s, record_pqueue *q, - unsigned char *priority); -static int dtls1_process_record(SSL *s); /* copy buffered record into SSL structure */ static int dtls1_copy_record(SSL *s, pitem *item) @@ -198,13 +191,14 @@ static int dtls1_copy_record(SSL *s, pitem *item) rdata = (DTLS1_RECORD_DATA *)item->data; - if (s->s3->rbuf.buf != NULL) - OPENSSL_free(s->s3->rbuf.buf); + SSL3_BUFFER_release(RECORD_LAYER_get_rbuf(&s->rlayer)); s->packet = rdata->packet; s->packet_length = rdata->packet_length; - memcpy(&(s->s3->rbuf), &(rdata->rbuf), sizeof(SSL3_BUFFER)); - memcpy(&(s->s3->rrec), &(rdata->rrec), sizeof(SSL3_RECORD)); + memcpy(RECORD_LAYER_get_rbuf(&s->rlayer), &(rdata->rbuf), + sizeof(SSL3_BUFFER)); + memcpy(RECORD_LAYER_get_rrec(&s->rlayer), &(rdata->rrec), + sizeof(SSL3_RECORD)); /* Set proper sequence number for mac calculation */ memcpy(&(s->s3->read_sequence[2]), &(rdata->packet[5]), 6); @@ -212,7 +206,7 @@ static int dtls1_copy_record(SSL *s, pitem *item) return (1); } -static int +int dtls1_buffer_record(SSL *s, record_pqueue *queue, unsigned char *priority) { DTLS1_RECORD_DATA *rdata; @@ -231,13 +225,15 @@ dtls1_buffer_record(SSL *s, record_pqueue *queue, unsigned char *priority) pitem_free(item); SSLerr(SSL_F_DTLS1_BUFFER_RECORD, ERR_R_INTERNAL_ERROR); - return (0); + return -1; } rdata->packet = s->packet; rdata->packet_length = s->packet_length; - memcpy(&(rdata->rbuf), &(s->s3->rbuf), sizeof(SSL3_BUFFER)); - memcpy(&(rdata->rrec), &(s->s3->rrec), sizeof(SSL3_RECORD)); + memcpy(&(rdata->rbuf), RECORD_LAYER_get_rbuf(&s->rlayer), + sizeof(SSL3_BUFFER)); + memcpy(&(rdata->rrec), RECORD_LAYER_get_rrec(&s->rlayer), + sizeof(SSL3_RECORD)); item->data = rdata; @@ -253,8 +249,8 @@ dtls1_buffer_record(SSL *s, record_pqueue *queue, unsigned char *priority) s->packet = NULL; s->packet_length = 0; - memset(&(s->s3->rbuf), 0, sizeof(SSL3_BUFFER)); - memset(&(s->s3->rrec), 0, sizeof(SSL3_RECORD)); + memset(RECORD_LAYER_get_rbuf(&s->rlayer), 0, sizeof(SSL3_BUFFER)); + memset(RECORD_LAYER_get_rrec(&s->rlayer), 0, sizeof(SSL3_RECORD)); if (!ssl3_setup_buffers(s)) { SSLerr(SSL_F_DTLS1_BUFFER_RECORD, ERR_R_INTERNAL_ERROR); @@ -278,7 +274,7 @@ dtls1_buffer_record(SSL *s, record_pqueue *queue, unsigned char *priority) return (1); } -static int dtls1_retrieve_buffered_record(SSL *s, record_pqueue *queue) +int dtls1_retrieve_buffered_record(SSL *s, record_pqueue *queue) { pitem *item; @@ -303,15 +299,8 @@ static int dtls1_retrieve_buffered_record(SSL *s, record_pqueue *queue) dtls1_retrieve_buffered_record((s), \ &((s)->d1->unprocessed_rcds)) -/* - * retrieve a buffered record that belongs to the current epoch, ie, - * processed - */ -#define dtls1_get_processed_record(s) \ - dtls1_retrieve_buffered_record((s), \ - &((s)->d1->processed_rcds)) -static int dtls1_process_buffered_records(SSL *s) +int dtls1_process_buffered_records(SSL *s) { pitem *item; @@ -327,7 +316,7 @@ static int dtls1_process_buffered_records(SSL *s) if (!dtls1_process_record(s)) return (0); if (dtls1_buffer_record(s, &(s->d1->processed_rcds), - s->s3->rrec.seq_num) < 0) + SSL3_RECORD_get_seq_num(RECORD_LAYER_get_rrec(&s->rlayer))) < 0) return -1; } } @@ -342,350 +331,6 @@ static int dtls1_process_buffered_records(SSL *s) return (1); } -static int dtls1_process_record(SSL *s) -{ - int i, al; - int enc_err; - SSL_SESSION *sess; - SSL3_RECORD *rr; - unsigned int mac_size; - unsigned char md[EVP_MAX_MD_SIZE]; - - rr = &(s->s3->rrec); - sess = s->session; - - /* - * At this point, s->packet_length == SSL3_RT_HEADER_LNGTH + rr->length, - * and we have that many bytes in s->packet - */ - rr->input = &(s->packet[DTLS1_RT_HEADER_LENGTH]); - - /* - * ok, we can now read from 's->packet' data into 'rr' rr->input points - * at rr->length bytes, which need to be copied into rr->data by either - * the decryption or by the decompression When the data is 'copied' into - * the rr->data buffer, rr->input will be pointed at the new buffer - */ - - /* - * We now have - encrypted [ MAC [ compressed [ plain ] ] ] rr->length - * bytes of encrypted compressed stuff. - */ - - /* check is not needed I believe */ - if (rr->length > SSL3_RT_MAX_ENCRYPTED_LENGTH) { - al = SSL_AD_RECORD_OVERFLOW; - SSLerr(SSL_F_DTLS1_PROCESS_RECORD, SSL_R_ENCRYPTED_LENGTH_TOO_LONG); - goto f_err; - } - - /* decrypt in place in 'rr->input' */ - rr->data = rr->input; - rr->orig_len = rr->length; - - enc_err = s->method->ssl3_enc->enc(s, 0); - /*- - * enc_err is: - * 0: (in non-constant time) if the record is publically invalid. - * 1: if the padding is valid - * -1: if the padding is invalid - */ - if (enc_err == 0) { - /* For DTLS we simply ignore bad packets. */ - rr->length = 0; - s->packet_length = 0; - goto err; - } -#ifdef TLS_DEBUG - printf("dec %d\n", rr->length); - { - unsigned int z; - for (z = 0; z < rr->length; z++) - printf("%02X%c", rr->data[z], ((z + 1) % 16) ? ' ' : '\n'); - } - printf("\n"); -#endif - - /* r->length is now the compressed data plus mac */ - if ((sess != NULL) && - (s->enc_read_ctx != NULL) && (EVP_MD_CTX_md(s->read_hash) != NULL)) { - /* s->read_hash != NULL => mac_size != -1 */ - unsigned char *mac = NULL; - unsigned char mac_tmp[EVP_MAX_MD_SIZE]; - mac_size = EVP_MD_CTX_size(s->read_hash); - OPENSSL_assert(mac_size <= EVP_MAX_MD_SIZE); - - /* - * orig_len is the length of the record before any padding was - * removed. This is public information, as is the MAC in use, - * therefore we can safely process the record in a different amount - * of time if it's too short to possibly contain a MAC. - */ - if (rr->orig_len < mac_size || - /* CBC records must have a padding length byte too. */ - (EVP_CIPHER_CTX_mode(s->enc_read_ctx) == EVP_CIPH_CBC_MODE && - rr->orig_len < mac_size + 1)) { - al = SSL_AD_DECODE_ERROR; - SSLerr(SSL_F_DTLS1_PROCESS_RECORD, SSL_R_LENGTH_TOO_SHORT); - goto f_err; - } - - if (EVP_CIPHER_CTX_mode(s->enc_read_ctx) == EVP_CIPH_CBC_MODE) { - /* - * We update the length so that the TLS header bytes can be - * constructed correctly but we need to extract the MAC in - * constant time from within the record, without leaking the - * contents of the padding bytes. - */ - mac = mac_tmp; - ssl3_cbc_copy_mac(mac_tmp, rr, mac_size); - rr->length -= mac_size; - } else { - /* - * In this case there's no padding, so |rec->orig_len| equals - * |rec->length| and we checked that there's enough bytes for - * |mac_size| above. - */ - rr->length -= mac_size; - mac = &rr->data[rr->length]; - } - - i = s->method->ssl3_enc->mac(s, md, 0 /* not send */ ); - if (i < 0 || mac == NULL - || CRYPTO_memcmp(md, mac, (size_t)mac_size) != 0) - enc_err = -1; - if (rr->length > SSL3_RT_MAX_COMPRESSED_LENGTH + mac_size) - enc_err = -1; - } - - if (enc_err < 0) { - /* decryption failed, silently discard message */ - rr->length = 0; - s->packet_length = 0; - goto err; - } - - /* r->length is now just compressed */ - if (s->expand != NULL) { - if (rr->length > SSL3_RT_MAX_COMPRESSED_LENGTH) { - al = SSL_AD_RECORD_OVERFLOW; - SSLerr(SSL_F_DTLS1_PROCESS_RECORD, - SSL_R_COMPRESSED_LENGTH_TOO_LONG); - goto f_err; - } - if (!ssl3_do_uncompress(s)) { - al = SSL_AD_DECOMPRESSION_FAILURE; - SSLerr(SSL_F_DTLS1_PROCESS_RECORD, SSL_R_BAD_DECOMPRESSION); - goto f_err; - } - } - - if (rr->length > SSL3_RT_MAX_PLAIN_LENGTH) { - al = SSL_AD_RECORD_OVERFLOW; - SSLerr(SSL_F_DTLS1_PROCESS_RECORD, SSL_R_DATA_LENGTH_TOO_LONG); - goto f_err; - } - - rr->off = 0; - /*- - * So at this point the following is true - * ssl->s3->rrec.type is the type of record - * ssl->s3->rrec.length == number of bytes in record - * ssl->s3->rrec.off == offset to first valid byte - * ssl->s3->rrec.data == where to take bytes from, increment - * after use :-). - */ - - /* we have pulled in a full packet so zero things */ - s->packet_length = 0; - return (1); - - f_err: - ssl3_send_alert(s, SSL3_AL_FATAL, al); - err: - return (0); -} - -/*- - * Call this to get a new input record. - * It will return <= 0 if more data is needed, normally due to an error - * or non-blocking IO. - * When it finishes, one packet has been decoded and can be found in - * ssl->s3->rrec.type - is the type of record - * ssl->s3->rrec.data, - data - * ssl->s3->rrec.length, - number of bytes - */ -/* used only by dtls1_read_bytes */ -int dtls1_get_record(SSL *s) -{ - int ssl_major, ssl_minor; - int i, n; - SSL3_RECORD *rr; - unsigned char *p = NULL; - unsigned short version; - DTLS1_BITMAP *bitmap; - unsigned int is_next_epoch; - - rr = &(s->s3->rrec); - - /* - * The epoch may have changed. If so, process all the pending records. - * This is a non-blocking operation. - */ - if (dtls1_process_buffered_records(s) < 0) - return -1; - - /* if we're renegotiating, then there may be buffered records */ - if (dtls1_get_processed_record(s)) - return 1; - - /* get something from the wire */ - again: - /* check if we have the header */ - if ((s->rstate != SSL_ST_READ_BODY) || - (s->packet_length < DTLS1_RT_HEADER_LENGTH)) { - n = ssl3_read_n(s, DTLS1_RT_HEADER_LENGTH, s->s3->rbuf.len, 0); - /* read timeout is handled by dtls1_read_bytes */ - if (n <= 0) - return (n); /* error or non-blocking */ - - /* this packet contained a partial record, dump it */ - if (s->packet_length != DTLS1_RT_HEADER_LENGTH) { - s->packet_length = 0; - goto again; - } - - s->rstate = SSL_ST_READ_BODY; - - p = s->packet; - - if (s->msg_callback) - s->msg_callback(0, 0, SSL3_RT_HEADER, p, DTLS1_RT_HEADER_LENGTH, - s, s->msg_callback_arg); - - /* Pull apart the header into the DTLS1_RECORD */ - rr->type = *(p++); - ssl_major = *(p++); - ssl_minor = *(p++); - version = (ssl_major << 8) | ssl_minor; - - /* sequence number is 64 bits, with top 2 bytes = epoch */ - n2s(p, rr->epoch); - - memcpy(&(s->s3->read_sequence[2]), p, 6); - p += 6; - - n2s(p, rr->length); - - /* Lets check version */ - if (!s->first_packet) { - if (version != s->version) { - /* unexpected version, silently discard */ - rr->length = 0; - s->packet_length = 0; - goto again; - } - } - - if ((version & 0xff00) != (s->version & 0xff00)) { - /* wrong version, silently discard record */ - rr->length = 0; - s->packet_length = 0; - goto again; - } - - if (rr->length > SSL3_RT_MAX_ENCRYPTED_LENGTH) { - /* record too long, silently discard it */ - rr->length = 0; - s->packet_length = 0; - goto again; - } - - /* now s->rstate == SSL_ST_READ_BODY */ - } - - /* s->rstate == SSL_ST_READ_BODY, get and decode the data */ - - if (rr->length > s->packet_length - DTLS1_RT_HEADER_LENGTH) { - /* now s->packet_length == DTLS1_RT_HEADER_LENGTH */ - i = rr->length; - n = ssl3_read_n(s, i, i, 1); - /* this packet contained a partial record, dump it */ - if (n != i) { - rr->length = 0; - s->packet_length = 0; - goto again; - } - - /* - * now n == rr->length, and s->packet_length == - * DTLS1_RT_HEADER_LENGTH + rr->length - */ - } - s->rstate = SSL_ST_READ_HEADER; /* set state for later operations */ - - /* match epochs. NULL means the packet is dropped on the floor */ - bitmap = dtls1_get_bitmap(s, rr, &is_next_epoch); - if (bitmap == NULL) { - rr->length = 0; - s->packet_length = 0; /* dump this record */ - goto again; /* get another record */ - } -#ifndef OPENSSL_NO_SCTP - /* Only do replay check if no SCTP bio */ - if (!BIO_dgram_is_sctp(SSL_get_rbio(s))) { -#endif - /* - * Check whether this is a repeat, or aged record. Don't check if - * we're listening and this message is a ClientHello. They can look - * as if they're replayed, since they arrive from different - * connections and would be dropped unnecessarily. - */ - if (!(s->d1->listen && rr->type == SSL3_RT_HANDSHAKE && - s->packet_length > DTLS1_RT_HEADER_LENGTH && - s->packet[DTLS1_RT_HEADER_LENGTH] == SSL3_MT_CLIENT_HELLO) && - !dtls1_record_replay_check(s, bitmap)) { - rr->length = 0; - s->packet_length = 0; /* dump this record */ - goto again; /* get another record */ - } -#ifndef OPENSSL_NO_SCTP - } -#endif - - /* just read a 0 length packet */ - if (rr->length == 0) - goto again; - - /* - * If this record is from the next epoch (either HM or ALERT), and a - * handshake is currently in progress, buffer it since it cannot be - * processed at this time. However, do not buffer anything while - * listening. - */ - if (is_next_epoch) { - if ((SSL_in_init(s) || s->in_handshake) && !s->d1->listen) { - if (dtls1_buffer_record - (s, &(s->d1->unprocessed_rcds), rr->seq_num) < 0) - return -1; - /* Mark receipt of record. */ - dtls1_record_bitmap_update(s, bitmap); - } - rr->length = 0; - s->packet_length = 0; - goto again; - } - - if (!dtls1_process_record(s)) { - rr->length = 0; - s->packet_length = 0; /* dump this record */ - goto again; /* get another record */ - } - dtls1_record_bitmap_update(s, bitmap); /* Mark receipt of record. */ - - return (1); - -} /*- * Return up to 'len' payload bytes received in 'type' records. @@ -722,9 +367,11 @@ int dtls1_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek) SSL3_RECORD *rr; void (*cb) (const SSL *ssl, int type2, int val) = NULL; - if (s->s3->rbuf.buf == NULL) /* Not initialized yet */ + if (!SSL3_BUFFER_is_initialised(RECORD_LAYER_get_rbuf(&s->rlayer))) { + /* Not initialized yet */ if (!ssl3_setup_buffers(s)) return (-1); + } if ((type && (type != SSL3_RT_APPLICATION_DATA) && (type != SSL3_RT_HANDSHAKE)) || @@ -776,7 +423,7 @@ int dtls1_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek) * s->s3->rrec.off, - offset into 'data' for next read * s->s3->rrec.length, - number of bytes. */ - rr = &(s->s3->rrec); + rr = RECORD_LAYER_get_rrec(&s->rlayer); /* * We are not handshaking and have no data yet, so process data buffered @@ -937,7 +584,10 @@ int dtls1_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek) } #ifndef OPENSSL_NO_HEARTBEATS else if (rr->type == TLS1_RT_HEARTBEAT) { - dtls1_process_heartbeat(s); + /* We allow a 0 return */ + if(dtls1_process_heartbeat(s) < 0) { + return -1; + } /* Exit and notify application to read again */ rr->length = 0; @@ -1044,7 +694,9 @@ int dtls1_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek) } if (!(s->mode & SSL_MODE_AUTO_RETRY)) { - if (s->s3->rbuf.left == 0) { /* no read-ahead left? */ + if (SSL3_BUFFER_get_left( + RECORD_LAYER_get_rbuf(&s->rlayer)) == 0) { + /* no read-ahead left? */ BIO *bio; /* * In the case where we try to read application data, @@ -1088,7 +740,7 @@ int dtls1_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek) cb(s, SSL_CB_READ_ALERT, j); } - if (alert_level == 1) { /* warning */ + if (alert_level == SSL3_AL_WARNING) { s->s3->warn_alert = alert_descr; if (alert_descr == SSL_AD_CLOSE_NOTIFY) { #ifndef OPENSSL_NO_SCTP @@ -1137,7 +789,7 @@ int dtls1_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek) } } #endif - } else if (alert_level == 2) { /* fatal */ + } else if (alert_level == SSL3_AL_FATAL) { char tmp[16]; s->rwstate = SSL_NOTHING; @@ -1266,7 +918,9 @@ int dtls1_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek) } if (!(s->mode & SSL_MODE_AUTO_RETRY)) { - if (s->s3->rbuf.left == 0) { /* no read-ahead left? */ + if (SSL3_BUFFER_get_left( + RECORD_LAYER_get_rbuf(&s->rlayer)) == 0) { + /* no read-ahead left? */ BIO *bio; /* * In the case where we try to read application data, but we @@ -1339,41 +993,6 @@ int dtls1_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek) return (-1); } -int dtls1_write_app_data_bytes(SSL *s, int type, const void *buf_, int len) -{ - int i; - -#ifndef OPENSSL_NO_SCTP - /* - * Check if we have to continue an interrupted handshake for reading - * belated app data with SCTP. - */ - if ((SSL_in_init(s) && !s->in_handshake) || - (BIO_dgram_is_sctp(SSL_get_wbio(s)) && - (s->state == DTLS1_SCTP_ST_SR_READ_SOCK - || s->state == DTLS1_SCTP_ST_CR_READ_SOCK))) -#else - if (SSL_in_init(s) && !s->in_handshake) -#endif - { - i = s->handshake_func(s); - if (i < 0) - return (i); - if (i == 0) { - SSLerr(SSL_F_DTLS1_WRITE_APP_DATA_BYTES, - SSL_R_SSL_HANDSHAKE_FAILURE); - return -1; - } - } - - if (len > SSL3_RT_MAX_PLAIN_LENGTH) { - SSLerr(SSL_F_DTLS1_WRITE_APP_DATA_BYTES, SSL_R_DTLS_MESSAGE_TOO_BIG); - return -1; - } - - i = dtls1_write_bytes(s, type, buf_, len); - return i; -} /* * this only happens when a client hello is received and a handshake @@ -1433,11 +1052,13 @@ int do_dtls1_write(SSL *s, int type, const unsigned char *buf, SSL3_BUFFER *wb; SSL_SESSION *sess; + wb = RECORD_LAYER_get_wbuf(&s->rlayer); + /* * first check if there is a SSL3_BUFFER still being written out. This * will happen with non blocking IO */ - if (s->s3->wbuf.left != 0) { + if (SSL3_BUFFER_get_left(wb) != 0) { OPENSSL_assert(0); /* XDTLS: want to see if we ever get here */ return (ssl3_write_pending(s, type, buf, len)); } @@ -1453,8 +1074,7 @@ int do_dtls1_write(SSL *s, int type, const unsigned char *buf, if (len == 0 && !create_empty_fragment) return 0; - wr = &(s->s3->wrec); - wb = &(s->s3->wbuf); + wr = RECORD_LAYER_get_wrec(&s->rlayer); sess = s->session; if ((sess == NULL) || @@ -1609,7 +1229,7 @@ int do_dtls1_write(SSL *s, int type, const unsigned char *buf, return -1; } -static int dtls1_record_replay_check(SSL *s, DTLS1_BITMAP *bitmap) +int dtls1_record_replay_check(SSL *s, DTLS1_BITMAP *bitmap) { int cmp; unsigned int shift; @@ -1617,7 +1237,7 @@ static int dtls1_record_replay_check(SSL *s, DTLS1_BITMAP *bitmap) cmp = satsub64be(seq, bitmap->max_seq_num); if (cmp > 0) { - memcpy(s->s3->rrec.seq_num, seq, 8); + SSL3_RECORD_set_seq_num(RECORD_LAYER_get_rrec(&s->rlayer), seq); return 1; /* this record in new */ } shift = -cmp; @@ -1626,11 +1246,11 @@ static int dtls1_record_replay_check(SSL *s, DTLS1_BITMAP *bitmap) else if (bitmap->map & (1UL << shift)) return 0; /* record previously received */ - memcpy(s->s3->rrec.seq_num, seq, 8); + SSL3_RECORD_set_seq_num(RECORD_LAYER_get_rrec(&s->rlayer), seq); return 1; } -static void dtls1_record_bitmap_update(SSL *s, DTLS1_BITMAP *bitmap) +void dtls1_record_bitmap_update(SSL *s, DTLS1_BITMAP *bitmap) { int cmp; unsigned int shift; @@ -1651,56 +1271,7 @@ static void dtls1_record_bitmap_update(SSL *s, DTLS1_BITMAP *bitmap) } } -int dtls1_dispatch_alert(SSL *s) -{ - int i, j; - void (*cb) (const SSL *ssl, int type, int val) = NULL; - unsigned char buf[DTLS1_AL_HEADER_LENGTH]; - unsigned char *ptr = &buf[0]; - - s->s3->alert_dispatch = 0; - - memset(buf, 0x00, sizeof(buf)); - *ptr++ = s->s3->send_alert[0]; - *ptr++ = s->s3->send_alert[1]; - -#ifdef DTLS1_AD_MISSING_HANDSHAKE_MESSAGE - if (s->s3->send_alert[1] == DTLS1_AD_MISSING_HANDSHAKE_MESSAGE) { - s2n(s->d1->handshake_read_seq, ptr); - l2n3(s->d1->r_msg_hdr.frag_off, ptr); - } -#endif - - i = do_dtls1_write(s, SSL3_RT_ALERT, &buf[0], sizeof(buf), 0); - if (i <= 0) { - s->s3->alert_dispatch = 1; - /* fprintf( stderr, "not done with alert\n" ); */ - } else { - if (s->s3->send_alert[0] == SSL3_AL_FATAL -#ifdef DTLS1_AD_MISSING_HANDSHAKE_MESSAGE - || s->s3->send_alert[1] == DTLS1_AD_MISSING_HANDSHAKE_MESSAGE -#endif - ) - (void)BIO_flush(s->wbio); - - if (s->msg_callback) - s->msg_callback(1, s->version, SSL3_RT_ALERT, s->s3->send_alert, - 2, s, s->msg_callback_arg); - - if (s->info_callback != NULL) - cb = s->info_callback; - else if (s->ctx->info_callback != NULL) - cb = s->ctx->info_callback; - - if (cb != NULL) { - j = (s->s3->send_alert[0] << 8) | s->s3->send_alert[1]; - cb(s, SSL_CB_WRITE_ALERT, j); - } - } - return (i); -} - -static DTLS1_BITMAP *dtls1_get_bitmap(SSL *s, SSL3_RECORD *rr, +DTLS1_BITMAP *dtls1_get_bitmap(SSL *s, SSL3_RECORD *rr, unsigned int *is_next_epoch) {