Fix the aborting of association with the iterator using an empty
user initiated error cause (using SCTP_ABORT|SCTP_SENDALL). Approved by: re (delphij) MFC after: 1 week
This commit is contained in:
parent
30d663c74e
commit
5dc80df9c5
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=255434
@ -6412,7 +6412,7 @@ sctp_sendall_iterator(struct sctp_inpcb *inp, struct sctp_tcb *stcb, void *ptr,
|
||||
/* TSNH */
|
||||
return;
|
||||
}
|
||||
if ((ca->m) && ca->sndlen) {
|
||||
if (ca->sndlen > 0) {
|
||||
m = SCTP_M_COPYM(ca->m, 0, M_COPYALL, M_NOWAIT);
|
||||
if (m == NULL) {
|
||||
/* can't copy so we are done */
|
||||
@ -6441,38 +6441,40 @@ sctp_sendall_iterator(struct sctp_inpcb *inp, struct sctp_tcb *stcb, void *ptr,
|
||||
}
|
||||
if (ca->sndrcv.sinfo_flags & SCTP_ABORT) {
|
||||
/* Abort this assoc with m as the user defined reason */
|
||||
if (m) {
|
||||
if (m != NULL) {
|
||||
SCTP_BUF_PREPEND(m, sizeof(struct sctp_paramhdr), M_NOWAIT);
|
||||
} else {
|
||||
m = sctp_get_mbuf_for_msg(sizeof(struct sctp_paramhdr),
|
||||
0, M_NOWAIT, 1, MT_DATA);
|
||||
SCTP_BUF_LEN(m) = sizeof(struct sctp_paramhdr);
|
||||
}
|
||||
if (m != NULL) {
|
||||
struct sctp_paramhdr *ph;
|
||||
|
||||
SCTP_BUF_PREPEND(m, sizeof(struct sctp_paramhdr), M_NOWAIT);
|
||||
if (m) {
|
||||
ph = mtod(m, struct sctp_paramhdr *);
|
||||
ph->param_type = htons(SCTP_CAUSE_USER_INITIATED_ABT);
|
||||
ph->param_length = htons(sizeof(struct sctp_paramhdr) + ca->sndlen);
|
||||
}
|
||||
/*
|
||||
* We add one here to keep the assoc from
|
||||
* dis-appearing on us.
|
||||
*/
|
||||
atomic_add_int(&stcb->asoc.refcnt, 1);
|
||||
sctp_abort_an_association(inp, stcb, m, SCTP_SO_NOT_LOCKED);
|
||||
/*
|
||||
* sctp_abort_an_association calls sctp_free_asoc()
|
||||
* free association will NOT free it since we
|
||||
* incremented the refcnt .. we do this to prevent
|
||||
* it being freed and things getting tricky since we
|
||||
* could end up (from free_asoc) calling inpcb_free
|
||||
* which would get a recursive lock call to the
|
||||
* iterator lock.. But as a consequence of that the
|
||||
* stcb will return to us un-locked.. since
|
||||
* free_asoc returns with either no TCB or the TCB
|
||||
* unlocked, we must relock.. to unlock in the
|
||||
* iterator timer :-0
|
||||
*/
|
||||
SCTP_TCB_LOCK(stcb);
|
||||
atomic_add_int(&stcb->asoc.refcnt, -1);
|
||||
goto no_chunk_output;
|
||||
ph = mtod(m, struct sctp_paramhdr *);
|
||||
ph->param_type = htons(SCTP_CAUSE_USER_INITIATED_ABT);
|
||||
ph->param_length = htons(sizeof(struct sctp_paramhdr) + ca->sndlen);
|
||||
}
|
||||
/*
|
||||
* We add one here to keep the assoc from dis-appearing on
|
||||
* us.
|
||||
*/
|
||||
atomic_add_int(&stcb->asoc.refcnt, 1);
|
||||
sctp_abort_an_association(inp, stcb, m, SCTP_SO_NOT_LOCKED);
|
||||
/*
|
||||
* sctp_abort_an_association calls sctp_free_asoc() free
|
||||
* association will NOT free it since we incremented the
|
||||
* refcnt .. we do this to prevent it being freed and things
|
||||
* getting tricky since we could end up (from free_asoc)
|
||||
* calling inpcb_free which would get a recursive lock call
|
||||
* to the iterator lock.. But as a consequence of that the
|
||||
* stcb will return to us un-locked.. since free_asoc
|
||||
* returns with either no TCB or the TCB unlocked, we must
|
||||
* relock.. to unlock in the iterator timer :-0
|
||||
*/
|
||||
SCTP_TCB_LOCK(stcb);
|
||||
atomic_add_int(&stcb->asoc.refcnt, -1);
|
||||
goto no_chunk_output;
|
||||
} else {
|
||||
if (m) {
|
||||
ret = sctp_msg_append(stcb, net, m,
|
||||
@ -6566,8 +6568,7 @@ sctp_sendall_iterator(struct sctp_inpcb *inp, struct sctp_tcb *stcb, void *ptr,
|
||||
|
||||
if ((sctp_is_feature_off(inp, SCTP_PCB_FLAGS_NODELAY)) &&
|
||||
(stcb->asoc.total_flight > 0) &&
|
||||
(un_sent < (int)(stcb->asoc.smallest_mtu - SCTP_MIN_OVERHEAD))
|
||||
) {
|
||||
(un_sent < (int)(stcb->asoc.smallest_mtu - SCTP_MIN_OVERHEAD))) {
|
||||
do_chunk_output = 0;
|
||||
}
|
||||
if (do_chunk_output)
|
||||
@ -6696,13 +6697,10 @@ sctp_sendall(struct sctp_inpcb *inp, struct uio *uio, struct mbuf *m,
|
||||
/* Gather the length of the send */
|
||||
struct mbuf *mat;
|
||||
|
||||
mat = m;
|
||||
ca->sndlen = 0;
|
||||
while (m) {
|
||||
ca->sndlen += SCTP_BUF_LEN(m);
|
||||
m = SCTP_BUF_NEXT(m);
|
||||
for (mat = m; mat; mat = SCTP_BUF_NEXT(mat)) {
|
||||
ca->sndlen += SCTP_BUF_LEN(mat);
|
||||
}
|
||||
ca->m = mat;
|
||||
}
|
||||
ret = sctp_initiate_iterator(NULL, sctp_sendall_iterator, NULL,
|
||||
SCTP_PCB_ANY_FLAGS, SCTP_PCB_ANY_FEATURES,
|
||||
|
Loading…
Reference in New Issue
Block a user