| 4818 | } |
| 4819 | |
| 4820 | void |
| 4821 | sctp_add_to_readq(struct sctp_inpcb *inp, |
| 4822 | struct sctp_tcb *stcb, |
| 4823 | struct sctp_queued_to_read *control, |
| 4824 | struct sockbuf *sb, |
| 4825 | int end, |
| 4826 | int inp_read_lock_held, |
| 4827 | int so_locked) |
| 4828 | { |
| 4829 | /* |
| 4830 | * Here we must place the control on the end of the socket read |
| 4831 | * queue AND increment sb_cc so that select will work properly on |
| 4832 | * read. |
| 4833 | */ |
| 4834 | struct mbuf *m, *prev = NULL; |
| 4835 | |
| 4836 | if (inp == NULL) { |
| 4837 | /* Gak, TSNH!! */ |
| 4838 | #ifdef INVARIANTS |
| 4839 | panic("Gak, inp NULL on add_to_readq"); |
| 4840 | #endif |
| 4841 | return; |
| 4842 | } |
| 4843 | if (inp_read_lock_held == 0) |
| 4844 | SCTP_INP_READ_LOCK(inp); |
| 4845 | if (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_CANT_READ) { |
| 4846 | if (!control->on_strm_q) { |
| 4847 | sctp_free_remote_addr(control->whoFrom); |
| 4848 | if (control->data) { |
| 4849 | sctp_m_freem(control->data); |
| 4850 | control->data = NULL; |
| 4851 | } |
| 4852 | sctp_free_a_readq(stcb, control); |
| 4853 | } |
| 4854 | if (inp_read_lock_held == 0) |
| 4855 | SCTP_INP_READ_UNLOCK(inp); |
| 4856 | return; |
| 4857 | } |
| 4858 | if (!(control->spec_flags & M_NOTIFICATION)) { |
| 4859 | atomic_add_int(&inp->total_recvs, 1); |
| 4860 | if (!control->do_not_ref_stcb) { |
| 4861 | atomic_add_int(&stcb->total_recvs, 1); |
| 4862 | } |
| 4863 | } |
| 4864 | m = control->data; |
| 4865 | control->held_length = 0; |
| 4866 | control->length = 0; |
| 4867 | while (m) { |
| 4868 | if (SCTP_BUF_LEN(m) == 0) { |
| 4869 | /* Skip mbufs with NO length */ |
| 4870 | if (prev == NULL) { |
| 4871 | /* First one */ |
| 4872 | control->data = sctp_m_free(m); |
| 4873 | m = control->data; |
| 4874 | } else { |
| 4875 | SCTP_BUF_NEXT(prev) = sctp_m_free(m); |
| 4876 | m = SCTP_BUF_NEXT(prev); |
| 4877 | } |
no test coverage detected