| 3368 | } |
| 3369 | |
| 3370 | static void |
| 3371 | sctp_notify_send_failed(struct sctp_tcb *stcb, uint8_t sent, uint32_t error, |
| 3372 | struct sctp_tmit_chunk *chk, int so_locked) |
| 3373 | { |
| 3374 | struct mbuf *m_notify; |
| 3375 | struct sctp_send_failed *ssf; |
| 3376 | struct sctp_send_failed_event *ssfe; |
| 3377 | struct sctp_queued_to_read *control; |
| 3378 | struct sctp_chunkhdr *chkhdr; |
| 3379 | int notifhdr_len, chk_len, chkhdr_len, padding_len, payload_len; |
| 3380 | |
| 3381 | if ((stcb == NULL) || |
| 3382 | (sctp_stcb_is_feature_off(stcb->sctp_ep, stcb, SCTP_PCB_FLAGS_RECVSENDFAILEVNT) && |
| 3383 | sctp_stcb_is_feature_off(stcb->sctp_ep, stcb, SCTP_PCB_FLAGS_RECVNSENDFAILEVNT))) { |
| 3384 | /* event not enabled */ |
| 3385 | return; |
| 3386 | } |
| 3387 | |
| 3388 | if (sctp_stcb_is_feature_on(stcb->sctp_ep, stcb, SCTP_PCB_FLAGS_RECVNSENDFAILEVNT)) { |
| 3389 | notifhdr_len = sizeof(struct sctp_send_failed_event); |
| 3390 | } else { |
| 3391 | notifhdr_len = sizeof(struct sctp_send_failed); |
| 3392 | } |
| 3393 | m_notify = sctp_get_mbuf_for_msg(notifhdr_len, 0, M_NOWAIT, 1, MT_DATA); |
| 3394 | if (m_notify == NULL) |
| 3395 | /* no space left */ |
| 3396 | return; |
| 3397 | SCTP_BUF_LEN(m_notify) = notifhdr_len; |
| 3398 | if (stcb->asoc.idata_supported) { |
| 3399 | chkhdr_len = sizeof(struct sctp_idata_chunk); |
| 3400 | } else { |
| 3401 | chkhdr_len = sizeof(struct sctp_data_chunk); |
| 3402 | } |
| 3403 | /* Use some defaults in case we can't access the chunk header */ |
| 3404 | if (chk->send_size >= chkhdr_len) { |
| 3405 | payload_len = chk->send_size - chkhdr_len; |
| 3406 | } else { |
| 3407 | payload_len = 0; |
| 3408 | } |
| 3409 | padding_len = 0; |
| 3410 | if (chk->data != NULL) { |
| 3411 | chkhdr = mtod(chk->data, struct sctp_chunkhdr *); |
| 3412 | if (chkhdr != NULL) { |
| 3413 | chk_len = ntohs(chkhdr->chunk_length); |
| 3414 | if ((chk_len >= chkhdr_len) && |
| 3415 | (chk->send_size >= chk_len) && |
| 3416 | (chk->send_size - chk_len < 4)) { |
| 3417 | padding_len = chk->send_size - chk_len; |
| 3418 | payload_len = chk->send_size - chkhdr_len - padding_len; |
| 3419 | } |
| 3420 | } |
| 3421 | } |
| 3422 | if (sctp_stcb_is_feature_on(stcb->sctp_ep, stcb, SCTP_PCB_FLAGS_RECVNSENDFAILEVNT)) { |
| 3423 | ssfe = mtod(m_notify, struct sctp_send_failed_event *); |
| 3424 | memset(ssfe, 0, notifhdr_len); |
| 3425 | ssfe->ssfe_type = SCTP_SEND_FAILED_EVENT; |
| 3426 | if (sent) { |
| 3427 | ssfe->ssfe_flags = SCTP_DATA_SENT; |
no test coverage detected