diff options
Diffstat (limited to 'sys/netinet/sctp_indata.c')
-rw-r--r-- | sys/netinet/sctp_indata.c | 208 |
1 files changed, 110 insertions, 98 deletions
diff --git a/sys/netinet/sctp_indata.c b/sys/netinet/sctp_indata.c index 0d8bbac..27bdfd2 100644 --- a/sys/netinet/sctp_indata.c +++ b/sys/netinet/sctp_indata.c @@ -1611,16 +1611,20 @@ sctp_process_a_data_chunk(struct sctp_tcb *stcb, struct sctp_association *asoc, */ strmseq = ntohs(ch->dp.stream_sequence); #ifdef SCTP_ASOCLOG_OF_TSNS + SCTP_TCB_LOCK_ASSERT(stcb); + if (asoc->tsn_in_at >= SCTP_TSN_LOG_SIZE) { + asoc->tsn_in_at = 0; + asoc->tsn_in_wrapped = 1; + } asoc->in_tsnlog[asoc->tsn_in_at].tsn = tsn; asoc->in_tsnlog[asoc->tsn_in_at].strm = strmno; asoc->in_tsnlog[asoc->tsn_in_at].seq = strmseq; asoc->in_tsnlog[asoc->tsn_in_at].sz = chk_length; asoc->in_tsnlog[asoc->tsn_in_at].flgs = chunk_flags; + asoc->in_tsnlog[asoc->tsn_in_at].stcb = (void *)stcb; + asoc->in_tsnlog[asoc->tsn_in_at].in_pos = asoc->tsn_in_at; + asoc->in_tsnlog[asoc->tsn_in_at].in_out = 1; asoc->tsn_in_at++; - if (asoc->tsn_in_at >= SCTP_TSN_LOG_SIZE) { - asoc->tsn_in_at = 0; - asoc->tsn_in_wrapped = 1; - } #endif if ((chunk_flags & SCTP_DATA_FIRST_FRAG) && (TAILQ_EMPTY(&asoc->resetHead)) && @@ -2998,7 +3002,8 @@ sctp_handle_segments(struct mbuf *m, int *offset, struct sctp_tcb *stcb, struct sctp_calculate_rto(stcb, asoc, tp1->whoTo, - &tp1->sent_rcv_time); + &tp1->sent_rcv_time, + sctp_align_safe_nocopy); tp1->do_rtt = 0; } } @@ -3456,7 +3461,7 @@ sctp_strike_gap_ack_chunks(struct sctp_tcb *stcb, struct sctp_association *asoc, tp1->no_fr_allowed = 1; alt = tp1->whoTo; /* sa_ignore NO_NULL_CHK */ - if (sctp_cmt_pf) { + if (sctp_cmt_on_off && sctp_cmt_pf) { /* * JRS 5/18/07 - If CMT PF is on, * use the PF version of @@ -3730,7 +3735,6 @@ sctp_window_probe_recovery(struct sctp_tcb *stcb, /* First setup this one and get it moved back */ tp1->sent = SCTP_DATAGRAM_UNSENT; - tp1->window_probe = 0; if (sctp_logging_level & SCTP_FLIGHT_LOGGING_ENABLE) { sctp_misc_ints(SCTP_FLIGHT_LOG_DOWN_WP, tp1->whoTo->flight_size, @@ -3752,7 +3756,6 @@ sctp_window_probe_recovery(struct sctp_tcb *stcb, if (chk->sent == SCTP_DATAGRAM_RESEND) { /* Another chunk to move */ chk->sent = SCTP_DATAGRAM_UNSENT; - chk->window_probe = 0; /* It should not be in flight */ TAILQ_REMOVE(&asoc->sent_queue, chk, sctp_next); TAILQ_INSERT_AFTER(&asoc->send_queue, tp1, chk, sctp_next); @@ -3781,6 +3784,13 @@ sctp_express_handle_sack(struct sctp_tcb *stcb, uint32_t cumack, rwnd, stcb->asoc.last_acked_seq, stcb->asoc.peers_rwnd); } SCTP_TCB_LOCK_ASSERT(stcb); +#ifdef SCTP_ASOCLOG_OF_TSNS + stcb->asoc.cumack_log[stcb->asoc.cumack_log_at] = cumack; + stcb->asoc.cumack_log_at++; + if (stcb->asoc.cumack_log_at > SCTP_TSN_LOG_SIZE) { + stcb->asoc.cumack_log_at = 0; + } +#endif asoc = &stcb->asoc; old_rwnd = asoc->peers_rwnd; if (compare_with_wrap(asoc->last_acked_seq, cumack, MAX_TSN)) { @@ -3864,103 +3874,101 @@ sctp_express_handle_sack(struct sctp_tcb *stcb, uint32_t cumack, if (compare_with_wrap(cumack, tp1->rec.data.TSN_seq, MAX_TSN) || cumack == tp1->rec.data.TSN_seq) { - if (tp1->sent != SCTP_DATAGRAM_UNSENT) { + if (tp1->sent == SCTP_DATAGRAM_UNSENT) { + printf("Warning, an unsent is now acked?\n"); + } + /* + * ECN Nonce: Add the nonce to the sender's + * nonce sum + */ + asoc->nonce_sum_expect_base += tp1->rec.data.ect_nonce; + if (tp1->sent < SCTP_DATAGRAM_ACKED) { /* - * ECN Nonce: Add the nonce to the - * sender's nonce sum + * If it is less than ACKED, it is + * now no-longer in flight. Higher + * values may occur during marking */ - asoc->nonce_sum_expect_base += tp1->rec.data.ect_nonce; - if (tp1->sent < SCTP_DATAGRAM_ACKED) { - /* - * If it is less than ACKED, - * it is now no-longer in - * flight. Higher values may - * occur during marking - */ - if (tp1->sent < SCTP_DATAGRAM_RESEND) { - if (sctp_logging_level & SCTP_FLIGHT_LOGGING_ENABLE) { - sctp_misc_ints(SCTP_FLIGHT_LOG_DOWN_CA, - tp1->whoTo->flight_size, - tp1->book_size, - (uintptr_t) tp1->whoTo, - tp1->rec.data.TSN_seq); - } - sctp_flight_size_decrease(tp1); - sctp_total_flight_decrease(stcb, tp1); - } - tp1->whoTo->net_ack += tp1->send_size; - if (tp1->snd_count < 2) { - /* - * True - * non-retransmited - * chunk - */ - tp1->whoTo->net_ack2 += - tp1->send_size; - - /* update RTO too? */ - if (tp1->do_rtt) { - tp1->whoTo->RTO = - sctp_calculate_rto(stcb, - asoc, tp1->whoTo, - &tp1->sent_rcv_time); - tp1->do_rtt = 0; - } + if (tp1->sent < SCTP_DATAGRAM_RESEND) { + if (sctp_logging_level & SCTP_FLIGHT_LOGGING_ENABLE) { + sctp_misc_ints(SCTP_FLIGHT_LOG_DOWN_CA, + tp1->whoTo->flight_size, + tp1->book_size, + (uintptr_t) tp1->whoTo, + tp1->rec.data.TSN_seq); } + sctp_flight_size_decrease(tp1); + sctp_total_flight_decrease(stcb, tp1); + } + tp1->whoTo->net_ack += tp1->send_size; + if (tp1->snd_count < 2) { /* - * CMT: CUCv2 algorithm. - * From the cumack'd TSNs, - * for each TSN being acked - * for the first time, set - * the following variables - * for the corresp - * destination. - * new_pseudo_cumack will - * trigger a cwnd update. - * find_(rtx_)pseudo_cumack - * will trigger search for - * the next expected - * (rtx-)pseudo-cumack. + * True non-retransmited + * chunk */ - tp1->whoTo->new_pseudo_cumack = 1; - tp1->whoTo->find_pseudo_cumack = 1; - tp1->whoTo->find_rtx_pseudo_cumack = 1; + tp1->whoTo->net_ack2 += + tp1->send_size; - if (sctp_logging_level & SCTP_CWND_LOGGING_ENABLE) { - sctp_log_cwnd(stcb, tp1->whoTo, tp1->rec.data.TSN_seq, SCTP_CWND_LOG_FROM_SACK); + /* update RTO too? */ + if (tp1->do_rtt) { + tp1->whoTo->RTO = + sctp_calculate_rto(stcb, + asoc, tp1->whoTo, + &tp1->sent_rcv_time, + sctp_align_safe_nocopy); + tp1->do_rtt = 0; } } - if (tp1->sent == SCTP_DATAGRAM_RESEND) { - sctp_ucount_decr(asoc->sent_queue_retran_cnt); - } - if (tp1->rec.data.chunk_was_revoked) { - /* deflate the cwnd */ - tp1->whoTo->cwnd -= tp1->book_size; - tp1->rec.data.chunk_was_revoked = 0; + /* + * CMT: CUCv2 algorithm. From the + * cumack'd TSNs, for each TSN being + * acked for the first time, set the + * following variables for the + * corresp destination. + * new_pseudo_cumack will trigger a + * cwnd update. + * find_(rtx_)pseudo_cumack will + * trigger search for the next + * expected (rtx-)pseudo-cumack. + */ + tp1->whoTo->new_pseudo_cumack = 1; + tp1->whoTo->find_pseudo_cumack = 1; + tp1->whoTo->find_rtx_pseudo_cumack = 1; + + if (sctp_logging_level & SCTP_CWND_LOGGING_ENABLE) { + sctp_log_cwnd(stcb, tp1->whoTo, tp1->rec.data.TSN_seq, SCTP_CWND_LOG_FROM_SACK); } - tp1->sent = SCTP_DATAGRAM_ACKED; } + if (tp1->sent == SCTP_DATAGRAM_RESEND) { + sctp_ucount_decr(asoc->sent_queue_retran_cnt); + } + if (tp1->rec.data.chunk_was_revoked) { + /* deflate the cwnd */ + tp1->whoTo->cwnd -= tp1->book_size; + tp1->rec.data.chunk_was_revoked = 0; + } + tp1->sent = SCTP_DATAGRAM_ACKED; + TAILQ_REMOVE(&asoc->sent_queue, tp1, sctp_next); + if (tp1->data) { + sctp_free_bufspace(stcb, asoc, tp1, 1); + sctp_m_freem(tp1->data); + } + if (sctp_logging_level & SCTP_SACK_LOGGING_ENABLE) { + sctp_log_sack(asoc->last_acked_seq, + cumack, + tp1->rec.data.TSN_seq, + 0, + 0, + SCTP_LOG_FREE_SENT); + } + tp1->data = NULL; + asoc->sent_queue_cnt--; + sctp_free_a_chunk(stcb, tp1); + tp1 = tp2; } else { break; } - TAILQ_REMOVE(&asoc->sent_queue, tp1, sctp_next); - if (tp1->data) { - sctp_free_bufspace(stcb, asoc, tp1, 1); - sctp_m_freem(tp1->data); - } - if (sctp_logging_level & SCTP_SACK_LOGGING_ENABLE) { - sctp_log_sack(asoc->last_acked_seq, - cumack, - tp1->rec.data.TSN_seq, - 0, - 0, - SCTP_LOG_FREE_SENT); - } - tp1->data = NULL; - asoc->sent_queue_cnt--; - sctp_free_a_chunk(stcb, tp1); - tp1 = tp2; } + } if (stcb->sctp_socket) { SOCKBUF_LOCK(&stcb->sctp_socket->so_snd); @@ -4268,6 +4276,13 @@ sctp_handle_sack(struct mbuf *m, int offset, SCTP_STAT_INCR(sctps_slowpath_sack); nonce_sum_flag = ch->ch.chunk_flags & SCTP_SACK_NONCE_SUM; cum_ack = last_tsn = ntohl(sack->cum_tsn_ack); +#ifdef SCTP_ASOCLOG_OF_TSNS + stcb->asoc.cumack_log[stcb->asoc.cumack_log_at] = cum_ack; + stcb->asoc.cumack_log_at++; + if (stcb->asoc.cumack_log_at > SCTP_TSN_LOG_SIZE) { + stcb->asoc.cumack_log_at = 0; + } +#endif num_seg = ntohs(sack->num_gap_ack_blks); a_rwnd = rwnd; @@ -4491,7 +4506,8 @@ sctp_handle_sack(struct mbuf *m, int offset, tp1->whoTo->RTO = sctp_calculate_rto(stcb, asoc, tp1->whoTo, - &tp1->sent_rcv_time); + &tp1->sent_rcv_time, + sctp_align_safe_nocopy); tp1->do_rtt = 0; } } @@ -4626,15 +4642,11 @@ skip_segments: } if (tp1->sent == SCTP_DATAGRAM_UNSENT) { /* no more sent on list */ - break; + printf("Warning, tp1->sent == %d and its now acked?\n", + tp1->sent); } tp2 = TAILQ_NEXT(tp1, sctp_next); TAILQ_REMOVE(&asoc->sent_queue, tp1, sctp_next); - /* - * Friendlier printf in lieu of panic now that I think its - * fixed - */ - if (tp1->pr_sctp_on) { if (asoc->pr_sctp_cnt != 0) asoc->pr_sctp_cnt--; |