diff options
author | rrs <rrs@FreeBSD.org> | 2007-12-06 00:22:55 +0000 |
---|---|---|
committer | rrs <rrs@FreeBSD.org> | 2007-12-06 00:22:55 +0000 |
commit | 475b5616558f70d42e26258e5c744cf8b400f258 (patch) | |
tree | 04be9199e13286fd70174279e01025f63a5f46ab | |
parent | e9665dcb0a25e85f22330fc96f8e07dc01796154 (diff) | |
download | FreeBSD-src-475b5616558f70d42e26258e5c744cf8b400f258.zip FreeBSD-src-475b5616558f70d42e26258e5c744cf8b400f258.tar.gz |
- optimize the initialization of the SB max variables.
- Missing lock when sending data and moving it to the
outqueue.
- If a mbuf alloc fails during moving to outqueue the
reassembly of the old mbuf chain was incorrect.
- some_taken becomes a counter in sctputil.c instead of a set to 1.
- Fix a panic to be only under invarients and have a proper recovery.
- msg_flags needed to be set.to the value collected not or'd.
MFC after: 1 week
-rw-r--r-- | sys/netinet/sctp_output.c | 18 | ||||
-rw-r--r-- | sys/netinet/sctputil.c | 11 |
2 files changed, 20 insertions, 9 deletions
diff --git a/sys/netinet/sctp_output.c b/sys/netinet/sctp_output.c index d1c9d71..7299702 100644 --- a/sys/netinet/sctp_output.c +++ b/sys/netinet/sctp_output.c @@ -6459,6 +6459,10 @@ out_gu: /* clear out the chunk before setting up */ memset(chk, 0, sizeof(*chk)); chk->rec.data.rcv_flags = rcv_flags; + if ((send_lock_up == 0) && (sp->msg_is_complete == 0)) { + SCTP_TCB_SEND_LOCK(stcb); + send_lock_up = 1; + } if (SCTP_BUF_IS_EXTENDED(sp->data)) { chk->copy_by_ref = 1; } else { @@ -6521,6 +6525,12 @@ out_gu: } else { atomic_subtract_int(&sp->length, to_move); } + if (chk->last_mbuf == NULL) { + chk->last_mbuf = chk->data; + while (SCTP_BUF_NEXT(chk->last_mbuf) != NULL) { + chk->last_mbuf = SCTP_BUF_NEXT(chk->last_mbuf); + } + } if (M_LEADINGSPACE(chk->data) < (int)sizeof(struct sctp_data_chunk)) { /* Not enough room for a chunk header, get some */ struct mbuf *m; @@ -6546,7 +6556,7 @@ out_gu: /* reassemble the data */ m_tmp = sp->data; sp->data = chk->data; - SCTP_BUF_NEXT(sp->data) = m_tmp; + SCTP_BUF_NEXT(chk->last_mbuf) = m_tmp; } sp->some_taken = some_taken; atomic_add_int(&sp->length, to_move); @@ -6583,12 +6593,6 @@ out_gu: * get last_mbuf and counts of mb useage This is ugly but hopefully * its only one mbuf. */ - if (chk->last_mbuf == NULL) { - chk->last_mbuf = chk->data; - while (SCTP_BUF_NEXT(chk->last_mbuf) != NULL) { - chk->last_mbuf = SCTP_BUF_NEXT(chk->last_mbuf); - } - } chk->flags = 0; chk->asoc = &stcb->asoc; chk->pad_inplace = 0; diff --git a/sys/netinet/sctputil.c b/sys/netinet/sctputil.c index fb660c8..906ad6e 100644 --- a/sys/netinet/sctputil.c +++ b/sys/netinet/sctputil.c @@ -5260,7 +5260,7 @@ found_one: * If we reach here, control has a some data for us to read off. * Note that stcb COULD be NULL. */ - control->some_taken = 1; + control->some_taken++; if (hold_sblock) { SOCKBUF_UNLOCK(&so->so_rcv); hold_sblock = 0; @@ -5731,7 +5731,14 @@ wait_some_more: * big trouble.. we have the lock and its * corrupt? */ +#ifdef INVARIANTS panic("Impossible data==NULL length !=0"); +#endif + out_flags |= MSG_EOR; + out_flags |= MSG_TRUNC; + control->length = 0; + SCTP_INP_READ_UNLOCK(inp); + goto done_with_control; } SCTP_INP_READ_UNLOCK(inp); /* We will fall around to get more data */ @@ -5807,7 +5814,7 @@ release_unlocked: sctp_user_rcvd(stcb, &freed_so_far, hold_rlock, rwnd_req); } if (msg_flags) - *msg_flags |= out_flags; + *msg_flags = out_flags; out: if (((out_flags & MSG_EOR) == 0) && ((in_flags & MSG_PEEK) == 0) && |