- More work on making send lock contention.
- Removed free-oqueue cache. - Fix counter for sq entries - Increased the amount of information retained on ASOC_TSN logging on the association. - Made it so with the ASOC_TSN logging on sending or recieving an abort we dump the log. - Went through and added invariant's around some panic's that needed them. - decrements went to atomic_subtact_int instead of add -1 - Removed residual count increment that threw off a strm oq count. - Tracks and complaints if we don't have a LAST fragment and clean up the sp structure. - Track a new stat that counts number of abandoned msgs that happen if you close without reading. - Fix lookup of frag point to be aware of a 0 assoc-id. Reviewed by: gnn
This commit is contained in:
parent
a0c079b341
commit
f1f73e5718
@ -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) {
|
||||
|
@ -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) {
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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 */
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
@ -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(); \
|
||||
} \
|
||||
}
|
||||
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user