| 3917 | } |
| 3918 | |
| 3919 | static void |
| 3920 | sctp_notify_stream_reset(struct sctp_tcb *stcb, |
| 3921 | int number_entries, uint16_t *list, int flag) |
| 3922 | { |
| 3923 | struct mbuf *m_notify; |
| 3924 | struct sctp_queued_to_read *control; |
| 3925 | struct sctp_stream_reset_event *strreset; |
| 3926 | int len; |
| 3927 | |
| 3928 | if ((stcb == NULL) || |
| 3929 | (sctp_stcb_is_feature_off(stcb->sctp_ep, stcb, SCTP_PCB_FLAGS_STREAM_RESETEVNT))) { |
| 3930 | /* event not enabled */ |
| 3931 | return; |
| 3932 | } |
| 3933 | |
| 3934 | m_notify = sctp_get_mbuf_for_msg(MCLBYTES, 0, M_NOWAIT, 1, MT_DATA); |
| 3935 | if (m_notify == NULL) |
| 3936 | /* no space left */ |
| 3937 | return; |
| 3938 | SCTP_BUF_LEN(m_notify) = 0; |
| 3939 | len = sizeof(struct sctp_stream_reset_event) + (number_entries * sizeof(uint16_t)); |
| 3940 | if (len > M_TRAILINGSPACE(m_notify)) { |
| 3941 | /* never enough room */ |
| 3942 | sctp_m_freem(m_notify); |
| 3943 | return; |
| 3944 | } |
| 3945 | strreset = mtod(m_notify, struct sctp_stream_reset_event *); |
| 3946 | memset(strreset, 0, len); |
| 3947 | strreset->strreset_type = SCTP_STREAM_RESET_EVENT; |
| 3948 | strreset->strreset_flags = flag; |
| 3949 | strreset->strreset_length = len; |
| 3950 | strreset->strreset_assoc_id = sctp_get_associd(stcb); |
| 3951 | if (number_entries) { |
| 3952 | int i; |
| 3953 | |
| 3954 | for (i = 0; i < number_entries; i++) { |
| 3955 | strreset->strreset_stream_list[i] = ntohs(list[i]); |
| 3956 | } |
| 3957 | } |
| 3958 | SCTP_BUF_LEN(m_notify) = len; |
| 3959 | SCTP_BUF_NEXT(m_notify) = NULL; |
| 3960 | if (sctp_sbspace(&stcb->asoc, &stcb->sctp_socket->so_rcv) < SCTP_BUF_LEN(m_notify)) { |
| 3961 | /* no space */ |
| 3962 | sctp_m_freem(m_notify); |
| 3963 | return; |
| 3964 | } |
| 3965 | /* append to socket */ |
| 3966 | control = sctp_build_readq_entry(stcb, stcb->asoc.primary_destination, |
| 3967 | 0, 0, stcb->asoc.context, 0, 0, 0, |
| 3968 | m_notify); |
| 3969 | if (control == NULL) { |
| 3970 | /* no memory */ |
| 3971 | sctp_m_freem(m_notify); |
| 3972 | return; |
| 3973 | } |
| 3974 | control->length = SCTP_BUF_LEN(m_notify); |
| 3975 | control->spec_flags = M_NOTIFICATION; |
| 3976 | /* not that we need this */ |
no test coverage detected