diff options
Diffstat (limited to 'sys')
-rw-r--r-- | sys/netinet/sctp_asconf.c | 37 | ||||
-rw-r--r-- | sys/netinet/sctp_bsd_addr.c | 4 | ||||
-rw-r--r-- | sys/netinet/sctp_indata.c | 444 | ||||
-rw-r--r-- | sys/netinet/sctp_input.c | 102 | ||||
-rw-r--r-- | sys/netinet/sctp_output.c | 36 | ||||
-rw-r--r-- | sys/netinet/sctp_pcb.c | 377 | ||||
-rw-r--r-- | sys/netinet/sctp_timer.c | 35 | ||||
-rw-r--r-- | sys/netinet/sctp_usrreq.c | 6 | ||||
-rw-r--r-- | sys/netinet/sctputil.c | 136 |
9 files changed, 439 insertions, 738 deletions
diff --git a/sys/netinet/sctp_asconf.c b/sys/netinet/sctp_asconf.c index a9d0f37512b1..1933de5ee63d 100644 --- a/sys/netinet/sctp_asconf.c +++ b/sys/netinet/sctp_asconf.c @@ -656,19 +656,16 @@ sctp_handle_asconf(struct mbuf *m, unsigned int offset, /* delete old cache */ SCTPDBG(SCTP_DEBUG_ASCONF1, "handle_asconf: Now processing firstASCONF. Try to delte old cache\n"); - ack = TAILQ_FIRST(&stcb->asoc.asconf_ack_sent); - while (ack != NULL) { - ack_next = TAILQ_NEXT(ack, next); + TAILQ_FOREACH_SAFE(ack, &asoc->asconf_ack_sent, next, ack_next) { if (ack->serial_number == serial_num) break; SCTPDBG(SCTP_DEBUG_ASCONF1, "handle_asconf: delete old(%u) < first(%u)\n", ack->serial_number, serial_num); - TAILQ_REMOVE(&stcb->asoc.asconf_ack_sent, ack, next); + TAILQ_REMOVE(&asoc->asconf_ack_sent, ack, next); if (ack->data != NULL) { sctp_m_freem(ack->data); } SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_asconf_ack), ack); - ack = ack_next; } } m_ack = sctp_get_mbuf_for_msg(sizeof(struct sctp_asconf_ack_chunk), 0, @@ -1264,9 +1261,7 @@ sctp_asconf_queue_mgmt(struct sctp_tcb *stcb, struct sctp_ifa *ifa, struct sockaddr *sa; /* make sure the request isn't already in the queue */ - for (aa = TAILQ_FIRST(&stcb->asoc.asconf_queue); aa != NULL; - aa = aa_next) { - aa_next = TAILQ_NEXT(aa, next); + TAILQ_FOREACH_SAFE(aa, &stcb->asoc.asconf_queue, next, aa_next) { /* address match? */ if (sctp_asconf_addr_match(aa, &ifa->address.sa) == 0) continue; @@ -1480,9 +1475,7 @@ sctp_asconf_queue_sa_delete(struct sctp_tcb *stcb, struct sockaddr *sa) return (-1); } /* make sure the request isn't already in the queue */ - for (aa = TAILQ_FIRST(&stcb->asoc.asconf_queue); aa != NULL; - aa = aa_next) { - aa_next = TAILQ_NEXT(aa, next); + TAILQ_FOREACH_SAFE(aa, &stcb->asoc.asconf_queue, next, aa_next) { /* address match? */ if (sctp_asconf_addr_match(aa, sa) == 0) continue; @@ -1836,9 +1829,7 @@ sctp_handle_asconf_ack(struct mbuf *m, int offset, */ if (last_error_id == 0) last_error_id--;/* set to "max" value */ - for (aa = TAILQ_FIRST(&stcb->asoc.asconf_queue); aa != NULL; - aa = aa_next) { - aa_next = TAILQ_NEXT(aa, next); + TAILQ_FOREACH_SAFE(aa, &stcb->asoc.asconf_queue, next, aa_next) { if (aa->sent == 1) { /* * implicitly successful or failed if correlation_id @@ -2098,14 +2089,11 @@ sctp_asconf_iterator_ep_end(struct sctp_inpcb *inp, void *ptr, uint32_t val) } } } else if (l->action == SCTP_DEL_IP_ADDRESS) { - laddr = LIST_FIRST(&inp->sctp_addr_list); - while (laddr) { - nladdr = LIST_NEXT(laddr, sctp_nxt_addr); + LIST_FOREACH_SAFE(laddr, &inp->sctp_addr_list, sctp_nxt_addr, nladdr) { /* remove only after all guys are done */ if (laddr->ifa == ifa) { sctp_del_local_addr_ep(inp, ifa); } - laddr = nladdr; } } } @@ -2285,12 +2273,10 @@ sctp_asconf_iterator_end(void *ptr, uint32_t val) { struct sctp_asconf_iterator *asc; struct sctp_ifa *ifa; - struct sctp_laddr *l, *l_next; + struct sctp_laddr *l, *nl; asc = (struct sctp_asconf_iterator *)ptr; - l = LIST_FIRST(&asc->list_of_work); - while (l != NULL) { - l_next = LIST_NEXT(l, sctp_nxt_addr); + LIST_FOREACH_SAFE(l, &asc->list_of_work, sctp_nxt_addr, nl) { ifa = l->ifa; if (l->action == SCTP_ADD_IP_ADDRESS) { /* Clear the defer use flag */ @@ -2299,7 +2285,6 @@ sctp_asconf_iterator_end(void *ptr, uint32_t val) sctp_free_ifa(ifa); SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_laddr), l); SCTP_DECR_LADDR_COUNT(); - l = l_next; } SCTP_FREE(asc, SCTP_M_ASC_IT); } @@ -2394,11 +2379,7 @@ sctp_is_addr_pending(struct sctp_tcb *stcb, struct sctp_ifa *sctp_ifa) add_cnt = del_cnt = 0; last_param_type = 0; - for (chk = TAILQ_FIRST(&stcb->asoc.asconf_send_queue); chk != NULL; - chk = nchk) { - /* get next chk */ - nchk = TAILQ_NEXT(chk, sctp_next); - + TAILQ_FOREACH_SAFE(chk, &stcb->asoc.asconf_send_queue, sctp_next, nchk) { if (chk->data == NULL) { SCTPDBG(SCTP_DEBUG_ASCONF1, "is_addr_pending: No mbuf data?\n"); continue; diff --git a/sys/netinet/sctp_bsd_addr.c b/sys/netinet/sctp_bsd_addr.c index 90fd9a134433..216a6d3eb239 100644 --- a/sys/netinet/sctp_bsd_addr.c +++ b/sys/netinet/sctp_bsd_addr.c @@ -77,9 +77,9 @@ static int __sctp_thread_based_iterator_started = 0; static void sctp_cleanup_itqueue(void) { - struct sctp_iterator *it; + struct sctp_iterator *it, *nit; - while ((it = TAILQ_FIRST(&sctp_it_ctl.iteratorhead)) != NULL) { + TAILQ_FOREACH_SAFE(it, &sctp_it_ctl.iteratorhead, sctp_nxt_itr, nit) { if (it->function_atend != NULL) { (*it->function_atend) (it->pointer, it->val); } diff --git a/sys/netinet/sctp_indata.c b/sys/netinet/sctp_indata.c index b518a5c18b61..eb32a9120d9b 100644 --- a/sys/netinet/sctp_indata.c +++ b/sys/netinet/sctp_indata.c @@ -344,13 +344,12 @@ sctp_mark_non_revokable(struct sctp_association *asoc, uint32_t tsn) static void sctp_service_reassembly(struct sctp_tcb *stcb, struct sctp_association *asoc) { - struct sctp_tmit_chunk *chk; + struct sctp_tmit_chunk *chk, *nchk; uint16_t nxt_todel; uint16_t stream_no; int end = 0; int cntDel; - - struct sctp_queued_to_read *control, *ctl, *ctlat; + struct sctp_queued_to_read *control, *ctl, *nctl; if (stcb == NULL) return; @@ -362,8 +361,7 @@ sctp_service_reassembly(struct sctp_tcb *stcb, struct sctp_association *asoc) /* socket above is long gone or going.. */ abandon: asoc->fragmented_delivery_inprogress = 0; - chk = TAILQ_FIRST(&asoc->reasmqueue); - while (chk) { + TAILQ_FOREACH_SAFE(chk, &asoc->reasmqueue, sctp_next, nchk) { TAILQ_REMOVE(&asoc->reasmqueue, chk, sctp_next); asoc->size_on_reasm_queue -= chk->send_size; sctp_ucount_decr(asoc->cnt_on_reasm_queue); @@ -378,16 +376,11 @@ abandon: /* Now free the address and data */ sctp_free_a_chunk(stcb, chk); /* sa_ignore FREED_MEMORY */ - chk = TAILQ_FIRST(&asoc->reasmqueue); } return; } SCTP_TCB_LOCK_ASSERT(stcb); - do { - chk = TAILQ_FIRST(&asoc->reasmqueue); - if (chk == NULL) { - return; - } + TAILQ_FOREACH_SAFE(chk, &asoc->reasmqueue, sctp_next, nchk) { if (chk->rec.data.TSN_seq != (asoc->tsn_last_delivered + 1)) { /* Can't deliver more :< */ return; @@ -496,33 +489,26 @@ abandon: strm = &asoc->strmin[stream_no]; nxt_todel = strm->last_sequence_delivered + 1; - ctl = TAILQ_FIRST(&strm->inqueue); - if (ctl && (nxt_todel == ctl->sinfo_ssn)) { - while (ctl != NULL) { - /* Deliver more if we can. */ - if (nxt_todel == ctl->sinfo_ssn) { - ctlat = TAILQ_NEXT(ctl, next); - TAILQ_REMOVE(&strm->inqueue, ctl, next); - asoc->size_on_all_streams -= ctl->length; - sctp_ucount_decr(asoc->cnt_on_all_streams); - strm->last_sequence_delivered++; - sctp_mark_non_revokable(asoc, ctl->sinfo_tsn); - sctp_add_to_readq(stcb->sctp_ep, stcb, - ctl, - &stcb->sctp_socket->so_rcv, 1, - SCTP_READ_LOCK_NOT_HELD, SCTP_SO_NOT_LOCKED); - ctl = ctlat; - } else { - break; - } - nxt_todel = strm->last_sequence_delivered + 1; + TAILQ_FOREACH_SAFE(ctl, &strm->inqueue, next, nctl) { + /* Deliver more if we can. */ + if (nxt_todel == ctl->sinfo_ssn) { + TAILQ_REMOVE(&strm->inqueue, ctl, next); + asoc->size_on_all_streams -= ctl->length; + sctp_ucount_decr(asoc->cnt_on_all_streams); + strm->last_sequence_delivered++; + sctp_mark_non_revokable(asoc, ctl->sinfo_tsn); + sctp_add_to_readq(stcb->sctp_ep, stcb, + ctl, + &stcb->sctp_socket->so_rcv, 1, + SCTP_READ_LOCK_NOT_HELD, SCTP_SO_NOT_LOCKED); + } else { + break; } + nxt_todel = strm->last_sequence_delivered + 1; } break; } - /* sa_ignore FREED_MEMORY */ - chk = TAILQ_FIRST(&asoc->reasmqueue); - } while (chk); + } } /* @@ -626,12 +612,10 @@ protocol_error: control, &stcb->sctp_socket->so_rcv, 1, SCTP_READ_LOCK_NOT_HELD, SCTP_SO_NOT_LOCKED); - control = TAILQ_FIRST(&strm->inqueue); - while (control != NULL) { + TAILQ_FOREACH_SAFE(control, &strm->inqueue, next, at) { /* all delivered */ nxt_todel = strm->last_sequence_delivered + 1; if (nxt_todel == control->sinfo_ssn) { - at = TAILQ_NEXT(control, next); TAILQ_REMOVE(&strm->inqueue, control, next); asoc->size_on_all_streams -= control->length; sctp_ucount_decr(asoc->cnt_on_all_streams); @@ -652,7 +636,6 @@ protocol_error: &stcb->sctp_socket->so_rcv, 1, SCTP_READ_LOCK_NOT_HELD, SCTP_SO_NOT_LOCKED); - control = at; continue; } break; @@ -756,7 +739,7 @@ sctp_is_all_msg_on_reasm(struct sctp_association *asoc, uint32_t * t_size) return (0); } tsn = chk->rec.data.TSN_seq; - while (chk) { + TAILQ_FOREACH(chk, &asoc->reasmqueue, sctp_next) { if (tsn != chk->rec.data.TSN_seq) { return (0); } @@ -765,7 +748,6 @@ sctp_is_all_msg_on_reasm(struct sctp_association *asoc, uint32_t * t_size) return (1); } tsn++; - chk = TAILQ_NEXT(chk, sctp_next); } return (0); } @@ -2090,14 +2072,14 @@ failed_pdapi_express_del: /* first one on */ TAILQ_INSERT_TAIL(&asoc->pending_reply_queue, control, next); } else { - struct sctp_queued_to_read *ctlOn; + struct sctp_queued_to_read *ctlOn, + *nctlOn; unsigned char inserted = 0; - ctlOn = TAILQ_FIRST(&asoc->pending_reply_queue); - while (ctlOn) { + TAILQ_FOREACH_SAFE(ctlOn, &asoc->pending_reply_queue, next, nctlOn) { if (compare_with_wrap(control->sinfo_tsn, ctlOn->sinfo_tsn, MAX_TSN)) { - ctlOn = TAILQ_NEXT(ctlOn, next); + continue; } else { /* found it */ TAILQ_INSERT_BEFORE(ctlOn, control, next); @@ -2166,27 +2148,27 @@ finish_express_del: * pending_reply space 3: distribute any chunks in * pending_reply_queue. */ - struct sctp_queued_to_read *ctl; + struct sctp_queued_to_read *ctl, *nctl; sctp_reset_in_stream(stcb, liste->number_entries, liste->req.list_of_streams); TAILQ_REMOVE(&asoc->resetHead, liste, next_resp); SCTP_FREE(liste, SCTP_M_STRESET); /* sa_ignore FREED_MEMORY */ liste = TAILQ_FIRST(&asoc->resetHead); - ctl = TAILQ_FIRST(&asoc->pending_reply_queue); - if (ctl && (liste == NULL)) { + if (TAILQ_EMPTY(&asoc->resetHead)) { /* All can be removed */ - while (ctl) { + TAILQ_FOREACH_SAFE(ctl, &asoc->pending_reply_queue, next, nctl) { TAILQ_REMOVE(&asoc->pending_reply_queue, ctl, next); sctp_queue_data_to_stream(stcb, asoc, ctl, abort_flag); if (*abort_flag) { return (0); } - ctl = TAILQ_FIRST(&asoc->pending_reply_queue); } - } else if (ctl) { - /* more than one in queue */ - while (!compare_with_wrap(ctl->sinfo_tsn, liste->tsn, MAX_TSN)) { + } else { + TAILQ_FOREACH_SAFE(ctl, &asoc->pending_reply_queue, next, nctl) { + if (compare_with_wrap(ctl->sinfo_tsn, liste->tsn, MAX_TSN)) { + break; + } /* * if ctl->sinfo_tsn is <= liste->tsn we can * process it which is the NOT of @@ -2197,7 +2179,6 @@ finish_express_del: if (*abort_flag) { return (0); } - ctl = TAILQ_FIRST(&asoc->pending_reply_queue); } } /* @@ -3143,8 +3124,7 @@ sctp_check_for_revoked(struct sctp_tcb *stcb, struct sctp_tmit_chunk *tp1; int tot_revoked = 0; - tp1 = TAILQ_FIRST(&asoc->sent_queue); - while (tp1) { + TAILQ_FOREACH(tp1, &asoc->sent_queue, sctp_next) { if (compare_with_wrap(tp1->rec.data.TSN_seq, cumack, MAX_TSN)) { /* @@ -3196,7 +3176,6 @@ sctp_check_for_revoked(struct sctp_tcb *stcb, } if (tp1->sent == SCTP_DATAGRAM_UNSENT) break; - tp1 = TAILQ_NEXT(tp1, sctp_next); } if (tot_revoked > 0) { /* @@ -3252,12 +3231,10 @@ sctp_strike_gap_ack_chunks(struct sctp_tcb *stcb, struct sctp_association *asoc, if (stcb->asoc.peer_supports_prsctp) { (void)SCTP_GETTIME_TIMEVAL(&now); } - tp1 = TAILQ_FIRST(&asoc->sent_queue); - while (tp1) { + TAILQ_FOREACH(tp1, &asoc->sent_queue, sctp_next) { strike_flag = 0; if (tp1->no_fr_allowed) { /* this one had a timeout or something */ - tp1 = TAILQ_NEXT(tp1, sctp_next); continue; } if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_FR_LOGGING_ENABLE) { @@ -3283,7 +3260,6 @@ sctp_strike_gap_ack_chunks(struct sctp_tcb *stcb, struct sctp_association *asoc, (SCTP_RESPONSE_TO_USER_REQ | SCTP_NOTIFY_DATAGRAM_SENT), SCTP_SO_NOT_LOCKED); } - tp1 = TAILQ_NEXT(tp1, sctp_next); continue; } } @@ -3300,7 +3276,6 @@ sctp_strike_gap_ack_chunks(struct sctp_tcb *stcb, struct sctp_association *asoc, /* Continue strikin FWD-TSN chunks */ tp1->rec.data.fwd_tsn_cnt++; } - tp1 = TAILQ_NEXT(tp1, sctp_next); continue; } /* @@ -3313,7 +3288,6 @@ sctp_strike_gap_ack_chunks(struct sctp_tcb *stcb, struct sctp_association *asoc, * CMT, no data sent to this dest can be marked for * FR using this SACK. */ - tp1 = TAILQ_NEXT(tp1, sctp_next); continue; } else if (tp1->whoTo && compare_with_wrap(tp1->rec.data.TSN_seq, tp1->whoTo->this_sack_highest_newack, MAX_TSN)) { @@ -3325,7 +3299,6 @@ sctp_strike_gap_ack_chunks(struct sctp_tcb *stcb, struct sctp_association *asoc, * this SACK. This step covers part of the DAC algo * and the HTNA algo as well. */ - tp1 = TAILQ_NEXT(tp1, sctp_next); continue; } /* @@ -3546,7 +3519,6 @@ sctp_strike_gap_ack_chunks(struct sctp_tcb *stcb, struct sctp_association *asoc, } /* Make sure to flag we had a FR */ tp1->whoTo->net_ack++; - tp1 = TAILQ_NEXT(tp1, sctp_next); continue; } } @@ -3660,8 +3632,7 @@ sctp_strike_gap_ack_chunks(struct sctp_tcb *stcb, struct sctp_association *asoc, atomic_add_int(&alt->ref_count, 1); } } - tp1 = TAILQ_NEXT(tp1, sctp_next); - } /* while (tp1) */ + } if (tot_retrans > 0) { /* @@ -3686,8 +3657,7 @@ sctp_try_advance_peer_ack_point(struct sctp_tcb *stcb, if (asoc->peer_supports_prsctp == 0) { return (NULL); } - tp1 = TAILQ_FIRST(&asoc->sent_queue); - while (tp1) { + TAILQ_FOREACH_SAFE(tp1, &asoc->sent_queue, sctp_next, tp2) { if (tp1->sent != SCTP_FORWARD_TSN_SKIP && tp1->sent != SCTP_DATAGRAM_RESEND) { /* no chance to advance, out of here */ @@ -3711,7 +3681,6 @@ sctp_try_advance_peer_ack_point(struct sctp_tcb *stcb, (void)SCTP_GETTIME_TIMEVAL(&now); now_filled = 1; } - tp2 = TAILQ_NEXT(tp1, sctp_next); /* * now we got a chunk which is marked for another * retransmission to a PR-stream but has run out its chances @@ -3763,11 +3732,6 @@ sctp_try_advance_peer_ack_point(struct sctp_tcb *stcb, */ break; } - /* - * If we hit here we just dumped tp1, move to next tsn on - * sent queue. - */ - tp1 = tp2; } return (a_adv); } @@ -3961,9 +3925,7 @@ sctp_express_handle_sack(struct sctp_tcb *stcb, uint32_t cumack, stcb->asoc.overall_error_count = 0; if (compare_with_wrap(cumack, asoc->last_acked_seq, MAX_TSN)) { /* process the new consecutive TSN first */ - tp1 = TAILQ_FIRST(&asoc->sent_queue); - while (tp1) { - tp2 = TAILQ_NEXT(tp1, sctp_next); + TAILQ_FOREACH_SAFE(tp1, &asoc->sent_queue, sctp_next, tp2) { if (compare_with_wrap(cumack, tp1->rec.data.TSN_seq, MAX_TSN) || cumack == tp1->rec.data.TSN_seq) { @@ -4051,6 +4013,7 @@ sctp_express_handle_sack(struct sctp_tcb *stcb, uint32_t cumack, /* sa_ignore NO_NULL_CHK */ sctp_free_bufspace(stcb, asoc, tp1, 1); sctp_m_freem(tp1->data); + tp1->data = NULL; } if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_SACK_LOGGING_ENABLE) { sctp_log_sack(asoc->last_acked_seq, @@ -4060,10 +4023,8 @@ sctp_express_handle_sack(struct sctp_tcb *stcb, uint32_t cumack, 0, SCTP_LOG_FREE_SENT); } - tp1->data = NULL; asoc->sent_queue_cnt--; sctp_free_a_chunk(stcb, tp1); - tp1 = tp2; } else { break; } @@ -4612,8 +4573,7 @@ sctp_handle_sack(struct mbuf *m, int offset_seg, int offset_dup, net->will_exit_fast_recovery = 0; } /* process the new consecutive TSN first */ - tp1 = TAILQ_FIRST(&asoc->sent_queue); - while (tp1) { + TAILQ_FOREACH(tp1, &asoc->sent_queue, sctp_next) { if (compare_with_wrap(last_tsn, tp1->rec.data.TSN_seq, MAX_TSN) || last_tsn == tp1->rec.data.TSN_seq) { @@ -4725,7 +4685,6 @@ sctp_handle_sack(struct mbuf *m, int offset_seg, int offset_dup, } else { break; } - tp1 = TAILQ_NEXT(tp1, sctp_next); } biggest_tsn_newly_acked = biggest_tsn_acked = last_tsn; /* always set this up to cum-ack */ @@ -4899,36 +4858,32 @@ sctp_handle_sack(struct mbuf *m, int offset_seg, int offset_dup, } else if (asoc->saw_sack_with_frags) { int cnt_revoked = 0; - tp1 = TAILQ_FIRST(&asoc->sent_queue); - if (tp1 != NULL) { - /* Peer revoked all dg's marked or acked */ - TAILQ_FOREACH(tp1, &asoc->sent_queue, sctp_next) { - if (tp1->sent == SCTP_DATAGRAM_ACKED) { - tp1->sent = SCTP_DATAGRAM_SENT; - if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_FLIGHT_LOGGING_ENABLE) { - sctp_misc_ints(SCTP_FLIGHT_LOG_UP_REVOKE, - tp1->whoTo->flight_size, - tp1->book_size, - (uintptr_t) tp1->whoTo, - tp1->rec.data.TSN_seq); - } - sctp_flight_size_increase(tp1); - sctp_total_flight_increase(stcb, tp1); - tp1->rec.data.chunk_was_revoked = 1; - /* - * To ensure that this increase in - * flightsize, which is artificial, - * does not throttle the sender, we - * also increase the cwnd - * artificially. - */ - tp1->whoTo->cwnd += tp1->book_size; - cnt_revoked++; + /* Peer revoked all dg's marked or acked */ + TAILQ_FOREACH(tp1, &asoc->sent_queue, sctp_next) { + if (tp1->sent == SCTP_DATAGRAM_ACKED) { + tp1->sent = SCTP_DATAGRAM_SENT; + if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_FLIGHT_LOGGING_ENABLE) { + sctp_misc_ints(SCTP_FLIGHT_LOG_UP_REVOKE, + tp1->whoTo->flight_size, + tp1->book_size, + (uintptr_t) tp1->whoTo, + tp1->rec.data.TSN_seq); } + sctp_flight_size_increase(tp1); + sctp_total_flight_increase(stcb, tp1); + tp1->rec.data.chunk_was_revoked = 1; + /* + * To ensure that this increase in + * flightsize, which is artificial, does not + * throttle the sender, we also increase the + * cwnd artificially. + */ + tp1->whoTo->cwnd += tp1->book_size; + cnt_revoked++; } - if (cnt_revoked) { - reneged_all = 1; - } + } + if (cnt_revoked) { + reneged_all = 1; } asoc->saw_sack_with_frags = 0; } @@ -5346,9 +5301,7 @@ sctp_kick_prsctp_reorder_queue(struct sctp_tcb *stcb, * First deliver anything prior to and including the stream no that * came in */ - ctl = TAILQ_FIRST(&strmin->inqueue); - while (ctl) { - nctl = TAILQ_NEXT(ctl, next); + TAILQ_FOREACH_SAFE(ctl, &strmin->inqueue, next, nctl) { if (compare_with_wrap(tt, ctl->sinfo_ssn, MAX_SEQ) || (tt == ctl->sinfo_ssn)) { /* this is deliverable now */ @@ -5367,16 +5320,13 @@ sctp_kick_prsctp_reorder_queue(struct sctp_tcb *stcb, /* no more delivery now. */ break; } - ctl = nctl; } /* * now we must deliver things in queue the normal way if any are * now ready. */ tt = strmin->last_sequence_delivered + 1; - ctl = TAILQ_FIRST(&strmin->inqueue); - while (ctl) { - nctl = TAILQ_NEXT(ctl, next); + TAILQ_FOREACH_SAFE(ctl, &strmin->inqueue, next, nctl) { if (tt == ctl->sinfo_ssn) { /* this is deliverable now */ TAILQ_REMOVE(&strmin->inqueue, ctl, next); @@ -5396,7 +5346,6 @@ sctp_kick_prsctp_reorder_queue(struct sctp_tcb *stcb, } else { break; } - ctl = nctl; } } @@ -5405,87 +5354,73 @@ sctp_flush_reassm_for_str_seq(struct sctp_tcb *stcb, struct sctp_association *asoc, uint16_t stream, uint16_t seq) { - struct sctp_tmit_chunk *chk, *at; + struct sctp_tmit_chunk *chk, *nchk; - if (!TAILQ_EMPTY(&asoc->reasmqueue)) { - /* For each one on here see if we need to toss it */ + /* For each one on here see if we need to toss it */ + /* + * For now large messages held on the reasmqueue that are complete + * will be tossed too. We could in theory do more work to spin + * through and stop after dumping one msg aka seeing the start of a + * new msg at the head, and call the delivery function... to see if + * it can be delivered... But for now we just dump everything on the + * queue. + */ + TAILQ_FOREACH_SAFE(chk, &asoc->reasmqueue, sctp_next, nchk) { /* - * For now large messages held on the reasmqueue that are - * complete will be tossed too. We could in theory do more - * work to spin through and stop after dumping one msg aka - * seeing the start of a new msg at the head, and call the - * delivery function... to see if it can be delivered... But - * for now we just dump everything on the queue. + * Do not toss it if on a different stream or marked for + * unordered delivery in which case the stream sequence + * number has no meaning. */ - chk = TAILQ_FIRST(&asoc->reasmqueue); - while (chk) { - at = TAILQ_NEXT(chk, sctp_next); - /* - * Do not toss it if on a different stream or marked - * for unordered delivery in which case the stream - * sequence number has no meaning. - */ - if ((chk->rec.data.stream_number != stream) || - ((chk->rec.data.rcv_flags & SCTP_DATA_UNORDERED) == SCTP_DATA_UNORDERED)) { - chk = at; - continue; + if ((chk->rec.data.stream_number != stream) || + ((chk->rec.data.rcv_flags & SCTP_DATA_UNORDERED) == SCTP_DATA_UNORDERED)) { + continue; + } + if (chk->rec.data.stream_seq == seq) { + /* It needs to be tossed */ + TAILQ_REMOVE(&asoc->reasmqueue, chk, sctp_next); + if (compare_with_wrap(chk->rec.data.TSN_seq, + asoc->tsn_last_delivered, MAX_TSN)) { + asoc->tsn_last_delivered = chk->rec.data.TSN_seq; + asoc->str_of_pdapi = chk->rec.data.stream_number; + asoc->ssn_of_pdapi = chk->rec.data.stream_seq; + asoc->fragment_flags = chk->rec.data.rcv_flags; } - if (chk->rec.data.stream_seq == seq) { - /* It needs to be tossed */ - TAILQ_REMOVE(&asoc->reasmqueue, chk, sctp_next); - if (compare_with_wrap(chk->rec.data.TSN_seq, - asoc->tsn_last_delivered, MAX_TSN)) { - asoc->tsn_last_delivered = - chk->rec.data.TSN_seq; - asoc->str_of_pdapi = - chk->rec.data.stream_number; - asoc->ssn_of_pdapi = - chk->rec.data.stream_seq; - asoc->fragment_flags = - chk->rec.data.rcv_flags; - } - asoc->size_on_reasm_queue -= chk->send_size; - sctp_ucount_decr(asoc->cnt_on_reasm_queue); - - /* Clear up any stream problem */ - if ((chk->rec.data.rcv_flags & SCTP_DATA_UNORDERED) != - SCTP_DATA_UNORDERED && - (compare_with_wrap(chk->rec.data.stream_seq, - asoc->strmin[chk->rec.data.stream_number].last_sequence_delivered, - MAX_SEQ))) { - /* - * We must dump forward this streams - * sequence number if the chunk is - * not unordered that is being - * skipped. There is a chance that - * if the peer does not include the - * last fragment in its FWD-TSN we - * WILL have a problem here since - * you would have a partial chunk in - * queue that may not be - * deliverable. Also if a Partial - * delivery API as started the user - * may get a partial chunk. The next - * read returning a new chunk... - * really ugly but I see no way - * around it! Maybe a notify?? - */ - asoc->strmin[chk->rec.data.stream_number].last_sequence_delivered = - chk->rec.data.stream_seq; - } - if (chk->data) { - sctp_m_freem(chk->data); - chk->data = NULL; - } - sctp_free_a_chunk(stcb, chk); - } else if (compare_with_wrap(chk->rec.data.stream_seq, seq, MAX_SEQ)) { + asoc->size_on_reasm_queue -= chk->send_size; + sctp_ucount_decr(asoc->cnt_on_reasm_queue); + + /* Clear up any stream problem */ + if ((chk->rec.data.rcv_flags & SCTP_DATA_UNORDERED) != + SCTP_DATA_UNORDERED && + (compare_with_wrap(chk->rec.data.stream_seq, + asoc->strmin[chk->rec.data.stream_number].last_sequence_delivered, + MAX_SEQ))) { /* - * If the stream_seq is > than the purging - * one, we are done + * We must dump forward this streams + * sequence number if the chunk is not + * unordered that is being skipped. There is + * a chance that if the peer does not + * include the last fragment in its FWD-TSN + * we WILL have a problem here since you + * would have a partial chunk in queue that + * may not be deliverable. Also if a Partial + * delivery API as started the user may get + * a partial chunk. The next read returning + * a new chunk... really ugly but I see no + * way around it! Maybe a notify?? */ - break; + asoc->strmin[chk->rec.data.stream_number].last_sequence_delivered = chk->rec.data.stream_seq; + } + if (chk->data) { + sctp_m_freem(chk->data); + chk->data = NULL; } - chk = at; + sctp_free_a_chunk(stcb, chk); + } else if (compare_with_wrap(chk->rec.data.stream_seq, seq, MAX_SEQ)) { + /* + * If the stream_seq is > than the purging one, we + * are done + */ + break; } } } @@ -5524,7 +5459,7 @@ sctp_handle_forward_tsn(struct sctp_tcb *stcb, unsigned int i, fwd_sz, cumack_set_flag, m_size; uint32_t str_seq; struct sctp_stream_in *strm; - struct sctp_tmit_chunk *chk, *at; + struct sctp_tmit_chunk *chk, *nchk; struct sctp_queued_to_read *ctl, *sv; cumack_set_flag = 0; @@ -5618,77 +5553,64 @@ sctp_handle_forward_tsn(struct sctp_tcb *stcb, if (asoc->fragmented_delivery_inprogress) { sctp_service_reassembly(stcb, asoc); } - if (!TAILQ_EMPTY(&asoc->reasmqueue)) { - /* For each one on here see if we need to toss it */ - /* - * For now large messages held on the reasmqueue that are - * complete will be tossed too. We could in theory do more - * work to spin through and stop after dumping one msg aka - * seeing the start of a new msg at the head, and call the - * delivery function... to see if it can be delivered... But - * for now we just dump everything on the queue. - */ - chk = TAILQ_FIRST(&asoc->reasmqueue); - while (chk) { - at = TAILQ_NEXT(chk, sctp_next); - if ((compare_with_wrap(new_cum_tsn, - chk->rec.data.TSN_seq, MAX_TSN)) || - (new_cum_tsn == chk->rec.data.TSN_seq)) { - /* It needs to be tossed */ - TAILQ_REMOVE(&asoc->reasmqueue, chk, sctp_next); - if (compare_with_wrap(chk->rec.data.TSN_seq, - asoc->tsn_last_delivered, MAX_TSN)) { - asoc->tsn_last_delivered = - chk->rec.data.TSN_seq; - asoc->str_of_pdapi = - chk->rec.data.stream_number; - asoc->ssn_of_pdapi = - chk->rec.data.stream_seq; - asoc->fragment_flags = - chk->rec.data.rcv_flags; - } - asoc->size_on_reasm_queue -= chk->send_size; - sctp_ucount_decr(asoc->cnt_on_reasm_queue); - - /* Clear up any stream problem */ - if ((chk->rec.data.rcv_flags & SCTP_DATA_UNORDERED) != - SCTP_DATA_UNORDERED && - (compare_with_wrap(chk->rec.data.stream_seq, - asoc->strmin[chk->rec.data.stream_number].last_sequence_delivered, - MAX_SEQ))) { - /* - * We must dump forward this streams - * sequence number if the chunk is - * not unordered that is being - * skipped. There is a chance that - * if the peer does not include the - * last fragment in its FWD-TSN we - * WILL have a problem here since - * you would have a partial chunk in - * queue that may not be - * deliverable. Also if a Partial - * delivery API as started the user - * may get a partial chunk. The next - * read returning a new chunk... - * really ugly but I see no way - * around it! Maybe a notify?? - */ - asoc->strmin[chk->rec.data.stream_number].last_sequence_delivered = - chk->rec.data.stream_seq; - } - if (chk->data) { - sctp_m_freem(chk->data); - chk->data = NULL; - } - sctp_free_a_chunk(stcb, chk); - } else { + /* For each one on here see if we need to toss it */ + /* + * For now large messages held on the reasmqueue that are complete + * will be tossed too. We could in theory do more work to spin + * through and stop after dumping one msg aka seeing the start of a + * new msg at the head, and call the delivery function... to see if + * it can be delivered... But for now we just dump everything on the + * queue. + */ + TAILQ_FOREACH_SAFE(chk, &asoc->reasmqueue, sctp_next, nchk) { + if ((compare_with_wrap(new_cum_tsn, + chk->rec.data.TSN_seq, MAX_TSN)) || + (new_cum_tsn == chk->rec.data.TSN_seq)) { + /* It needs to be tossed */ + TAILQ_REMOVE(&asoc->reasmqueue, chk, sctp_next); + if (compare_with_wrap(chk->rec.data.TSN_seq, + asoc->tsn_last_delivered, MAX_TSN)) { + asoc->tsn_last_delivered = chk->rec.data.TSN_seq; + asoc->str_of_pdapi = chk->rec.data.stream_number; + asoc->ssn_of_pdapi = chk->rec.data.stream_seq; + asoc->fragment_flags = chk->rec.data.rcv_flags; + } + asoc->size_on_reasm_queue -= chk->send_size; + sctp_ucount_decr(asoc->cnt_on_reasm_queue); + + /* Clear up any stream problem */ + if ((chk->rec.data.rcv_flags & SCTP_DATA_UNORDERED) != + SCTP_DATA_UNORDERED && + (compare_with_wrap(chk->rec.data.stream_seq, + asoc->strmin[chk->rec.data.stream_number].last_sequence_delivered, + MAX_SEQ))) { /* - * Ok we have gone beyond the end of the - * fwd-tsn's mark. + * We must dump forward this streams + * sequence number if the chunk is not + * unordered that is being skipped. There is + * a chance that if the peer does not + * include the last fragment in its FWD-TSN + * we WILL have a problem here since you + * would have a partial chunk in queue that + * may not be deliverable. Also if a Partial + * delivery API as started the user may get + * a partial chunk. The next read returning + * a new chunk... really ugly but I see no + * way around it! Maybe a notify?? */ - break; + asoc->strmin[chk->rec.data.stream_number].last_sequence_delivered = chk->rec.data.stream_seq; } - chk = at; + if (chk->data) { + sctp_m_freem(chk->data); + chk->data = NULL; + } + sctp_free_a_chunk(stcb, chk); + } else { + /* + * Ok we have gone beyond the end of the fwd-tsn's + * mark. + */ + break; } } /*******************************************************/ diff --git a/sys/netinet/sctp_input.c b/sys/netinet/sctp_input.c index 08b4b6585408..179673f37eb0 100644 --- a/sys/netinet/sctp_input.c +++ b/sys/netinet/sctp_input.c @@ -193,7 +193,7 @@ int sctp_is_there_unsent_data(struct sctp_tcb *stcb) { int unsent_data = 0; - struct sctp_stream_queue_pending *sp; + struct sctp_stream_queue_pending *sp, *nsp; struct sctp_stream_out *strq; struct sctp_association *asoc; @@ -205,15 +205,9 @@ sctp_is_there_unsent_data(struct sctp_tcb *stcb) */ asoc = &stcb->asoc; SCTP_TCB_SEND_LOCK(stcb); - if (!TAILQ_EMPTY(&asoc->out_wheel)) { - /* Check to see if some data queued */ - TAILQ_FOREACH(strq, &asoc->out_wheel, next_spoke) { - is_there_another: - /* sa_ignore FREED_MEMORY */ - sp = TAILQ_FIRST(&strq->outqueue); - if (sp == NULL) { - continue; - } + TAILQ_FOREACH(strq, &asoc->out_wheel, next_spoke) { + /* sa_ignore FREED_MEMORY */ + TAILQ_FOREACH_SAFE(sp, &strq->outqueue, next, nsp) { if ((sp->msg_is_complete) && (sp->length == 0) && (sp->sender_all_done)) { @@ -230,7 +224,7 @@ sctp_is_there_unsent_data(struct sctp_tcb *stcb) sp->msg_is_complete, sp->put_last_out); } - atomic_subtract_int(&stcb->asoc.stream_queue_cnt, 1); + atomic_subtract_int(&asoc->stream_queue_cnt, 1); TAILQ_REMOVE(&strq->outqueue, sp, next); if (sp->net) { sctp_free_remote_addr(sp->net); @@ -241,10 +235,9 @@ sctp_is_there_unsent_data(struct sctp_tcb *stcb) sp->data = NULL; } sctp_free_a_strmoq(stcb, sp); - goto is_there_another; } else { unsent_data++; - continue; + break; } } } @@ -280,38 +273,32 @@ sctp_process_init(struct sctp_init_chunk *cp, struct sctp_tcb *stcb, if (asoc->pre_open_streams > ntohs(init->num_inbound_streams)) { unsigned int newcnt; struct sctp_stream_out *outs; - struct sctp_stream_queue_pending *sp; - struct sctp_tmit_chunk *chk, *chk_next; + struct sctp_stream_queue_pending *sp, *nsp; + struct sctp_tmit_chunk *chk, *nchk; /* abandon the upper streams */ newcnt = ntohs(init->num_inbound_streams); - if (!TAILQ_EMPTY(&asoc->send_queue)) { - chk = TAILQ_FIRST(&asoc->send_queue); - while (chk) { - chk_next = TAILQ_NEXT(chk, sctp_next); - if (chk->rec.data.stream_number >= newcnt) { - TAILQ_REMOVE(&asoc->send_queue, chk, sctp_next); - asoc->send_queue_cnt--; - if (chk->data != NULL) { - sctp_free_bufspace(stcb, asoc, chk, 1); - sctp_ulp_notify(SCTP_NOTIFY_DG_FAIL, stcb, - SCTP_NOTIFY_DATAGRAM_UNSENT, chk, SCTP_SO_NOT_LOCKED); - if (chk->data) { - sctp_m_freem(chk->data); - chk->data = NULL; - } + TAILQ_FOREACH_SAFE(chk, &asoc->send_queue, sctp_next, nchk) { + if (chk->rec.data.stream_number >= newcnt) { + TAILQ_REMOVE(&asoc->send_queue, chk, sctp_next); + asoc->send_queue_cnt--; + if (chk->data != NULL) { + sctp_free_bufspace(stcb, asoc, chk, 1); + sctp_ulp_notify(SCTP_NOTIFY_DG_FAIL, stcb, + SCTP_NOTIFY_DATAGRAM_UNSENT, chk, SCTP_SO_NOT_LOCKED); + if (chk->data) { + sctp_m_freem(chk->data); + chk->data = NULL; } - sctp_free_a_chunk(stcb, chk); - /* sa_ignore FREED_MEMORY */ } - chk = chk_next; + sctp_free_a_chunk(stcb, chk); + /* sa_ignore FREED_MEMORY */ } } if (asoc->strmout) { for (i = newcnt; i < asoc->pre_open_streams; i++) { outs = &asoc->strmout[i]; - sp = TAILQ_FIRST(&outs->outqueue); - while (sp) { + TAILQ_FOREACH_SAFE(sp, &outs->outqueue, next, nsp) { TAILQ_REMOVE(&outs->outqueue, sp, next); asoc->stream_queue_cnt--; sctp_ulp_notify(SCTP_NOTIFY_SPECIAL_SP_FAIL, @@ -328,7 +315,6 @@ sctp_process_init(struct sctp_init_chunk *cp, struct sctp_tcb *stcb, /* Free the chunk */ sctp_free_a_strmoq(stcb, sp); /* sa_ignore FREED_MEMORY */ - sp = TAILQ_FIRST(&outs->outqueue); } } } @@ -355,18 +341,16 @@ sctp_process_init(struct sctp_init_chunk *cp, struct sctp_tcb *stcb, if (asoc->strmin != NULL) { /* Free the old ones */ - struct sctp_queued_to_read *ctl; + struct sctp_queued_to_read *ctl, *nctl; for (i = 0; i < asoc->streamincnt; i++) { - ctl = TAILQ_FIRST(&asoc->strmin[i].inqueue); - while (ctl) { + TAILQ_FOREACH_SAFE(ctl, &asoc->strmin[i].inqueue, next, nctl) { TAILQ_REMOVE(&asoc->strmin[i].inqueue, ctl, next); sctp_free_remote_addr(ctl->whoFrom); ctl->whoFrom = NULL; sctp_m_freem(ctl->data); ctl->data = NULL; sctp_free_a_readq(stcb, ctl); - ctl = TAILQ_FIRST(&asoc->strmin[i].inqueue); } } SCTP_FREE(asoc->strmin, SCTP_M_STRMI); @@ -456,13 +440,11 @@ sctp_process_init_ack(struct mbuf *m, int iphlen, int offset, } /* if the peer doesn't support asconf, flush the asconf queue */ if (asoc->peer_supports_asconf == 0) { - struct sctp_asconf_addr *aparam; + struct sctp_asconf_addr *param, *nparam; - while (!TAILQ_EMPTY(&asoc->asconf_queue)) { - /* sa_ignore FREED_MEMORY */ - aparam = TAILQ_FIRST(&asoc->asconf_queue); - TAILQ_REMOVE(&asoc->asconf_queue, aparam, next); - SCTP_FREE(aparam, SCTP_M_ASC_ADDR); + TAILQ_FOREACH_SAFE(param, &asoc->asconf_queue, next, nparam) { + TAILQ_REMOVE(&asoc->asconf_queue, param, next); + SCTP_FREE(param, SCTP_M_ASC_ADDR); } } stcb->asoc.peer_hmac_id = sctp_negotiate_hmacid(stcb->asoc.peer_hmacs, @@ -2905,10 +2887,7 @@ sctp_handle_cookie_ack(struct sctp_cookie_ack_chunk *cp, struct sctp_tmit_chunk *chk; chk = TAILQ_FIRST(&asoc->sent_queue); - if (chk) { - sctp_timer_start(SCTP_TIMER_TYPE_SEND, stcb->sctp_ep, - stcb, chk->whoTo); - } + sctp_timer_start(SCTP_TIMER_TYPE_SEND, stcb->sctp_ep, stcb, chk->whoTo); } } @@ -2938,15 +2917,13 @@ sctp_handle_ecn_echo(struct sctp_ecne_chunk *cp, /* Find where it was sent, if possible */ net = NULL; - lchk = TAILQ_FIRST(&stcb->asoc.sent_queue); - while (lchk) { + TAILQ_FOREACH(lchk, &stcb->asoc.sent_queue, sctp_next) { if (lchk->rec.data.TSN_seq == tsn) { net = lchk->whoTo; break; } if (compare_with_wrap(lchk->rec.data.TSN_seq, tsn, MAX_TSN)) break; - lchk = TAILQ_NEXT(lchk, sctp_next); } if (net == NULL) /* default is we use the primary */ @@ -3078,8 +3055,7 @@ process_chunk_drop(struct sctp_tcb *stcb, struct sctp_chunk_desc *desc, struct sctp_tmit_chunk *tp1; tsn = ntohl(desc->tsn_ifany); - tp1 = TAILQ_FIRST(&stcb->asoc.sent_queue); - while (tp1) { + TAILQ_FOREACH(tp1, &stcb->asoc.sent_queue, sctp_next) { if (tp1->rec.data.TSN_seq == tsn) { /* found it */ break; @@ -3090,7 +3066,6 @@ process_chunk_drop(struct sctp_tcb *stcb, struct sctp_chunk_desc *desc, tp1 = NULL; break; } - tp1 = TAILQ_NEXT(tp1, sctp_next); } if (tp1 == NULL) { /* @@ -3098,13 +3073,11 @@ process_chunk_drop(struct sctp_tcb *stcb, struct sctp_chunk_desc *desc, * attention to queue seq order. */ SCTP_STAT_INCR(sctps_pdrpdnfnd); - tp1 = TAILQ_FIRST(&stcb->asoc.sent_queue); - while (tp1) { + TAILQ_FOREACH(tp1, &stcb->asoc.sent_queue, sctp_next) { if (tp1->rec.data.TSN_seq == tsn) { /* found it */ break; } - tp1 = TAILQ_NEXT(tp1, sctp_next); } } if (tp1 == NULL) { @@ -3755,7 +3728,7 @@ sctp_handle_str_reset_add_strm(struct sctp_tcb *stcb, struct sctp_tmit_chunk *ch uint16_t num_stream, i; uint32_t seq; struct sctp_association *asoc = &stcb->asoc; - struct sctp_queued_to_read *ctl; + struct sctp_queued_to_read *ctl, *nctl; /* Get the number. */ seq = ntohl(str_add->request_seq); @@ -3789,8 +3762,7 @@ sctp_handle_str_reset_add_strm(struct sctp_tcb *stcb, struct sctp_tmit_chunk *ch stcb->asoc.strmin[i].last_sequence_delivered = oldstrm[i].last_sequence_delivered; stcb->asoc.strmin[i].delivery_started = oldstrm[i].delivery_started; /* now anything on those queues? */ - while (TAILQ_EMPTY(&oldstrm[i].inqueue) == 0) { - ctl = TAILQ_FIRST(&oldstrm[i].inqueue); + TAILQ_FOREACH_SAFE(ctl, &oldstrm[i].inqueue, next, nctl) { TAILQ_REMOVE(&oldstrm[i].inqueue, ctl, next); TAILQ_INSERT_TAIL(&stcb->asoc.strmin[i].inqueue, ctl, next); } @@ -4965,11 +4937,7 @@ process_control_chunks: struct sctp_tmit_chunk *chk; chk = TAILQ_FIRST(&stcb->asoc.sent_queue); - if (chk) { - sctp_timer_start(SCTP_TIMER_TYPE_SEND, - stcb->sctp_ep, stcb, - chk->whoTo); - } + sctp_timer_start(SCTP_TIMER_TYPE_SEND, stcb->sctp_ep, stcb, chk->whoTo); } } break; diff --git a/sys/netinet/sctp_output.c b/sys/netinet/sctp_output.c index abe124eaffb7..58fe164eb4ba 100644 --- a/sys/netinet/sctp_output.c +++ b/sys/netinet/sctp_output.c @@ -5718,9 +5718,7 @@ sctp_prune_prsctp(struct sctp_tcb *stcb, } /* if chunk has enabled */ } /* tailqforeach */ - chk = TAILQ_FIRST(&asoc->send_queue); - while (chk) { - nchk = TAILQ_NEXT(chk, sctp_next); + TAILQ_FOREACH_SAFE(chk, &asoc->send_queue, sctp_next, nchk) { /* Here we must move to the sent queue and mark */ if (PR_SCTP_BUF_ENABLED(chk->flags)) { if (chk->rec.data.timetodrop.tv_sec >= (long)srcv->sinfo_timetolive) { @@ -5742,8 +5740,7 @@ sctp_prune_prsctp(struct sctp_tcb *stcb, } /* end if chk->data */ } /* end if right class */ } /* end if chk pr-sctp */ - chk = nchk; - } /* end while (chk) */ + } /* tailqforeachsafe (chk) */ } /* if enabled in asoc */ } @@ -6445,9 +6442,7 @@ sctp_toss_old_cookies(struct sctp_tcb *stcb, struct sctp_association *asoc) { struct sctp_tmit_chunk *chk, *nchk; - chk = TAILQ_FIRST(&asoc->control_send_queue); - while (chk) { - nchk = TAILQ_NEXT(chk, sctp_next); + TAILQ_FOREACH_SAFE(chk, &asoc->control_send_queue, sctp_next, nchk) { if (chk->rec.chunk_id.id == SCTP_COOKIE_ECHO) { TAILQ_REMOVE(&asoc->control_send_queue, chk, sctp_next); if (chk->data) { @@ -6457,7 +6452,6 @@ sctp_toss_old_cookies(struct sctp_tcb *stcb, struct sctp_association *asoc) asoc->ctrl_queue_cnt--; sctp_free_a_chunk(stcb, chk); } - chk = nchk; } } @@ -6465,19 +6459,16 @@ void sctp_toss_old_asconf(struct sctp_tcb *stcb) { struct sctp_association *asoc; - struct sctp_tmit_chunk *chk, *chk_tmp; + struct sctp_tmit_chunk *chk, *nchk; struct sctp_asconf_chunk *acp; asoc = &stcb->asoc; - for (chk = TAILQ_FIRST(&asoc->asconf_send_queue); chk != NULL; - chk = chk_tmp) { - /* get next chk */ - chk_tmp = TAILQ_NEXT(chk, sctp_next); + TAILQ_FOREACH_SAFE(chk, &asoc->asconf_send_queue, sctp_next, nchk) { /* find SCTP_ASCONF chunk in queue */ if (chk->rec.chunk_id.id == SCTP_ASCONF) { if (chk->data) { acp = mtod(chk->data, struct sctp_asconf_chunk *); - if (compare_with_wrap(ntohl(acp->serial_number), stcb->asoc.asconf_seq_out_acked, MAX_TSN)) { + if (compare_with_wrap(ntohl(acp->serial_number), asoc->asconf_seq_out_acked, MAX_TSN)) { /* Not Acked yet */ break; } @@ -6589,9 +6580,7 @@ sctp_clean_up_ctl(struct sctp_tcb *stcb, struct sctp_association *asoc) { struct sctp_tmit_chunk *chk, *nchk; - for (chk = TAILQ_FIRST(&asoc->control_send_queue); - chk; chk = nchk) { - nchk = TAILQ_NEXT(chk, sctp_next); + TAILQ_FOREACH_SAFE(chk, &asoc->control_send_queue, sctp_next, nchk) { if ((chk->rec.chunk_id.id == SCTP_SELECTIVE_ACK) || (chk->rec.chunk_id.id == SCTP_NR_SELECTIVE_ACK) || /* EY */ (chk->rec.chunk_id.id == SCTP_HEARTBEAT_REQUEST) || @@ -7627,9 +7616,7 @@ again_one_more_time: /* ASCONF transmission */ /************************/ /* Now first lets go through the asconf queue */ - for (chk = TAILQ_FIRST(&asoc->asconf_send_queue); - chk; chk = nchk) { - nchk = TAILQ_NEXT(chk, sctp_next); + TAILQ_FOREACH_SAFE(chk, &asoc->asconf_send_queue, sctp_next, nchk) { if (chk->rec.chunk_id.id != SCTP_ASCONF) { continue; } @@ -7805,9 +7792,7 @@ again_one_more_time: /* Control transmission */ /************************/ /* Now first lets go through the control queue */ - for (chk = TAILQ_FIRST(&asoc->control_send_queue); - chk; chk = nchk) { - nchk = TAILQ_NEXT(chk, sctp_next); + TAILQ_FOREACH_SAFE(chk, &asoc->control_send_queue, sctp_next, nchk) { if (chk->whoTo != net) { /* * No, not sent to the network we are @@ -8091,7 +8076,7 @@ again_one_more_time: if ((((asoc->state & SCTP_STATE_OPEN) == SCTP_STATE_OPEN) && (skip_data_for_this_net == 0)) || (cookie)) { - for (chk = TAILQ_FIRST(&asoc->send_queue); chk; chk = nchk) { + TAILQ_FOREACH_SAFE(chk, &asoc->send_queue, sctp_next, nchk) { if (no_data_chunks) { /* let only control go out */ *reason_code = 1; @@ -8102,7 +8087,6 @@ again_one_more_time: *reason_code = 2; break; } - nchk = TAILQ_NEXT(chk, sctp_next); if ((chk->whoTo != NULL) && (chk->whoTo != net)) { /* Don't send the chunk on this net */ diff --git a/sys/netinet/sctp_pcb.c b/sys/netinet/sctp_pcb.c index 949121e88b05..0f3d19ac160e 100644 --- a/sys/netinet/sctp_pcb.c +++ b/sys/netinet/sctp_pcb.c @@ -3154,11 +3154,8 @@ sctp_iterator_inp_being_freed(struct sctp_inpcb *inp) * may be still pending on the list */ SCTP_IPI_ITERATOR_WQ_LOCK(); - it = TAILQ_FIRST(&sctp_it_ctl.iteratorhead); - while (it) { - nit = TAILQ_NEXT(it, sctp_nxt_itr); + TAILQ_FOREACH_SAFE(it, &sctp_it_ctl.iteratorhead, sctp_nxt_itr, nit) { if (it->vn != curvnet) { - it = nit; continue; } if (it->inp == inp) { @@ -3183,7 +3180,6 @@ sctp_iterator_inp_being_freed(struct sctp_inpcb *inp) */ SCTP_INP_DECR_REF(inp); } - it = nit; } SCTP_IPI_ITERATOR_WQ_UNLOCK(); } @@ -3206,11 +3202,9 @@ sctp_inpcb_free(struct sctp_inpcb *inp, int immediate, int from) struct inpcb *ip_pcb; struct socket *so; int being_refed = 0; - struct sctp_queued_to_read *sq; - - + struct sctp_queued_to_read *sq, *nsq; int cnt; - sctp_sharedkey_t *shared_key; + sctp_sharedkey_t *shared_key, *nshared_key; #ifdef SCTP_LOG_CLOSING @@ -3261,10 +3255,8 @@ sctp_inpcb_free(struct sctp_inpcb *inp, int immediate, int from) int cnt_in_sd; cnt_in_sd = 0; - for ((asoc = LIST_FIRST(&inp->sctp_asoc_list)); asoc != NULL; - asoc = nasoc) { + LIST_FOREACH_SAFE(asoc, &inp->sctp_asoc_list, sctp_tcblist, nasoc) { SCTP_TCB_LOCK(asoc); - nasoc = LIST_NEXT(asoc, sctp_tcblist); if (asoc->asoc.state & SCTP_STATE_ABOUT_TO_BE_FREED) { /* Skip guys being freed */ cnt_in_sd++; @@ -3463,10 +3455,8 @@ sctp_inpcb_free(struct sctp_inpcb *inp, int immediate, int from) * have a contest on the INP lock.. which would cause us to die ... */ cnt = 0; - for ((asoc = LIST_FIRST(&inp->sctp_asoc_list)); asoc != NULL; - asoc = nasoc) { + LIST_FOREACH_SAFE(asoc, &inp->sctp_asoc_list, sctp_tcblist, nasoc) { SCTP_TCB_LOCK(asoc); - nasoc = LIST_NEXT(asoc, sctp_tcblist); if (asoc->asoc.state & SCTP_STATE_ABOUT_TO_BE_FREED) { if (asoc->asoc.state & SCTP_STATE_IN_ACCEPT_QUEUE) { asoc->asoc.state &= ~SCTP_STATE_IN_ACCEPT_QUEUE; @@ -3581,7 +3571,7 @@ sctp_inpcb_free(struct sctp_inpcb *inp, int immediate, int from) inp->sctp_asocidhash = NULL; } /* sa_ignore FREED_MEMORY */ - while ((sq = TAILQ_FIRST(&inp->read_queue)) != NULL) { + TAILQ_FOREACH_SAFE(sq, &inp->read_queue, next, nsq) { /* Its only abandoned if it had data left */ if (sq->length) SCTP_STAT_INCR(sctps_left_abandon); @@ -3638,12 +3628,10 @@ sctp_inpcb_free(struct sctp_inpcb *inp, int immediate, int from) if (inp->sctp_ep.local_hmacs != NULL) sctp_free_hmaclist(inp->sctp_ep.local_hmacs); - shared_key = LIST_FIRST(&inp->sctp_ep.shared_keys); - while (shared_key) { + LIST_FOREACH_SAFE(shared_key, &inp->sctp_ep.shared_keys, next, nshared_key) { LIST_REMOVE(shared_key, next); sctp_free_sharedkey(shared_key); /* sa_ignore FREED_MEMORY */ - shared_key = LIST_FIRST(&inp->sctp_ep.shared_keys); } /* @@ -3651,17 +3639,13 @@ sctp_inpcb_free(struct sctp_inpcb *inp, int immediate, int from) * ifaddr's that are set into this ep. Again macro limitations here, * since the LIST_FOREACH could be a bad idea. */ - for ((laddr = LIST_FIRST(&inp->sctp_addr_list)); laddr != NULL; - laddr = nladdr) { - nladdr = LIST_NEXT(laddr, sctp_nxt_addr); + LIST_FOREACH_SAFE(laddr, &inp->sctp_addr_list, sctp_nxt_addr, nladdr) { sctp_remove_laddr(laddr); } #ifdef SCTP_TRACK_FREED_ASOCS /* TEMP CODE */ - for ((asoc = LIST_FIRST(&inp->sctp_asoc_free_list)); asoc != NULL; - asoc = nasoc) { - nasoc = LIST_NEXT(asoc, sctp_tcblist); + LIST_FOREACH_SAFE(asoc, &inp->sctp_asoc_free_list, sctp_tcblist, nasoc) { LIST_REMOVE(asoc, sctp_tcblist); SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_asoc), asoc); SCTP_DECR_ASOC_COUNT(); @@ -4359,13 +4343,12 @@ sctp_del_remote_addr(struct sctp_tcb *stcb, struct sockaddr *remaddr) * no other addresses. */ struct sctp_association *asoc; - struct sctp_nets *net, *net_tmp; + struct sctp_nets *net, *nnet; asoc = &stcb->asoc; /* locate the address */ - for (net = TAILQ_FIRST(&asoc->nets); net != NULL; net = net_tmp) { - net_tmp = TAILQ_NEXT(net, sctp_next); + TAILQ_FOREACH_SAFE(net, &asoc->nets, sctp_next, nnet) { if (net->ro._l_addr.sa.sa_family != remaddr->sa_family) { continue; } @@ -4530,18 +4513,16 @@ sctp_free_assoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb, int from_inpcbfre { int i; struct sctp_association *asoc; - struct sctp_nets *net, *prev; - struct sctp_laddr *laddr; - struct sctp_tmit_chunk *chk; - struct sctp_asconf_addr *aparam; - struct sctp_asconf_ack *aack; - struct sctp_stream_reset_list *liste; - struct sctp_queued_to_read *sq; - struct sctp_stream_queue_pending *sp; - sctp_sharedkey_t *shared_key; + struct sctp_nets *net, *nnet; + struct sctp_laddr *laddr, *naddr; + struct sctp_tmit_chunk *chk, *nchk; + struct sctp_asconf_addr *aparam, *naparam; + struct sctp_asconf_ack *aack, *naack; + struct sctp_stream_reset_list *strrst, *nstrrst; + struct sctp_queued_to_read *sq, *nsq; + struct sctp_stream_queue_pending *sp, *nsp; + sctp_sharedkey_t *shared_key, *nshared_key; struct socket *so; - int ccnt = 0; - int cnt = 0; /* first, lets purge the entry from the hash table. */ @@ -4626,7 +4607,6 @@ sctp_free_assoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb, int from_inpcbfre net->pmtu_timer.self = NULL; } /* Now the read queue needs to be cleaned up (only once) */ - cnt = 0; if ((stcb->asoc.state & SCTP_STATE_ABOUT_TO_BE_FREED) == 0) { stcb->asoc.state |= SCTP_STATE_ABOUT_TO_BE_FREED; SCTP_INP_READ_LOCK(inp); @@ -4665,12 +4645,10 @@ sctp_free_assoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb, int from_inpcbfre } /* Add an end to wake them */ sq->end_added = 1; - cnt++; } } SCTP_INP_READ_UNLOCK(inp); if (stcb->block_entry) { - cnt++; SCTP_LTRACE_ERR_RET(inp, stcb, NULL, SCTP_FROM_SCTP_PCB, ECONNRESET); stcb->block_entry->error = ECONNRESET; stcb->block_entry = NULL; @@ -4808,7 +4786,6 @@ sctp_free_assoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb, int from_inpcbfre } asoc->strreset_timer.type = SCTP_TIMER_TYPE_NONE; - prev = NULL; /* * The chunk lists and such SHOULD be empty but we check them just * in case. @@ -4819,8 +4796,7 @@ sctp_free_assoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb, int from_inpcbfre outs = &asoc->strmout[i]; /* now clean up any chunks here */ - sp = TAILQ_FIRST(&outs->outqueue); - while (sp) { + TAILQ_FOREACH_SAFE(sp, &outs->outqueue, next, nsp) { TAILQ_REMOVE(&outs->outqueue, sp, next); if (sp->data) { if (so) { @@ -4846,18 +4822,14 @@ sctp_free_assoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb, int from_inpcbfre SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_strmoq), sp); SCTP_DECR_STRMOQ_COUNT(); /* sa_ignore FREED_MEMORY */ - sp = TAILQ_FIRST(&outs->outqueue); } } - /* sa_ignore FREED_MEMORY */ - while ((liste = TAILQ_FIRST(&asoc->resetHead)) != NULL) { - TAILQ_REMOVE(&asoc->resetHead, liste, next_resp); - SCTP_FREE(liste, SCTP_M_STRESET); + TAILQ_FOREACH_SAFE(strrst, &asoc->resetHead, next_resp, nstrrst) { + TAILQ_REMOVE(&asoc->resetHead, strrst, next_resp); + SCTP_FREE(strrst, SCTP_M_STRESET); } - - sq = TAILQ_FIRST(&asoc->pending_reply_queue); - while (sq) { + TAILQ_FOREACH_SAFE(sq, &asoc->pending_reply_queue, next, nsq) { TAILQ_REMOVE(&asoc->pending_reply_queue, sq, next); if (sq->data) { sctp_m_freem(sq->data); @@ -4870,11 +4842,8 @@ sctp_free_assoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb, int from_inpcbfre SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_readq), sq); SCTP_DECR_READQ_COUNT(); /* sa_ignore FREED_MEMORY */ - sq = TAILQ_FIRST(&asoc->pending_reply_queue); } - - chk = TAILQ_FIRST(&asoc->free_chunks); - while (chk) { + TAILQ_FOREACH_SAFE(chk, &asoc->free_chunks, sctp_next, nchk) { TAILQ_REMOVE(&asoc->free_chunks, chk, sctp_next); if (chk->data) { sctp_m_freem(chk->data); @@ -4882,156 +4851,99 @@ sctp_free_assoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb, int from_inpcbfre } if (chk->holds_key_ref) sctp_auth_key_release(stcb, chk->auth_keyid); - ccnt++; SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_chunk), chk); SCTP_DECR_CHK_COUNT(); atomic_subtract_int(&SCTP_BASE_INFO(ipi_free_chunks), 1); asoc->free_chunk_cnt--; /* sa_ignore FREED_MEMORY */ - chk = TAILQ_FIRST(&asoc->free_chunks); } /* pending send queue SHOULD be empty */ - if (!TAILQ_EMPTY(&asoc->send_queue)) { - chk = TAILQ_FIRST(&asoc->send_queue); - while (chk) { - TAILQ_REMOVE(&asoc->send_queue, chk, sctp_next); - if (chk->data) { - if (so) { - /* Still a socket? */ - sctp_ulp_notify(SCTP_NOTIFY_DG_FAIL, stcb, - SCTP_NOTIFY_DATAGRAM_UNSENT, chk, SCTP_SO_LOCKED); - } - if (chk->data) { - sctp_m_freem(chk->data); - chk->data = NULL; - } - } - if (chk->holds_key_ref) - sctp_auth_key_release(stcb, chk->auth_keyid); - ccnt++; - if (chk->whoTo) { - sctp_free_remote_addr(chk->whoTo); - chk->whoTo = NULL; + TAILQ_FOREACH_SAFE(chk, &asoc->send_queue, sctp_next, nchk) { + TAILQ_REMOVE(&asoc->send_queue, chk, sctp_next); + if (chk->data) { + if (so) { + /* Still a socket? */ + sctp_ulp_notify(SCTP_NOTIFY_DG_FAIL, stcb, + SCTP_NOTIFY_DATAGRAM_UNSENT, chk, SCTP_SO_LOCKED); } - SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_chunk), chk); - SCTP_DECR_CHK_COUNT(); - /* sa_ignore FREED_MEMORY */ - chk = TAILQ_FIRST(&asoc->send_queue); - } - } -/* - if (ccnt) { - printf("Freed %d from send_queue\n", ccnt); - ccnt = 0; - } -*/ - /* sent queue SHOULD be empty */ - if (!TAILQ_EMPTY(&asoc->sent_queue)) { - chk = TAILQ_FIRST(&asoc->sent_queue); - while (chk) { - TAILQ_REMOVE(&asoc->sent_queue, chk, sctp_next); if (chk->data) { - if (so) { - /* Still a socket? */ - sctp_ulp_notify(SCTP_NOTIFY_DG_FAIL, stcb, - SCTP_NOTIFY_DATAGRAM_SENT, chk, SCTP_SO_LOCKED); - } - if (chk->data) { - sctp_m_freem(chk->data); - chk->data = NULL; - } + sctp_m_freem(chk->data); + chk->data = NULL; } - if (chk->holds_key_ref) - sctp_auth_key_release(stcb, chk->auth_keyid); - ccnt++; + } + if (chk->holds_key_ref) + sctp_auth_key_release(stcb, chk->auth_keyid); + if (chk->whoTo) { sctp_free_remote_addr(chk->whoTo); - SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_chunk), chk); - SCTP_DECR_CHK_COUNT(); - /* sa_ignore FREED_MEMORY */ - chk = TAILQ_FIRST(&asoc->sent_queue); + chk->whoTo = NULL; } + SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_chunk), chk); + SCTP_DECR_CHK_COUNT(); + /* sa_ignore FREED_MEMORY */ } -/* - if (ccnt) { - printf("Freed %d from sent_queue\n", ccnt); - ccnt = 0; - } -*/ - /* control queue MAY not be empty */ - if (!TAILQ_EMPTY(&asoc->control_send_queue)) { - chk = TAILQ_FIRST(&asoc->control_send_queue); - while (chk) { - TAILQ_REMOVE(&asoc->control_send_queue, chk, sctp_next); + /* sent queue SHOULD be empty */ + TAILQ_FOREACH_SAFE(chk, &asoc->sent_queue, sctp_next, nchk) { + TAILQ_REMOVE(&asoc->sent_queue, chk, sctp_next); + if (chk->data) { + if (so) { + /* Still a socket? */ + sctp_ulp_notify(SCTP_NOTIFY_DG_FAIL, stcb, + SCTP_NOTIFY_DATAGRAM_SENT, chk, SCTP_SO_LOCKED); + } if (chk->data) { sctp_m_freem(chk->data); chk->data = NULL; } - if (chk->holds_key_ref) - sctp_auth_key_release(stcb, chk->auth_keyid); - ccnt++; - sctp_free_remote_addr(chk->whoTo); - SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_chunk), chk); - SCTP_DECR_CHK_COUNT(); - /* sa_ignore FREED_MEMORY */ - chk = TAILQ_FIRST(&asoc->control_send_queue); } + if (chk->holds_key_ref) + sctp_auth_key_release(stcb, chk->auth_keyid); + sctp_free_remote_addr(chk->whoTo); + SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_chunk), chk); + SCTP_DECR_CHK_COUNT(); + /* sa_ignore FREED_MEMORY */ + } + /* control queue MAY not be empty */ + TAILQ_FOREACH_SAFE(chk, &asoc->control_send_queue, sctp_next, nchk) { + TAILQ_REMOVE(&asoc->control_send_queue, chk, sctp_next); + if (chk->data) { + sctp_m_freem(chk->data); + chk->data = NULL; + } + if (chk->holds_key_ref) + sctp_auth_key_release(stcb, chk->auth_keyid); + sctp_free_remote_addr(chk->whoTo); + SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_chunk), chk); + SCTP_DECR_CHK_COUNT(); + /* sa_ignore FREED_MEMORY */ } -/* - if (ccnt) { - printf("Freed %d from ctrl_queue\n", ccnt); - ccnt = 0; - } -*/ - /* ASCONF queue MAY not be empty */ - if (!TAILQ_EMPTY(&asoc->asconf_send_queue)) { - chk = TAILQ_FIRST(&asoc->asconf_send_queue); - while (chk) { - TAILQ_REMOVE(&asoc->asconf_send_queue, chk, sctp_next); - if (chk->data) { - sctp_m_freem(chk->data); - chk->data = NULL; - } - if (chk->holds_key_ref) - sctp_auth_key_release(stcb, chk->auth_keyid); - ccnt++; - sctp_free_remote_addr(chk->whoTo); - SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_chunk), chk); - SCTP_DECR_CHK_COUNT(); - /* sa_ignore FREED_MEMORY */ - chk = TAILQ_FIRST(&asoc->asconf_send_queue); + TAILQ_FOREACH_SAFE(chk, &asoc->asconf_send_queue, sctp_next, nchk) { + TAILQ_REMOVE(&asoc->asconf_send_queue, chk, sctp_next); + if (chk->data) { + sctp_m_freem(chk->data); + chk->data = NULL; } + if (chk->holds_key_ref) + sctp_auth_key_release(stcb, chk->auth_keyid); + sctp_free_remote_addr(chk->whoTo); + SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_chunk), chk); + SCTP_DECR_CHK_COUNT(); + /* sa_ignore FREED_MEMORY */ } -/* - if (ccnt) { - printf("Freed %d from asconf_queue\n", ccnt); - ccnt = 0; - } -*/ - if (!TAILQ_EMPTY(&asoc->reasmqueue)) { - chk = TAILQ_FIRST(&asoc->reasmqueue); - while (chk) { - TAILQ_REMOVE(&asoc->reasmqueue, chk, sctp_next); - if (chk->data) { - sctp_m_freem(chk->data); - chk->data = NULL; - } - if (chk->holds_key_ref) - sctp_auth_key_release(stcb, chk->auth_keyid); - sctp_free_remote_addr(chk->whoTo); - ccnt++; - SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_chunk), chk); - SCTP_DECR_CHK_COUNT(); - /* sa_ignore FREED_MEMORY */ - chk = TAILQ_FIRST(&asoc->reasmqueue); + TAILQ_FOREACH_SAFE(chk, &asoc->reasmqueue, sctp_next, nchk) { + TAILQ_REMOVE(&asoc->reasmqueue, chk, sctp_next); + if (chk->data) { + sctp_m_freem(chk->data); + chk->data = NULL; } + if (chk->holds_key_ref) + sctp_auth_key_release(stcb, chk->auth_keyid); + sctp_free_remote_addr(chk->whoTo); + SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_chunk), chk); + SCTP_DECR_CHK_COUNT(); + /* sa_ignore FREED_MEMORY */ } -/* - if (ccnt) { - printf("Freed %d from reasm_queue\n", ccnt); - ccnt = 0; - } -*/ + if (asoc->mapping_array) { SCTP_FREE(asoc->mapping_array, SCTP_M_MAP); asoc->mapping_array = NULL; @@ -5047,66 +4959,50 @@ sctp_free_assoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb, int from_inpcbfre } asoc->strm_realoutsize = asoc->streamoutcnt = 0; if (asoc->strmin) { - struct sctp_queued_to_read *ctl; + struct sctp_queued_to_read *ctl, *nctl; for (i = 0; i < asoc->streamincnt; i++) { - if (!TAILQ_EMPTY(&asoc->strmin[i].inqueue)) { - /* We have somethings on the streamin queue */ - ctl = TAILQ_FIRST(&asoc->strmin[i].inqueue); - while (ctl) { - TAILQ_REMOVE(&asoc->strmin[i].inqueue, - ctl, next); - sctp_free_remote_addr(ctl->whoFrom); - if (ctl->data) { - sctp_m_freem(ctl->data); - ctl->data = NULL; - } - /* - * We don't free the address here - * since all the net's were freed - * above. - */ - SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_readq), ctl); - SCTP_DECR_READQ_COUNT(); - ctl = TAILQ_FIRST(&asoc->strmin[i].inqueue); + TAILQ_FOREACH_SAFE(ctl, &asoc->strmin[i].inqueue, next, nctl) { + TAILQ_REMOVE(&asoc->strmin[i].inqueue, ctl, next); + sctp_free_remote_addr(ctl->whoFrom); + if (ctl->data) { + sctp_m_freem(ctl->data); + ctl->data = NULL; } + /* + * We don't free the address here since all + * the net's were freed above. + */ + SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_readq), ctl); + SCTP_DECR_READQ_COUNT(); } } SCTP_FREE(asoc->strmin, SCTP_M_STRMI); asoc->strmin = NULL; } asoc->streamincnt = 0; - while (!TAILQ_EMPTY(&asoc->nets)) { - /* sa_ignore FREED_MEMORY */ - net = TAILQ_FIRST(&asoc->nets); - /* pull from list */ - if ((SCTP_BASE_INFO(ipi_count_raddr) == 0) || (prev == net)) { + TAILQ_FOREACH_SAFE(net, &asoc->nets, sctp_next, nnet) { #ifdef INVARIANTS + if (SCTP_BASE_INFO(ipi_count_raddr) == 0) { panic("no net's left alloc'ed, or list points to itself"); -#endif - break; } - prev = net; +#endif TAILQ_REMOVE(&asoc->nets, net, sctp_next); sctp_free_remote_addr(net); } - - while (!LIST_EMPTY(&asoc->sctp_restricted_addrs)) { + LIST_FOREACH_SAFE(laddr, &asoc->sctp_restricted_addrs, sctp_nxt_addr, naddr) { /* sa_ignore FREED_MEMORY */ - laddr = LIST_FIRST(&asoc->sctp_restricted_addrs); sctp_remove_laddr(laddr); } /* pending asconf (address) parameters */ - while (!TAILQ_EMPTY(&asoc->asconf_queue)) { + TAILQ_FOREACH_SAFE(aparam, &asoc->asconf_queue, next, naparam) { /* sa_ignore FREED_MEMORY */ - aparam = TAILQ_FIRST(&asoc->asconf_queue); TAILQ_REMOVE(&asoc->asconf_queue, aparam, next); SCTP_FREE(aparam, SCTP_M_ASC_ADDR); } - while (!TAILQ_EMPTY(&asoc->asconf_ack_sent)) { + TAILQ_FOREACH_SAFE(aack, &asoc->asconf_ack_sent, next, naack) { /* sa_ignore FREED_MEMORY */ - aack = TAILQ_FIRST(&asoc->asconf_ack_sent); TAILQ_REMOVE(&asoc->asconf_ack_sent, aack, next); if (aack->data != NULL) { sctp_m_freem(aack->data); @@ -5126,12 +5022,10 @@ sctp_free_assoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb, int from_inpcbfre sctp_free_authinfo(&asoc->authinfo); - shared_key = LIST_FIRST(&asoc->shared_keys); - while (shared_key) { + LIST_FOREACH_SAFE(shared_key, &asoc->shared_keys, next, nshared_key) { LIST_REMOVE(shared_key, next); sctp_free_sharedkey(shared_key); /* sa_ignore FREED_MEMORY */ - shared_key = LIST_FIRST(&asoc->shared_keys); } /* Insert new items here :> */ @@ -5689,12 +5583,12 @@ void sctp_pcb_finish(void) { struct sctp_vrflist *vrf_bucket; - struct sctp_vrf *vrf; - struct sctp_ifn *ifn; - struct sctp_ifa *ifa; + struct sctp_vrf *vrf, *nvrf; + struct sctp_ifn *ifn, *nifn; + struct sctp_ifa *ifa, *nifa; struct sctpvtaghead *chain; struct sctp_tagblock *twait_block, *prev_twait_block; - struct sctp_laddr *wi; + struct sctp_laddr *wi, *nwi; int i; /* @@ -5706,20 +5600,15 @@ sctp_pcb_finish(void) struct sctp_iterator *it, *nit; SCTP_IPI_ITERATOR_WQ_LOCK(); - it = TAILQ_FIRST(&sctp_it_ctl.iteratorhead); - while (it) { - nit = TAILQ_NEXT(it, sctp_nxt_itr); + TAILQ_FOREACH_SAFE(it, &sctp_it_ctl.iteratorhead, sctp_nxt_itr, nit) { if (it->vn != curvnet) { - it = nit; continue; } - TAILQ_REMOVE(&sctp_it_ctl.iteratorhead, - it, sctp_nxt_itr); + TAILQ_REMOVE(&sctp_it_ctl.iteratorhead, it, sctp_nxt_itr); if (it->function_atend != NULL) { (*it->function_atend) (it->pointer, it->val); } SCTP_FREE(it, SCTP_M_ITER); - it = nit; } SCTP_IPI_ITERATOR_WQ_UNLOCK(); SCTP_ITERATOR_LOCK(); @@ -5732,7 +5621,7 @@ sctp_pcb_finish(void) SCTP_OS_TIMER_STOP(&SCTP_BASE_INFO(addr_wq_timer.timer)); SCTP_WQ_ADDR_LOCK(); - while ((wi = LIST_FIRST(&SCTP_BASE_INFO(addr_wq))) != NULL) { + LIST_FOREACH_SAFE(wi, &SCTP_BASE_INFO(addr_wq), sctp_nxt_addr, nwi) { LIST_REMOVE(wi, sctp_nxt_addr); SCTP_DECR_LADDR_COUNT(); SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_laddr), wi); @@ -5744,9 +5633,9 @@ sctp_pcb_finish(void) * destroyed first). */ vrf_bucket = &SCTP_BASE_INFO(sctp_vrfhash)[(SCTP_DEFAULT_VRFID & SCTP_BASE_INFO(hashvrfmark))]; - while ((vrf = LIST_FIRST(vrf_bucket)) != NULL) { - while ((ifn = LIST_FIRST(&vrf->ifnlist)) != NULL) { - while ((ifa = LIST_FIRST(&ifn->ifalist)) != NULL) { + LIST_FOREACH_SAFE(vrf, vrf_bucket, next_vrf, nvrf) { + LIST_FOREACH_SAFE(ifn, &vrf->ifnlist, next_ifn, nifn) { + LIST_FOREACH_SAFE(ifa, &ifn->ifalist, next_ifa, nifa) { /* free the ifa */ LIST_REMOVE(ifa, next_bucket); LIST_REMOVE(ifa, next_ifa); @@ -5827,7 +5716,7 @@ sctp_load_addresses_from_init(struct sctp_tcb *stcb, struct mbuf *m, * packet and the offset points to the beginning of the parameters. */ struct sctp_inpcb *inp, *l_inp; - struct sctp_nets *net, *net_tmp; + struct sctp_nets *net, *nnet, *net_tmp; struct ip *iph; struct sctp_paramhdr *phdr, parm_buf; struct sctp_tcb *stcb_tmp; @@ -6373,8 +6262,7 @@ next_param: sizeof(parm_buf)); } /* Now check to see if we need to purge any addresses */ - for (net = TAILQ_FIRST(&stcb->asoc.nets); net != NULL; net = net_tmp) { - net_tmp = TAILQ_NEXT(net, sctp_next); + TAILQ_FOREACH_SAFE(net, &stcb->asoc.nets, sctp_next, nnet) { if ((net->dest_state & SCTP_ADDR_NOT_IN_ASSOC) == SCTP_ADDR_NOT_IN_ASSOC) { /* This address has been removed from the asoc */ @@ -6587,10 +6475,7 @@ sctp_drain_mbufs(struct sctp_inpcb *inp, struct sctp_tcb *stcb) cumulative_tsn_p1 = asoc->cumulative_tsn + 1; cnt = 0; /* First look in the re-assembly queue */ - chk = TAILQ_FIRST(&asoc->reasmqueue); - while (chk) { - /* Get the next one */ - nchk = TAILQ_NEXT(chk, sctp_next); + TAILQ_FOREACH_SAFE(chk, &asoc->reasmqueue, sctp_next, nchk) { if (compare_with_wrap(chk->rec.data.TSN_seq, cumulative_tsn_p1, MAX_TSN)) { /* Yep it is above cum-ack */ @@ -6606,13 +6491,10 @@ sctp_drain_mbufs(struct sctp_inpcb *inp, struct sctp_tcb *stcb) } sctp_free_a_chunk(stcb, chk); } - chk = nchk; } /* Ok that was fun, now we will drain all the inbound streams? */ for (strmat = 0; strmat < asoc->streamincnt; strmat++) { - ctl = TAILQ_FIRST(&asoc->strmin[strmat].inqueue); - while (ctl) { - nctl = TAILQ_NEXT(ctl, next); + TAILQ_FOREACH_SAFE(ctl, &asoc->strmin[strmat].inqueue, next, nctl) { if (compare_with_wrap(ctl->sinfo_tsn, cumulative_tsn_p1, MAX_TSN)) { /* Yep it is above cum-ack */ @@ -6630,7 +6512,6 @@ sctp_drain_mbufs(struct sctp_inpcb *inp, struct sctp_tcb *stcb) SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_readq), ctl); SCTP_DECR_READQ_COUNT(); } - ctl = nctl; } } if (cnt) { diff --git a/sys/netinet/sctp_timer.c b/sys/netinet/sctp_timer.c index 74598af4d9ae..6001690d7fe5 100644 --- a/sys/netinet/sctp_timer.c +++ b/sys/netinet/sctp_timer.c @@ -57,7 +57,7 @@ sctp_early_fr_timer(struct sctp_inpcb *inp, struct sctp_tcb *stcb, struct sctp_nets *net) { - struct sctp_tmit_chunk *chk, *tp2; + struct sctp_tmit_chunk *chk, *pchk; struct timeval now, min_wait, tv; unsigned int cur_rtt, cnt = 0, cnt_resend = 0; @@ -88,9 +88,7 @@ sctp_early_fr_timer(struct sctp_inpcb *inp, */ min_wait.tv_sec = min_wait.tv_usec = 0; } - chk = TAILQ_LAST(&stcb->asoc.sent_queue, sctpchunk_listhead); - for (; chk != NULL; chk = tp2) { - tp2 = TAILQ_PREV(chk, sctpchunk_listhead, sctp_next); + TAILQ_FOREACH_REVERSE_SAFE(chk, &stcb->asoc.sent_queue, sctpchunk_listhead, sctp_next, pchk) { if (chk->whoTo != net) { continue; } @@ -574,20 +572,18 @@ sctp_backoff_on_timeout(struct sctp_tcb *stcb, static void sctp_recover_sent_list(struct sctp_tcb *stcb) { - struct sctp_tmit_chunk *chk, *tp2; + struct sctp_tmit_chunk *chk, *nchk; struct sctp_association *asoc; asoc = &stcb->asoc; - chk = TAILQ_FIRST(&stcb->asoc.sent_queue); - for (; chk != NULL; chk = tp2) { - tp2 = TAILQ_NEXT(chk, sctp_next); - if ((compare_with_wrap(stcb->asoc.last_acked_seq, + TAILQ_FOREACH_SAFE(chk, &asoc->sent_queue, sctp_next, nchk) { + if ((compare_with_wrap(asoc->last_acked_seq, chk->rec.data.TSN_seq, MAX_TSN)) || - (stcb->asoc.last_acked_seq == chk->rec.data.TSN_seq)) { + (asoc->last_acked_seq == chk->rec.data.TSN_seq)) { SCTP_PRINTF("Found chk:%p tsn:%x <= last_acked_seq:%x\n", - chk, chk->rec.data.TSN_seq, stcb->asoc.last_acked_seq); + chk, chk->rec.data.TSN_seq, asoc->last_acked_seq); TAILQ_REMOVE(&asoc->sent_queue, chk, sctp_next); if (chk->pr_sctp_on) { if (asoc->pr_sctp_cnt != 0) @@ -597,19 +593,17 @@ sctp_recover_sent_list(struct sctp_tcb *stcb) /* sa_ignore NO_NULL_CHK */ sctp_free_bufspace(stcb, asoc, chk, 1); sctp_m_freem(chk->data); + chk->data = NULL; if (asoc->peer_supports_prsctp && PR_SCTP_BUF_ENABLED(chk->flags)) { asoc->sent_queue_cnt_removeable--; } } - chk->data = NULL; asoc->sent_queue_cnt--; sctp_free_a_chunk(stcb, chk); } } SCTP_PRINTF("after recover order is as follows\n"); - chk = TAILQ_FIRST(&stcb->asoc.sent_queue); - for (; chk != NULL; chk = tp2) { - tp2 = TAILQ_NEXT(chk, sctp_next); + TAILQ_FOREACH(chk, &asoc->sent_queue, sctp_next) { SCTP_PRINTF("chk:%p TSN:%x\n", chk, chk->rec.data.TSN_seq); } } @@ -631,7 +625,7 @@ sctp_mark_all_for_resend(struct sctp_tcb *stcb, * We only mark chunks that have been outstanding long enough to * have received feed-back. */ - struct sctp_tmit_chunk *chk, *tp2; + struct sctp_tmit_chunk *chk, *nchk; struct sctp_nets *lnets; struct timeval now, min_wait, tv; int cur_rtt; @@ -697,9 +691,7 @@ sctp_mark_all_for_resend(struct sctp_tcb *stcb, #ifndef INVARIANTS start_again: #endif - chk = TAILQ_FIRST(&stcb->asoc.sent_queue); - for (; chk != NULL; chk = tp2) { - tp2 = TAILQ_NEXT(chk, sctp_next); + TAILQ_FOREACH_SAFE(chk, &stcb->asoc.sent_queue, sctp_next, nchk) { if ((compare_with_wrap(stcb->asoc.last_acked_seq, chk->rec.data.TSN_seq, MAX_TSN)) || @@ -1369,7 +1361,7 @@ sctp_asconf_timer(struct sctp_inpcb *inp, struct sctp_tcb *stcb, struct sctp_nets *net) { struct sctp_nets *alt; - struct sctp_tmit_chunk *asconf, *chk, *nchk; + struct sctp_tmit_chunk *asconf, *chk; /* is this a first send, or a retransmission? */ if (TAILQ_EMPTY(&stcb->asoc.asconf_send_queue)) { @@ -1427,8 +1419,7 @@ sctp_asconf_timer(struct sctp_inpcb *inp, struct sctp_tcb *stcb, atomic_add_int(&alt->ref_count, 1); } } - for (chk = asconf; chk; chk = nchk) { - nchk = TAILQ_NEXT(chk, sctp_next); + TAILQ_FOREACH(chk, &stcb->asoc.asconf_send_queue, sctp_next) { if (chk->whoTo != alt) { sctp_free_remote_addr(chk->whoTo); chk->whoTo = alt; diff --git a/sys/netinet/sctp_usrreq.c b/sys/netinet/sctp_usrreq.c index 5211ea507eed..2908f5dde284 100644 --- a/sys/netinet/sctp_usrreq.c +++ b/sys/netinet/sctp_usrreq.c @@ -3335,7 +3335,8 @@ sctp_setopt(struct socket *so, int optname, void *optval, size_t optsize, if ((stcb->asoc.strm_realoutsize - stcb->asoc.streamoutcnt) < addstrmcnt) { /* Need to allocate more */ struct sctp_stream_out *oldstream; - struct sctp_stream_queue_pending *sp; + struct sctp_stream_queue_pending *sp, + *nsp; int removed; oldstream = stcb->asoc.strmout; @@ -3374,8 +3375,7 @@ sctp_setopt(struct socket *so, int optname, void *optval, size_t optsize, * now anything on those * queues? */ - while (TAILQ_EMPTY(&oldstream[i].outqueue) == 0) { - sp = TAILQ_FIRST(&oldstream[i].outqueue); + TAILQ_FOREACH_SAFE(sp, &oldstream[i].outqueue, next, nsp) { TAILQ_REMOVE(&oldstream[i].outqueue, sp, next); TAILQ_INSERT_TAIL(&stcb->asoc.strmout[i].outqueue, sp, next); } diff --git a/sys/netinet/sctputil.c b/sys/netinet/sctputil.c index 975acb86f3a5..72e5269c0263 100644 --- a/sys/netinet/sctputil.c +++ b/sys/netinet/sctputil.c @@ -1417,13 +1417,13 @@ no_stcb: void sctp_iterator_worker(void) { - struct sctp_iterator *it = NULL; + struct sctp_iterator *it, *nit; /* This function is called with the WQ lock in place */ sctp_it_ctl.iterator_running = 1; - sctp_it_ctl.cur_it = it = TAILQ_FIRST(&sctp_it_ctl.iteratorhead); - while (it) { + TAILQ_FOREACH_SAFE(it, &sctp_it_ctl.iteratorhead, sctp_nxt_itr, nit) { + sctp_it_ctl.cur_it = it; /* now lets work on this one */ TAILQ_REMOVE(&sctp_it_ctl.iteratorhead, it, sctp_nxt_itr); SCTP_IPI_ITERATOR_WQ_UNLOCK(); @@ -1437,7 +1437,6 @@ sctp_iterator_worker(void) break; } /* sa_ignore FREED_MEMORY */ - sctp_it_ctl.cur_it = it = TAILQ_FIRST(&sctp_it_ctl.iteratorhead); } sctp_it_ctl.iterator_running = 0; return; @@ -1448,7 +1447,7 @@ static void sctp_handle_addr_wq(void) { /* deal with the ADDR wq from the rtsock calls */ - struct sctp_laddr *wi; + struct sctp_laddr *wi, *nwi; struct sctp_asconf_iterator *asc; SCTP_MALLOC(asc, struct sctp_asconf_iterator *, @@ -1465,12 +1464,10 @@ sctp_handle_addr_wq(void) asc->cnt = 0; SCTP_WQ_ADDR_LOCK(); - wi = LIST_FIRST(&SCTP_BASE_INFO(addr_wq)); - while (wi != NULL) { + LIST_FOREACH_SAFE(wi, &SCTP_BASE_INFO(addr_wq), sctp_nxt_addr, nwi) { LIST_REMOVE(wi, sctp_nxt_addr); LIST_INSERT_HEAD(&asc->list_of_work, wi, sctp_nxt_addr); asc->cnt++; - wi = LIST_FIRST(&SCTP_BASE_INFO(addr_wq)); } SCTP_WQ_ADDR_UNLOCK(); @@ -1664,8 +1661,7 @@ sctp_timeout_handler(void *t) #endif sctp_chunk_output(inp, stcb, SCTP_OUTPUT_FROM_T3, SCTP_SO_NOT_LOCKED); if ((stcb->asoc.num_send_timers_up == 0) && - (stcb->asoc.sent_queue_cnt > 0) - ) { + (stcb->asoc.sent_queue_cnt > 0)) { struct sctp_tmit_chunk *chk; /* @@ -3693,22 +3689,21 @@ sctp_report_all_outbound(struct sctp_tcb *stcb, int holds_lock, int so_locked { struct sctp_association *asoc; struct sctp_stream_out *outs; - struct sctp_tmit_chunk *chk; - struct sctp_stream_queue_pending *sp; + struct sctp_tmit_chunk *chk, *nchk; + struct sctp_stream_queue_pending *sp, *nsp; int i; - asoc = &stcb->asoc; - if (stcb == NULL) { return; } - if (stcb->asoc.state & SCTP_STATE_ABOUT_TO_BE_FREED) { + asoc = &stcb->asoc; + if (asoc->state & SCTP_STATE_ABOUT_TO_BE_FREED) { /* already being freed */ return; } if ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) || (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) || - (stcb->asoc.state & SCTP_STATE_CLOSED_SOCKET)) { + (asoc->state & SCTP_STATE_CLOSED_SOCKET)) { return; } /* now through all the gunk freeing chunks */ @@ -3716,53 +3711,44 @@ sctp_report_all_outbound(struct sctp_tcb *stcb, int holds_lock, int so_locked SCTP_TCB_SEND_LOCK(stcb); } /* sent queue SHOULD be empty */ - if (!TAILQ_EMPTY(&asoc->sent_queue)) { - chk = TAILQ_FIRST(&asoc->sent_queue); - while (chk) { - TAILQ_REMOVE(&asoc->sent_queue, chk, sctp_next); - asoc->sent_queue_cnt--; - if (chk->data != NULL) { - sctp_free_bufspace(stcb, asoc, chk, 1); - sctp_ulp_notify(SCTP_NOTIFY_DG_FAIL, stcb, - SCTP_NOTIFY_DATAGRAM_SENT, chk, so_locked); - if (chk->data) { - sctp_m_freem(chk->data); - chk->data = NULL; - } + TAILQ_FOREACH_SAFE(chk, &asoc->sent_queue, sctp_next, nchk) { + TAILQ_REMOVE(&asoc->sent_queue, chk, sctp_next); + asoc->sent_queue_cnt--; + if (chk->data != NULL) { + sctp_free_bufspace(stcb, asoc, chk, 1); + sctp_ulp_notify(SCTP_NOTIFY_DG_FAIL, stcb, + SCTP_NOTIFY_DATAGRAM_SENT, chk, so_locked); + if (chk->data) { + sctp_m_freem(chk->data); + chk->data = NULL; } - sctp_free_a_chunk(stcb, chk); - /* sa_ignore FREED_MEMORY */ - chk = TAILQ_FIRST(&asoc->sent_queue); } + sctp_free_a_chunk(stcb, chk); + /* sa_ignore FREED_MEMORY */ } /* pending send queue SHOULD be empty */ - if (!TAILQ_EMPTY(&asoc->send_queue)) { - chk = TAILQ_FIRST(&asoc->send_queue); - while (chk) { - TAILQ_REMOVE(&asoc->send_queue, chk, sctp_next); - asoc->send_queue_cnt--; - if (chk->data != NULL) { - sctp_free_bufspace(stcb, asoc, chk, 1); - sctp_ulp_notify(SCTP_NOTIFY_DG_FAIL, stcb, - SCTP_NOTIFY_DATAGRAM_UNSENT, chk, so_locked); - if (chk->data) { - sctp_m_freem(chk->data); - chk->data = NULL; - } + TAILQ_FOREACH_SAFE(chk, &asoc->send_queue, sctp_next, nchk) { + TAILQ_REMOVE(&asoc->send_queue, chk, sctp_next); + asoc->send_queue_cnt--; + if (chk->data != NULL) { + sctp_free_bufspace(stcb, asoc, chk, 1); + sctp_ulp_notify(SCTP_NOTIFY_DG_FAIL, stcb, + SCTP_NOTIFY_DATAGRAM_UNSENT, chk, so_locked); + if (chk->data) { + sctp_m_freem(chk->data); + chk->data = NULL; } - sctp_free_a_chunk(stcb, chk); - /* sa_ignore FREED_MEMORY */ - chk = TAILQ_FIRST(&asoc->send_queue); } + sctp_free_a_chunk(stcb, chk); + /* sa_ignore FREED_MEMORY */ } - for (i = 0; i < stcb->asoc.streamoutcnt; i++) { + for (i = 0; i < asoc->streamoutcnt; i++) { /* For each stream */ - outs = &stcb->asoc.strmout[i]; + outs = &asoc->strmout[i]; /* clean up any sends there */ - stcb->asoc.locked_on_sending = NULL; - sp = TAILQ_FIRST(&outs->outqueue); - while (sp) { - stcb->asoc.stream_queue_cnt--; + asoc->locked_on_sending = NULL; + TAILQ_FOREACH_SAFE(sp, &outs->outqueue, next, nsp) { + asoc->stream_queue_cnt--; TAILQ_REMOVE(&outs->outqueue, sp, next); sctp_free_spbufspace(stcb, asoc, sp); if (sp->data) { @@ -3780,7 +3766,6 @@ sctp_report_all_outbound(struct sctp_tcb *stcb, int holds_lock, int so_locked /* Free the chunk */ sctp_free_a_strmoq(stcb, sp); /* sa_ignore FREED_MEMORY */ - sp = TAILQ_FIRST(&outs->outqueue); } } @@ -4311,10 +4296,8 @@ sctp_pull_off_control_to_new_inp(struct sctp_inpcb *old_inp, } /* lock the socket buffers */ SCTP_INP_READ_LOCK(old_inp); - control = TAILQ_FIRST(&old_inp->read_queue); - /* Pull off all for out target stcb */ - while (control) { - nctl = TAILQ_NEXT(control, next); + TAILQ_FOREACH_SAFE(control, &old_inp->read_queue, next, nctl) { + /* Pull off all for out target stcb */ if (control->stcb == stcb) { /* remove it we want it */ TAILQ_REMOVE(&old_inp->read_queue, control, next); @@ -4331,17 +4314,14 @@ sctp_pull_off_control_to_new_inp(struct sctp_inpcb *old_inp, m = SCTP_BUF_NEXT(m); } } - control = nctl; } SCTP_INP_READ_UNLOCK(old_inp); /* Remove the sb-lock on the old socket */ sbunlock(&old_so->so_rcv); /* Now we move them over to the new socket buffer */ - control = TAILQ_FIRST(&tmp_queue); SCTP_INP_READ_LOCK(new_inp); - while (control) { - nctl = TAILQ_NEXT(control, next); + TAILQ_FOREACH_SAFE(control, &tmp_queue, next, nctl) { TAILQ_INSERT_TAIL(&new_inp->read_queue, control, next); m = control->data; while (m) { @@ -4354,7 +4334,6 @@ sctp_pull_off_control_to_new_inp(struct sctp_inpcb *old_inp, } m = SCTP_BUF_NEXT(m); } - control = nctl; } SCTP_INP_READ_UNLOCK(new_inp); } @@ -4700,7 +4679,7 @@ sctp_release_pr_sctp_chunk(struct sctp_tcb *stcb, struct sctp_tmit_chunk *tp1, ) { struct sctp_stream_out *strq; - struct sctp_tmit_chunk *chk = NULL; + struct sctp_tmit_chunk *chk = NULL, *tp2; struct sctp_stream_queue_pending *sp; uint16_t stream = 0, seq = 0; uint8_t foundeom = 0; @@ -4754,15 +4733,11 @@ sctp_release_pr_sctp_chunk(struct sctp_tcb *stcb, struct sctp_tmit_chunk *tp1, * The multi-part message was scattered across the send and * sent queue. */ -next_on_sent: - tp1 = TAILQ_FIRST(&stcb->asoc.send_queue); - /* - * recurse throught the send_queue too, starting at the - * beginning. - */ - if ((tp1) && - (tp1->rec.data.stream_number == stream) && - (tp1->rec.data.stream_seq == seq)) { + TAILQ_FOREACH_SAFE(tp1, &stcb->asoc.send_queue, sctp_next, tp2) { + if ((tp1->rec.data.stream_number != stream) || + (tp1->rec.data.stream_seq != seq)) { + break; + } /* * save to chk in case we have some on stream out * queue. If so and we have an un-transmitted one we @@ -4792,7 +4767,6 @@ next_on_sent: sctp_next); stcb->asoc.send_queue_cnt--; stcb->asoc.sent_queue_cnt++; - goto next_on_sent; } } if (foundeom == 0) { @@ -4802,8 +4776,11 @@ next_on_sent: */ strq = &stcb->asoc.strmout[stream]; SCTP_TCB_SEND_LOCK(stcb); - sp = TAILQ_FIRST(&strq->outqueue); - while (sp->strseq <= seq) { + TAILQ_FOREACH(sp, &strq->outqueue, next) { + /* FIXME: Shouldn't this be a serial number check? */ + if (sp->strseq > seq) { + break; + } /* Check if its our SEQ */ if (sp->strseq == seq) { sp->discard_rest = 1; @@ -4866,11 +4843,8 @@ next_on_sent: sp->tail_mbuf = NULL; } break; - } else { - /* Next one please */ - sp = TAILQ_NEXT(sp, next); } - } /* End while */ + } /* End tailq_foreach */ SCTP_TCB_SEND_UNLOCK(stcb); } if (do_wakeup_routine) { |