| 6819 | } |
| 6820 | |
| 6821 | static int |
| 6822 | sctp_sendall(struct sctp_inpcb *inp, struct uio *uio, struct mbuf *m, |
| 6823 | struct sctp_sndrcvinfo *srcv) |
| 6824 | { |
| 6825 | int ret; |
| 6826 | struct sctp_copy_all *ca; |
| 6827 | |
| 6828 | if (inp->sctp_flags & SCTP_PCB_FLAGS_SND_ITERATOR_UP) { |
| 6829 | /* There is another. */ |
| 6830 | return (EBUSY); |
| 6831 | } |
| 6832 | if (uio->uio_resid > (ssize_t)SCTP_BASE_SYSCTL(sctp_sendall_limit)) { |
| 6833 | /* You must not be larger than the limit! */ |
| 6834 | return (EMSGSIZE); |
| 6835 | } |
| 6836 | SCTP_MALLOC(ca, struct sctp_copy_all *, sizeof(struct sctp_copy_all), |
| 6837 | SCTP_M_COPYAL); |
| 6838 | if (ca == NULL) { |
| 6839 | sctp_m_freem(m); |
| 6840 | SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_OUTPUT, ENOMEM); |
| 6841 | return (ENOMEM); |
| 6842 | } |
| 6843 | memset(ca, 0, sizeof(struct sctp_copy_all)); |
| 6844 | |
| 6845 | ca->inp = inp; |
| 6846 | if (srcv) { |
| 6847 | memcpy(&ca->sndrcv, srcv, sizeof(struct sctp_nonpad_sndrcvinfo)); |
| 6848 | } |
| 6849 | /* |
| 6850 | * take off the sendall flag, it would be bad if we failed to do |
| 6851 | * this :-0 |
| 6852 | */ |
| 6853 | ca->sndrcv.sinfo_flags &= ~SCTP_SENDALL; |
| 6854 | /* get length and mbuf chain */ |
| 6855 | if (uio) { |
| 6856 | ca->sndlen = uio->uio_resid; |
| 6857 | ca->m = sctp_copy_out_all(uio, ca->sndlen); |
| 6858 | if (ca->m == NULL) { |
| 6859 | SCTP_FREE(ca, SCTP_M_COPYAL); |
| 6860 | SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_OUTPUT, ENOMEM); |
| 6861 | return (ENOMEM); |
| 6862 | } |
| 6863 | } else { |
| 6864 | /* Gather the length of the send */ |
| 6865 | struct mbuf *mat; |
| 6866 | |
| 6867 | ca->sndlen = 0; |
| 6868 | for (mat = m; mat; mat = SCTP_BUF_NEXT(mat)) { |
| 6869 | ca->sndlen += SCTP_BUF_LEN(mat); |
| 6870 | } |
| 6871 | } |
| 6872 | inp->sctp_flags |= SCTP_PCB_FLAGS_SND_ITERATOR_UP; |
| 6873 | ret = sctp_initiate_iterator(NULL, sctp_sendall_iterator, NULL, |
| 6874 | SCTP_PCB_ANY_FLAGS, SCTP_PCB_ANY_FEATURES, |
| 6875 | SCTP_ASOC_ANY_STATE, |
| 6876 | (void *)ca, 0, |
| 6877 | sctp_sendall_completes, inp, 1); |
| 6878 | if (ret) { |
no test coverage detected