diff --git a/sys/netinet/sctp_indata.c b/sys/netinet/sctp_indata.c index c9c2ff91de48..81d678063d1e 100644 --- a/sys/netinet/sctp_indata.c +++ b/sys/netinet/sctp_indata.c @@ -1608,9 +1608,12 @@ sctp_process_a_data_chunk(struct sctp_tcb *stcb, struct sctp_association *asoc, 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->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) && @@ -4077,8 +4080,14 @@ sctp_fs_audit(struct sctp_association *asoc) acked++; } } + if ((inflight > 0) || (inbetween > 0)) { +#ifdef INVARIANTS panic("Flight size-express incorrect? \n"); +#else + printf("Flight size-express incorrect inflight:%d inbetween:%d\n", + inflight, inbetween); +#endif } } @@ -4986,11 +4995,13 @@ sctp_handle_sack(struct sctp_sack_chunk *ch, struct sctp_tcb *stcb, } if ((TAILQ_FIRST(&asoc->sent_queue) == NULL) && (asoc->total_flight > 0)) { +#ifdef INVARIANTS panic("Warning flight size is postive and should be 0"); -/* - printf("Warning flight size incorrect should be 0 is %d\n", - asoc->total_flight); -*/ +#else + + printf("Warning flight size incorrect should be 0 is %d\n", + asoc->total_flight); +#endif asoc->total_flight = 0; } if (tp1->data) { diff --git a/sys/netinet/sctp_input.c b/sys/netinet/sctp_input.c index d451d8620869..6dee5f40094d 100644 --- a/sys/netinet/sctp_input.c +++ b/sys/netinet/sctp_input.c @@ -545,6 +545,9 @@ sctp_handle_abort(struct sctp_abort_chunk *cp, (SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_SHUTDOWN_RECEIVED)) { SCTP_STAT_DECR_GAUGE32(sctps_currestab); } +#ifdef SCTP_ASOCLOG_OF_TSNS + sctp_print_out_track_log(stcb); +#endif sctp_free_assoc(stcb->sctp_ep, stcb, SCTP_NORMAL_PROC, SCTP_FROM_SCTP_INPUT + SCTP_LOC_6); #ifdef SCTP_DEBUG if (sctp_debug_on & SCTP_DEBUG_INPUT2) { diff --git a/sys/netinet/sctp_lock_bsd.h b/sys/netinet/sctp_lock_bsd.h index 07d782377db8..b95564732a5d 100644 --- a/sys/netinet/sctp_lock_bsd.h +++ b/sys/netinet/sctp_lock_bsd.h @@ -305,7 +305,7 @@ extern int sctp_logoff_stuff; #define SCTP_DECR_EP_COUNT() \ do { \ - atomic_add_int(&sctppcbinfo.ipi_count_ep,-1); \ + atomic_subtract_int(&sctppcbinfo.ipi_count_ep, 1); \ } while (0) #define SCTP_INCR_ASOC_COUNT() \ @@ -315,7 +315,7 @@ extern int sctp_logoff_stuff; #define SCTP_DECR_ASOC_COUNT() \ do { \ - atomic_add_int(&sctppcbinfo.ipi_count_asoc, -1); \ + atomic_subtract_int(&sctppcbinfo.ipi_count_asoc, 1); \ } while (0) #define SCTP_INCR_LADDR_COUNT() \ @@ -325,17 +325,17 @@ extern int sctp_logoff_stuff; #define SCTP_DECR_LADDR_COUNT() \ do { \ - atomic_add_int(&sctppcbinfo.ipi_count_laddr, -1); \ + atomic_subtract_int(&sctppcbinfo.ipi_count_laddr, 1); \ } while (0) #define SCTP_INCR_RADDR_COUNT() \ do { \ - atomic_add_int(&sctppcbinfo.ipi_count_raddr,1); \ + atomic_add_int(&sctppcbinfo.ipi_count_raddr, 1); \ } while (0) #define SCTP_DECR_RADDR_COUNT() \ do { \ - atomic_add_int(&sctppcbinfo.ipi_count_raddr,-1); \ + atomic_subtract_int(&sctppcbinfo.ipi_count_raddr,1); \ } while (0) #define SCTP_INCR_CHK_COUNT() \ @@ -347,7 +347,7 @@ extern int sctp_logoff_stuff; do { \ if(sctppcbinfo.ipi_count_chunk == 0) \ panic("chunk count to 0?"); \ - atomic_add_int(&sctppcbinfo.ipi_count_chunk,-1); \ + atomic_subtract_int(&sctppcbinfo.ipi_count_chunk, 1); \ } while (0) #define SCTP_INCR_READQ_COUNT() \ @@ -357,7 +357,7 @@ extern int sctp_logoff_stuff; #define SCTP_DECR_READQ_COUNT() \ do { \ - atomic_add_int(&sctppcbinfo.ipi_count_readq, -1); \ + atomic_subtract_int(&sctppcbinfo.ipi_count_readq, 1); \ } while (0) #define SCTP_INCR_STRMOQ_COUNT() \ @@ -367,11 +367,8 @@ extern int sctp_logoff_stuff; #define SCTP_DECR_STRMOQ_COUNT() \ do { \ - atomic_add_int(&sctppcbinfo.ipi_count_strmoq,-1); \ + atomic_subtract_int(&sctppcbinfo.ipi_count_strmoq, 1); \ } while (0) - - - #endif diff --git a/sys/netinet/sctp_output.c b/sys/netinet/sctp_output.c index e1ee546baccd..304d29997a21 100644 --- a/sys/netinet/sctp_output.c +++ b/sys/netinet/sctp_output.c @@ -3587,6 +3587,7 @@ sctp_lowlevel_chunk_output(struct sctp_inpcb *inp, SCTP_STAT_INCR_COUNTER64(sctps_outpackets); if (ret) SCTP_STAT_INCR(sctps_senderrors); + #ifdef SCTP_DEBUG if (sctp_debug_on & SCTP_DEBUG_OUTPUT3) { printf("Ip output returns %d\n", ret); @@ -5371,7 +5372,6 @@ sctp_msg_append(struct sctp_tcb *stcb, error = ENOMEM; goto out_now; } - SCTP_INCR_STRMOQ_COUNT(); sp->sinfo_flags = srcv->sinfo_flags; sp->timetolive = srcv->sinfo_timetolive; sp->ppid = srcv->sinfo_ppid; @@ -6084,15 +6084,16 @@ sctp_can_we_split_this(struct sctp_tcb *stcb, * If we have data outstanding, * we get another chance when the sack * arrives to transmit - wait for more data - * - * Could this be optimized to be aware of - * two packets? - * */ - if (stcb->asoc.total_flight > 0) - return (0); - else + if (stcb->asoc.total_flight == 0) { + /* + * If nothing is in flight, we zero the + * packet counter. + */ return (sp->length); + } + return (0); + } else { /* You can fill the rest */ return (goal_mtu); @@ -6132,7 +6133,6 @@ sctp_move_to_outqueue(struct sctp_tcb *stcb, struct sctp_nets *net, int to_move; uint8_t rcv_flags = 0; uint8_t some_taken; - uint8_t took_all = 0; uint8_t send_lock_up = 0; SCTP_TCB_LOCK_ASSERT(stcb); @@ -6159,12 +6159,23 @@ sctp_move_to_outqueue(struct sctp_tcb *stcb, struct sctp_nets *net, if (sp->length == 0) { if (sp->sender_all_done) { /* - * We are doing deffered cleanup. Last time + * We are doing differed cleanup. Last time * through when we took all the data the * sender_all_done was not set. */ - SCTP_TCB_SEND_LOCK(stcb); - send_lock_up = 1; + if (sp->put_last_out == 0) { + printf("Gak, put out entire msg with NO end!-1\n"); + printf("sender_done:%d len:%d msg_comp:%d put_last_out:%d send_lock:%d\n", + sp->sender_all_done, + sp->length, + sp->msg_is_complete, + sp->put_last_out, + send_lock_up); + } + if (TAILQ_NEXT(sp, next) == NULL) { + SCTP_TCB_SEND_LOCK(stcb); + send_lock_up = 1; + } atomic_subtract_int(&asoc->stream_queue_cnt, 1); TAILQ_REMOVE(&strq->outqueue, sp, next); sctp_free_remote_addr(sp->net); @@ -6206,6 +6217,7 @@ sctp_move_to_outqueue(struct sctp_tcb *stcb, struct sctp_nets *net, if (stcb->asoc.state & SCTP_STATE_CLOSED_SOCKET) { sp->msg_is_complete = 1; } +re_look: if (sp->msg_is_complete) { /* The message is complete */ to_move = min(sp->length, frag_point); @@ -6213,8 +6225,10 @@ sctp_move_to_outqueue(struct sctp_tcb *stcb, struct sctp_nets *net, /* All of it fits in the MTU */ if (sp->some_taken) { rcv_flags |= SCTP_DATA_LAST_FRAG; + sp->put_last_out = 1; } else { rcv_flags |= SCTP_DATA_NOT_FRAG; + sp->put_last_out = 1; } } else { /* Not all of it fits, we fragment */ @@ -6227,14 +6241,37 @@ sctp_move_to_outqueue(struct sctp_tcb *stcb, struct sctp_nets *net, to_move = sctp_can_we_split_this(stcb, sp, goal_mtu, frag_point, eeor_mode); if (to_move) { - if (to_move >= sp->length) { - to_move = sp->length; + /*- + * We use a snapshot of length in case it + * is expanding during the compare. + */ + uint32_t llen; + + llen = sp->length; + if (to_move >= llen) { + to_move = llen; + if (send_lock_up == 0) { + /*- + * We are taking all of an incomplete msg + * thus we need a send lock. + */ + SCTP_TCB_SEND_LOCK(stcb); + send_lock_up = 1; + if (sp->msg_is_complete) { + /* + * the sender finished the + * msg + */ + goto re_look; + } + } } if (sp->some_taken == 0) { rcv_flags |= SCTP_DATA_FIRST_FRAG; + sp->some_taken = 1; } - sp->some_taken = 1; } else { + /* Nothing to take. */ if (sp->some_taken) { *locked = 1; } @@ -6270,21 +6307,12 @@ sctp_move_to_outqueue(struct sctp_tcb *stcb, struct sctp_nets *net, } else { chk->copy_by_ref = 0; } - if ((sp->msg_is_complete == 0) && - (to_move >= sp->length)) { - SCTP_TCB_SEND_LOCK(stcb); - send_lock_up = 1; - } else { - send_lock_up = 0; - } - if (to_move >= sp->length) { /* we can steal the whole thing */ chk->data = sp->data; chk->last_mbuf = sp->tail_mbuf; /* register the stealing */ sp->data = sp->tail_mbuf = NULL; - took_all = 1; } else { struct mbuf *m; @@ -6303,16 +6331,35 @@ sctp_move_to_outqueue(struct sctp_tcb *stcb, struct sctp_nets *net, sp->data = SCTP_BUF_NEXT(m); SCTP_BUF_NEXT(m) = NULL; if (sp->tail_mbuf == m) { - /* freeing tail */ + /*- + * Freeing tail? TSNH since + * we supposedly were taking less + * than the sp->length. + */ +#ifdef INVARIANTS + panic("Huh, freing tail? - TSNH"); +#else printf("Huh, freeing tail? - TSNH\n"); - sp->tail_mbuf = sp->data; + sp->tail_mbuf = sp->data = NULL; + sp->length = 0; +#endif + } sctp_m_free(m); m = sp->data; } } if (to_move > sp->length) { + /*- This should not happen either + * since we always lower to_move to the size + * of sp->length if its larger. + */ +#ifdef INVARIANTS panic("Huh, how can to_move be larger?"); +#else + printf("Huh, how can to_move be larger?\n"); + sp->length = 0; +#endif } else { atomic_subtract_int(&sp->length, to_move); } @@ -6331,7 +6378,7 @@ sctp_move_to_outqueue(struct sctp_tcb *stcb, struct sctp_nets *net, SCTP_TCB_SEND_LOCK(stcb); send_lock_up = 1; } - if (took_all) { + if (chk->data == NULL) { /* unsteal the data */ sp->data = chk->data; sp->tail_mbuf = chk->last_mbuf; @@ -6344,7 +6391,7 @@ sctp_move_to_outqueue(struct sctp_tcb *stcb, struct sctp_nets *net, SCTP_BUF_NEXT(sp->data) = m; } sp->some_taken = some_taken; - sp->length += to_move; + atomic_add_int(&sp->length, to_move); chk->data = NULL; sctp_free_a_chunk(stcb, chk); goto out_gu; @@ -6357,9 +6404,13 @@ sctp_move_to_outqueue(struct sctp_tcb *stcb, struct sctp_nets *net, } SCTP_BUF_PREPEND(chk->data, sizeof(struct sctp_data_chunk), M_DONTWAIT); if (chk->data == NULL) { - /* HELP */ + /* HELP, TSNH since we assured it would not above? */ +#ifdef INVARIANTS + panic("prepend failes HELP?"); +#else printf("prepend fails HELP?\n"); sctp_free_a_chunk(stcb, chk); +#endif goto out_gu; } sctp_snd_sb_alloc(stcb, sizeof(struct sctp_data_chunk)); @@ -6414,9 +6465,12 @@ sctp_move_to_outqueue(struct sctp_tcb *stcb, struct sctp_nets *net, asoc->out_tsnlog[asoc->tsn_out_at].tsn = chk->rec.data.TSN_seq; asoc->out_tsnlog[asoc->tsn_out_at].strm = chk->rec.data.stream_number; asoc->out_tsnlog[asoc->tsn_out_at].seq = chk->rec.data.stream_seq; + asoc->out_tsnlog[asoc->tsn_out_at].sz = chk->send_size; + asoc->out_tsnlog[asoc->tsn_out_at].flgs = chk->rec.data.rcv_flags; asoc->tsn_out_at++; if (asoc->tsn_out_at >= SCTP_TSN_LOG_SIZE) { asoc->tsn_out_at = 0; + asoc->tsn_out_wrapped = 1; } #endif @@ -6450,7 +6504,16 @@ sctp_move_to_outqueue(struct sctp_tcb *stcb, struct sctp_nets *net, if (sp->msg_is_complete && (sp->length == 0) && (sp->sender_all_done)) { /* All done pull and kill the message */ atomic_subtract_int(&asoc->stream_queue_cnt, 1); - if (send_lock_up == 0) { + if (sp->put_last_out == 0) { + printf("Gak, put out entire msg with NO end!-2\n"); + printf("sender_done:%d len:%d msg_comp:%d put_last_out:%d send_lock:%d\n", + sp->sender_all_done, + sp->length, + sp->msg_is_complete, + sp->put_last_out, + send_lock_up); + } + if ((send_lock_up == 0) && (TAILQ_NEXT(sp, next) == NULL)) { SCTP_TCB_SEND_LOCK(stcb); send_lock_up = 1; } @@ -10422,7 +10485,6 @@ sctp_copy_it_in(struct sctp_tcb *stcb, *error = ENOMEM; goto out_now; } - SCTP_INCR_STRMOQ_COUNT(); sp->act_flags = 0; sp->sender_all_done = 0; sp->sinfo_flags = srcv->sinfo_flags; @@ -10445,6 +10507,7 @@ sctp_copy_it_in(struct sctp_tcb *stcb, } sp->sender_all_done = 0; sp->some_taken = 0; + sp->put_last_out = 0; resv_in_first = sizeof(struct sctp_data_chunk); sp->data = sp->tail_mbuf = NULL; *error = sctp_copy_one(sp, uio, resv_in_first); @@ -11105,9 +11168,7 @@ sctp_lower_sosend(struct socket *so, sp->sender_all_done = 0; } sctp_snd_sb_alloc(stcb, sp->length); - atomic_add_int(&asoc->stream_queue_cnt, 1); - TAILQ_INSERT_TAIL(&strm->outqueue, sp, next); if ((srcv->sinfo_flags & SCTP_UNORDERED) == 0) { sp->strseq = strm->next_sequence_sent; #ifdef SCTP_LOG_SENDING_STR @@ -11119,7 +11180,7 @@ sctp_lower_sosend(struct socket *so, } else { SCTP_STAT_INCR(sctps_sends_with_unord); } - + TAILQ_INSERT_TAIL(&strm->outqueue, sp, next); if ((strm->next_spoke.tqe_next == NULL) && (strm->next_spoke.tqe_prev == NULL)) { /* Not on wheel, insert */ @@ -11195,6 +11256,7 @@ sctp_lower_sosend(struct socket *so, /* Did we reach EOR? */ if ((uio->uio_resid == 0) && ((user_marks_eor == 0) || + (srcv->sinfo_flags & SCTP_EOF) || (user_marks_eor && (srcv->sinfo_flags & SCTP_EOR))) ) { sp->msg_is_complete = 1; @@ -11384,6 +11446,7 @@ sctp_lower_sosend(struct socket *so, asoc->stream_locked = 0; } } else { + printf("Huh no sp TSNH?\n"); strm->last_msg_incomplete = 0; asoc->stream_locked = 0; diff --git a/sys/netinet/sctp_pcb.c b/sys/netinet/sctp_pcb.c index da7d86478954..24c04b3c5235 100644 --- a/sys/netinet/sctp_pcb.c +++ b/sys/netinet/sctp_pcb.c @@ -2689,6 +2689,10 @@ sctp_inpcb_free(struct sctp_inpcb *inp, int immediate, int from) inp->sctp_ep.signature_change.type = SCTP_TIMER_TYPE_NONE; /* Clear the read queue */ while ((sq = TAILQ_FIRST(&inp->read_queue)) != NULL) { + /* Its only abandoned if it had data left */ + if (sq->length) + SCTP_STAT_INCR(sctps_left_abandon); + TAILQ_REMOVE(&inp->read_queue, sq, next); sctp_free_remote_addr(sq->whoFrom); if (so) @@ -3776,19 +3780,6 @@ sctp_free_assoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb, int from_inpcbfre } } - while ((sp = TAILQ_FIRST(&asoc->free_strmoq)) != NULL) { - TAILQ_REMOVE(&asoc->free_strmoq, sp, next); - if (sp->data) { - sctp_m_freem(sp->data); - sp->data = NULL; - sp->tail_mbuf = NULL; - } - /* Free the zone stuff */ - SCTP_ZONE_FREE(sctppcbinfo.ipi_zone_strmoq, sp); - SCTP_DECR_STRMOQ_COUNT(); - atomic_add_int(&sctppcbinfo.ipi_free_strmoq, -1); - } - while ((liste = TAILQ_FIRST(&asoc->resetHead)) != NULL) { TAILQ_REMOVE(&asoc->resetHead, liste, next_resp); SCTP_FREE(liste); diff --git a/sys/netinet/sctp_structs.h b/sys/netinet/sctp_structs.h index 5a1f9d213f15..4e88c1f87639 100644 --- a/sys/netinet/sctp_structs.h +++ b/sys/netinet/sctp_structs.h @@ -415,6 +415,7 @@ struct sctp_stream_queue_pending { uint8_t addr_over; uint8_t pr_sctp_on; uint8_t sender_all_done; + uint8_t put_last_out; }; /* @@ -463,6 +464,8 @@ struct sctp_tsn_log { uint32_t tsn; uint16_t strm; uint16_t seq; + uint16_t sz; + uint16_t flgs; }; /* @@ -499,8 +502,6 @@ struct sctp_association { /* Free chunk list */ struct sctpchunk_listhead free_chunks; - /* Free stream output control list */ - struct sctp_streamhead free_strmoq; /* Control chunk queue */ struct sctpchunk_listhead control_send_queue; @@ -680,6 +681,8 @@ struct sctp_association { struct sctp_tsn_log out_tsnlog[SCTP_TSN_LOG_SIZE]; uint16_t tsn_in_at; uint16_t tsn_out_at; + uint16_t tsn_in_wrapped; + uint16_t tsn_out_wrapped; #endif /* SCTP_ASOCLOG_OF_TSNS */ /* * window state information and smallest MTU that I use to bound @@ -823,7 +826,6 @@ struct sctp_association { uint16_t ecn_echo_cnt_onq; uint16_t free_chunk_cnt; - uint16_t free_strmoq_cnt; uint8_t stream_locked; uint8_t authenticated; /* packet authenticated ok */ diff --git a/sys/netinet/sctp_uio.h b/sys/netinet/sctp_uio.h index 3efd7ed1fdf6..263f417f71fd 100644 --- a/sys/netinet/sctp_uio.h +++ b/sys/netinet/sctp_uio.h @@ -899,6 +899,8 @@ struct sctpstat { u_long sctps_read_peeks;/* Number of times recv was called with peek */ u_long sctps_cached_chk;/* Number of cached chunks used */ u_long sctps_cached_strmoq; /* Number of cached stream oq's used */ + u_long sctps_left_abandon; /* Number of unread message abandonded + * by close */ }; #define SCTP_STAT_INCR(_x) SCTP_STAT_INCR_BY(_x,1) diff --git a/sys/netinet/sctp_usrreq.c b/sys/netinet/sctp_usrreq.c index f0f2c753830e..7f9bdf34f06f 100644 --- a/sys/netinet/sctp_usrreq.c +++ b/sys/netinet/sctp_usrreq.c @@ -1722,7 +1722,11 @@ sctp_getopt(struct socket *so, int optname, void *optval, size_t *optsize, int ovh; SCTP_CHECK_AND_CAST(av, optval, struct sctp_assoc_value, *optsize); - SCTP_FIND_STCB(inp, stcb, av->assoc_id); + if (av->assoc_id) { + SCTP_FIND_STCB(inp, stcb, av->assoc_id); + } else { + stcb = NULL; + } if (stcb) { av->assoc_value = sctp_get_frag_point(stcb, &stcb->asoc); diff --git a/sys/netinet/sctp_var.h b/sys/netinet/sctp_var.h index 7cccacdfb94b..b5f9ad4039c7 100644 --- a/sys/netinet/sctp_var.h +++ b/sys/netinet/sctp_var.h @@ -77,30 +77,15 @@ extern struct pr_usrreqs sctp_usrreqs; } #define sctp_free_a_strmoq(_stcb, _strmoq) { \ - if (((_stcb)->asoc.free_strmoq_cnt > sctp_asoc_free_resc_limit) || \ - (sctppcbinfo.ipi_free_strmoq > sctp_system_free_resc_limit)) { \ - SCTP_ZONE_FREE(sctppcbinfo.ipi_zone_strmoq, (_strmoq)); \ - SCTP_DECR_STRMOQ_COUNT(); \ - } else { \ - TAILQ_INSERT_TAIL(&(_stcb)->asoc.free_strmoq, (_strmoq), next); \ - (_stcb)->asoc.free_strmoq_cnt++; \ - atomic_add_int(&sctppcbinfo.ipi_free_strmoq, 1); \ - } \ + SCTP_ZONE_FREE(sctppcbinfo.ipi_zone_strmoq, (_strmoq)); \ + SCTP_DECR_STRMOQ_COUNT(); \ } #define sctp_alloc_a_strmoq(_stcb, _strmoq) { \ - if (TAILQ_EMPTY(&(_stcb)->asoc.free_strmoq)) { \ - (_strmoq) = SCTP_ZONE_GET(sctppcbinfo.ipi_zone_strmoq, struct sctp_stream_queue_pending); \ - if ((_strmoq)) { \ - SCTP_INCR_STRMOQ_COUNT(); \ - } \ - } else { \ - (_strmoq) = TAILQ_FIRST(&(_stcb)->asoc.free_strmoq); \ - TAILQ_REMOVE(&(_stcb)->asoc.free_strmoq, (_strmoq), next); \ - atomic_subtract_int(&sctppcbinfo.ipi_free_strmoq, 1); \ - SCTP_STAT_INCR(sctps_cached_strmoq); \ - (_stcb)->asoc.free_strmoq_cnt--; \ - } \ + (_strmoq) = SCTP_ZONE_GET(sctppcbinfo.ipi_zone_strmoq, struct sctp_stream_queue_pending); \ + if ((_strmoq)) { \ + SCTP_INCR_STRMOQ_COUNT(); \ + } \ } diff --git a/sys/netinet/sctputil.c b/sys/netinet/sctputil.c index 54aef9fbe710..c94b2d4e3c52 100644 --- a/sys/netinet/sctputil.c +++ b/sys/netinet/sctputil.c @@ -1085,7 +1085,6 @@ sctp_init_asoc(struct sctp_inpcb *m, struct sctp_association *asoc, memset(asoc->mapping_array, 0, asoc->mapping_array_size); /* Now the init of the other outqueues */ TAILQ_INIT(&asoc->free_chunks); - TAILQ_INIT(&asoc->free_strmoq); TAILQ_INIT(&asoc->out_wheel); TAILQ_INIT(&asoc->control_send_queue); TAILQ_INIT(&asoc->send_queue); @@ -3494,6 +3493,67 @@ sctp_abort_association(struct sctp_inpcb *inp, struct sctp_tcb *stcb, } } +#ifdef SCTP_ASOCLOG_OF_TSNS +void +sctp_print_out_track_log(struct sctp_tcb *stcb) +{ + int i; + + printf("Last ep reason:%x\n", stcb->sctp_ep->last_abort_code); + printf("IN bound TSN log-aaa\n"); + if ((stcb->asoc.tsn_in_at == 0) && (stcb->asoc.tsn_in_wrapped == 0)) { + printf("None rcvd\n"); + goto none_in; + } + if (stcb->asoc.tsn_in_wrapped) { + for (i = stcb->asoc.tsn_in_at; i < SCTP_TSN_LOG_SIZE; i++) { + printf("TSN:%x strm:%d seq:%d flags:%x sz:%d\n", + stcb->asoc.in_tsnlog[i].tsn, + stcb->asoc.in_tsnlog[i].strm, + stcb->asoc.in_tsnlog[i].seq, + stcb->asoc.in_tsnlog[i].flgs, + stcb->asoc.in_tsnlog[i].sz); + } + } + if (stcb->asoc.tsn_in_at) { + for (i = 0; i < stcb->asoc.tsn_in_at; i++) { + printf("TSN:%x strm:%d seq:%d flags:%x sz:%d\n", + stcb->asoc.in_tsnlog[i].tsn, + stcb->asoc.in_tsnlog[i].strm, + stcb->asoc.in_tsnlog[i].seq, + stcb->asoc.in_tsnlog[i].flgs, + stcb->asoc.in_tsnlog[i].sz); + } + } +none_in: + printf("OUT bound TSN log-aaa\n"); + if ((stcb->asoc.tsn_out_at == 0) && (stcb->asoc.tsn_out_wrapped == 0)) { + printf("None sent\n"); + } + if (stcb->asoc.tsn_out_wrapped) { + for (i = stcb->asoc.tsn_out_at; i < SCTP_TSN_LOG_SIZE; i++) { + printf("TSN:%x strm:%d seq:%d flags:%x sz:%d\n", + stcb->asoc.out_tsnlog[i].tsn, + stcb->asoc.out_tsnlog[i].strm, + stcb->asoc.out_tsnlog[i].seq, + stcb->asoc.out_tsnlog[i].flgs, + stcb->asoc.out_tsnlog[i].sz); + } + } + if (stcb->asoc.tsn_out_at) { + for (i = 0; i < stcb->asoc.tsn_out_at; i++) { + printf("TSN:%x strm:%d seq:%d flags:%x sz:%d\n", + stcb->asoc.out_tsnlog[i].tsn, + stcb->asoc.out_tsnlog[i].strm, + stcb->asoc.out_tsnlog[i].seq, + stcb->asoc.out_tsnlog[i].flgs, + stcb->asoc.out_tsnlog[i].sz); + } + } +} + +#endif + void sctp_abort_an_association(struct sctp_inpcb *inp, struct sctp_tcb *stcb, int error, struct mbuf *op_err) @@ -3521,6 +3581,9 @@ sctp_abort_an_association(struct sctp_inpcb *inp, struct sctp_tcb *stcb, SCTP_STAT_DECR_GAUGE32(sctps_currestab); } /* now free the asoc */ +#ifdef SCTP_ASOCLOG_OF_TSNS + sctp_print_out_track_log(stcb); +#endif sctp_free_assoc(inp, stcb, SCTP_NORMAL_PROC, SCTP_FROM_SCTPUTIL + SCTP_LOC_5); } diff --git a/sys/netinet/sctputil.h b/sys/netinet/sctputil.h index 001a273284b5..8496f421e47f 100644 --- a/sys/netinet/sctputil.h +++ b/sys/netinet/sctputil.h @@ -86,6 +86,11 @@ __FBSDID("$FreeBSD$"); #endif #endif +#ifdef SCTP_ASOCLOG_OF_TSNS +void sctp_print_out_track_log(struct sctp_tcb *stcb); + +#endif + #ifdef SCTP_MBUF_LOGGING struct mbuf *sctp_m_free(struct mbuf *m); void sctp_m_freem(struct mbuf *m);