summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authorrrs <rrs@FreeBSD.org>2007-12-06 00:22:55 +0000
committerrrs <rrs@FreeBSD.org>2007-12-06 00:22:55 +0000
commit475b5616558f70d42e26258e5c744cf8b400f258 (patch)
tree04be9199e13286fd70174279e01025f63a5f46ab /sys
parente9665dcb0a25e85f22330fc96f8e07dc01796154 (diff)
downloadFreeBSD-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
Diffstat (limited to 'sys')
-rw-r--r--sys/netinet/sctp_output.c18
-rw-r--r--sys/netinet/sctputil.c11
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) &&
OpenPOWER on IntegriCloud