aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/netinet/sctp_asconf.c37
-rw-r--r--sys/netinet/sctp_bsd_addr.c4
-rw-r--r--sys/netinet/sctp_indata.c444
-rw-r--r--sys/netinet/sctp_input.c102
-rw-r--r--sys/netinet/sctp_output.c36
-rw-r--r--sys/netinet/sctp_pcb.c377
-rw-r--r--sys/netinet/sctp_timer.c35
-rw-r--r--sys/netinet/sctp_usrreq.c6
-rw-r--r--sys/netinet/sctputil.c136
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) {