| 3996 | |
| 3997 | #ifdef __GNUC__ |
| 3998 | __attribute__((noinline)) |
| 3999 | #endif |
| 4000 | static int |
| 4001 | sctp_handle_stream_reset(struct sctp_tcb *stcb, struct mbuf *m, int offset, |
| 4002 | struct sctp_chunkhdr *ch_req) |
| 4003 | { |
| 4004 | uint16_t remaining_length, param_len, ptype; |
| 4005 | struct sctp_paramhdr pstore; |
| 4006 | uint8_t cstore[SCTP_CHUNK_BUFFER_SIZE]; |
| 4007 | uint32_t seq = 0; |
| 4008 | int num_req = 0; |
| 4009 | int trunc = 0; |
| 4010 | struct sctp_tmit_chunk *chk; |
| 4011 | struct sctp_chunkhdr *ch; |
| 4012 | struct sctp_paramhdr *ph; |
| 4013 | int ret_code = 0; |
| 4014 | int num_param = 0; |
| 4015 | |
| 4016 | /* now it may be a reset or a reset-response */ |
| 4017 | remaining_length = ntohs(ch_req->chunk_length) - sizeof(struct sctp_chunkhdr); |
| 4018 | |
| 4019 | /* setup for adding the response */ |
| 4020 | sctp_alloc_a_chunk(stcb, chk); |
| 4021 | if (chk == NULL) { |
| 4022 | return (ret_code); |
| 4023 | } |
| 4024 | chk->copy_by_ref = 0; |
| 4025 | chk->rec.chunk_id.id = SCTP_STREAM_RESET; |
| 4026 | chk->rec.chunk_id.can_take_data = 0; |
| 4027 | chk->flags = 0; |
| 4028 | chk->asoc = &stcb->asoc; |
| 4029 | chk->no_fr_allowed = 0; |
| 4030 | chk->book_size = chk->send_size = sizeof(struct sctp_chunkhdr); |
| 4031 | chk->book_size_scale = 0; |
| 4032 | chk->data = sctp_get_mbuf_for_msg(MCLBYTES, 0, M_NOWAIT, 1, MT_DATA); |
| 4033 | if (chk->data == NULL) { |
| 4034 | strres_nochunk: |
| 4035 | if (chk->data) { |
| 4036 | sctp_m_freem(chk->data); |
| 4037 | chk->data = NULL; |
| 4038 | } |
| 4039 | sctp_free_a_chunk(stcb, chk, SCTP_SO_NOT_LOCKED); |
| 4040 | return (ret_code); |
| 4041 | } |
| 4042 | SCTP_BUF_RESV_UF(chk->data, SCTP_MIN_OVERHEAD); |
| 4043 | |
| 4044 | /* setup chunk parameters */ |
| 4045 | chk->sent = SCTP_DATAGRAM_UNSENT; |
| 4046 | chk->snd_count = 0; |
| 4047 | chk->whoTo = NULL; |
| 4048 | |
| 4049 | ch = mtod(chk->data, struct sctp_chunkhdr *); |
| 4050 | ch->chunk_type = SCTP_STREAM_RESET; |
| 4051 | ch->chunk_flags = 0; |
| 4052 | ch->chunk_length = htons(chk->send_size); |
| 4053 | SCTP_BUF_LEN(chk->data) = SCTP_SIZE32(chk->send_size); |
| 4054 | offset += sizeof(struct sctp_chunkhdr); |
| 4055 | while (remaining_length >= sizeof(struct sctp_paramhdr)) { |
no test coverage detected