svn commit: r265966 - stable/9/sys/netinet
Michael Tuexen
tuexen at FreeBSD.org
Tue May 13 17:51:15 UTC 2014
Author: tuexen
Date: Tue May 13 17:51:15 2014
New Revision: 265966
URL: http://svnweb.freebsd.org/changeset/base/265966
Log:
MFC r255434:
Fix the aborting of association with the iterator using an empty
user initiated error cause (using SCTP_ABORT|SCTP_SENDALL).
Modified:
stable/9/sys/netinet/sctp_output.c
Directory Properties:
stable/9/sys/ (props changed)
Modified: stable/9/sys/netinet/sctp_output.c
==============================================================================
--- stable/9/sys/netinet/sctp_output.c Tue May 13 17:41:39 2014 (r265965)
+++ stable/9/sys/netinet/sctp_output.c Tue May 13 17:51:15 2014 (r265966)
@@ -6412,7 +6412,7 @@ sctp_sendall_iterator(struct sctp_inpcb
/* TSNH */
return;
}
- if ((ca->m) && ca->sndlen) {
+ if (ca->sndlen > 0) {
m = SCTP_M_COPYM(ca->m, 0, M_COPYALL, M_DONTWAIT);
if (m == NULL) {
/* can't copy so we are done */
@@ -6441,38 +6441,40 @@ sctp_sendall_iterator(struct sctp_inpcb
}
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_DONTWAIT);
- 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
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, str
/* 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,
More information about the svn-src-stable-9
mailing list