| 2646 | } |
| 2647 | |
| 2648 | int |
| 2649 | sctp_process_data(struct mbuf **mm, int iphlen, int *offset, int length, |
| 2650 | struct sctp_inpcb *inp, struct sctp_tcb *stcb, |
| 2651 | struct sctp_nets *net, uint32_t *high_tsn) |
| 2652 | { |
| 2653 | struct sctp_chunkhdr *ch, chunk_buf; |
| 2654 | struct sctp_association *asoc; |
| 2655 | int num_chunks = 0; /* number of control chunks processed */ |
| 2656 | int stop_proc = 0; |
| 2657 | int break_flag, last_chunk; |
| 2658 | int abort_flag = 0, was_a_gap; |
| 2659 | struct mbuf *m; |
| 2660 | uint32_t highest_tsn; |
| 2661 | uint16_t chk_length; |
| 2662 | |
| 2663 | /* set the rwnd */ |
| 2664 | sctp_set_rwnd(stcb, &stcb->asoc); |
| 2665 | |
| 2666 | m = *mm; |
| 2667 | SCTP_TCB_LOCK_ASSERT(stcb); |
| 2668 | asoc = &stcb->asoc; |
| 2669 | if (SCTP_TSN_GT(asoc->highest_tsn_inside_nr_map, asoc->highest_tsn_inside_map)) { |
| 2670 | highest_tsn = asoc->highest_tsn_inside_nr_map; |
| 2671 | } else { |
| 2672 | highest_tsn = asoc->highest_tsn_inside_map; |
| 2673 | } |
| 2674 | was_a_gap = SCTP_TSN_GT(highest_tsn, stcb->asoc.cumulative_tsn); |
| 2675 | /* |
| 2676 | * setup where we got the last DATA packet from for any SACK that |
| 2677 | * may need to go out. Don't bump the net. This is done ONLY when a |
| 2678 | * chunk is assigned. |
| 2679 | */ |
| 2680 | asoc->last_data_chunk_from = net; |
| 2681 | |
| 2682 | /*- |
| 2683 | * Now before we proceed we must figure out if this is a wasted |
| 2684 | * cluster... i.e. it is a small packet sent in and yet the driver |
| 2685 | * underneath allocated a full cluster for it. If so we must copy it |
| 2686 | * to a smaller mbuf and free up the cluster mbuf. This will help |
| 2687 | * with cluster starvation. |
| 2688 | */ |
| 2689 | if (SCTP_BUF_LEN(m) < (long)MLEN && SCTP_BUF_NEXT(m) == NULL) { |
| 2690 | /* we only handle mbufs that are singletons.. not chains */ |
| 2691 | m = sctp_get_mbuf_for_msg(SCTP_BUF_LEN(m), 0, M_NOWAIT, 1, MT_DATA); |
| 2692 | if (m) { |
| 2693 | /* ok lets see if we can copy the data up */ |
| 2694 | caddr_t *from, *to; |
| 2695 | |
| 2696 | /* get the pointers and copy */ |
| 2697 | to = mtod(m, caddr_t *); |
| 2698 | from = mtod((*mm), caddr_t *); |
| 2699 | memcpy(to, from, SCTP_BUF_LEN((*mm))); |
| 2700 | /* copy the length and free up the old */ |
| 2701 | SCTP_BUF_LEN(m) = SCTP_BUF_LEN((*mm)); |
| 2702 | sctp_m_freem(*mm); |
| 2703 | /* success, back copy */ |
| 2704 | *mm = m; |
| 2705 | } else { |
no test coverage detected