summaryrefslogtreecommitdiffstats
path: root/sys/netinet/sctputil.c
diff options
context:
space:
mode:
authorrrs <rrs@FreeBSD.org>2007-06-09 13:46:57 +0000
committerrrs <rrs@FreeBSD.org>2007-06-09 13:46:57 +0000
commit4ecfa17662f61c5918ac2f9a900430917a2de0d2 (patch)
tree1afec9873efbc725a9bb5c46d940784789c46118 /sys/netinet/sctputil.c
parentaf285a5d356346bc793bdb7693bb0ab8399d24b9 (diff)
downloadFreeBSD-src-4ecfa17662f61c5918ac2f9a900430917a2de0d2.zip
FreeBSD-src-4ecfa17662f61c5918ac2f9a900430917a2de0d2.tar.gz
- fix send_failed notification contents
- Reorder send failed to be in correct order. - Fixed calulation of init-ack to be right off mbuf lengths instead of the precalculated value. This will fix one 64 bit platform issue.
Diffstat (limited to 'sys/netinet/sctputil.c')
-rw-r--r--sys/netinet/sctputil.c88
1 files changed, 46 insertions, 42 deletions
diff --git a/sys/netinet/sctputil.c b/sys/netinet/sctputil.c
index 2afafcc..9dcc551 100644
--- a/sys/netinet/sctputil.c
+++ b/sys/netinet/sctputil.c
@@ -2925,6 +2925,7 @@ sctp_notify_send_failed(struct sctp_tcb *stcb, uint32_t error,
ssf->ssf_length = length;
ssf->ssf_error = error;
/* not exactly what the user sent in, but should be close :) */
+ bzero(&ssf->ssf_info, sizeof(ssf->ssf_info));
ssf->ssf_info.sinfo_stream = chk->rec.data.stream_number;
ssf->ssf_info.sinfo_ssn = chk->rec.data.stream_seq;
ssf->ssf_info.sinfo_flags = chk->rec.data.rcv_flags;
@@ -2976,7 +2977,7 @@ sctp_notify_send_failed2(struct sctp_tcb *stcb, uint32_t error,
return;
length = sizeof(struct sctp_send_failed) + sp->length;
- m_notify = sctp_get_mbuf_for_msg(sizeof(struct sctp_adaption_event), 0, M_DONTWAIT, 1, MT_DATA);
+ m_notify = sctp_get_mbuf_for_msg(sizeof(struct sctp_send_failed), 0, M_DONTWAIT, 1, MT_DATA);
if (m_notify == NULL)
/* no space left */
return;
@@ -2990,6 +2991,7 @@ sctp_notify_send_failed2(struct sctp_tcb *stcb, uint32_t error,
ssf->ssf_length = length;
ssf->ssf_error = error;
/* not exactly what the user sent in, but should be close :) */
+ bzero(&ssf->ssf_info, sizeof(ssf->ssf_info));
ssf->ssf_info.sinfo_stream = sp->stream;
ssf->ssf_info.sinfo_ssn = sp->strseq;
ssf->ssf_info.sinfo_flags = sp->sinfo_flags;
@@ -3458,38 +3460,12 @@ sctp_report_all_outbound(struct sctp_tcb *stcb, int holds_lock)
if (holds_lock == 0) {
SCTP_TCB_SEND_LOCK(stcb);
}
- for (i = 0; i < stcb->asoc.streamoutcnt; i++) {
- /* For each stream */
- outs = &stcb->asoc.strmout[i];
- /* clean up any sends there */
- stcb->asoc.locked_on_sending = NULL;
- sp = TAILQ_FIRST(&outs->outqueue);
- while (sp) {
- stcb->asoc.stream_queue_cnt--;
- TAILQ_REMOVE(&outs->outqueue, sp, next);
- sctp_free_spbufspace(stcb, asoc, sp);
- sctp_ulp_notify(SCTP_NOTIFY_SPECIAL_SP_FAIL, stcb,
- SCTP_NOTIFY_DATAGRAM_UNSENT, (void *)sp);
- if (sp->data) {
- sctp_m_freem(sp->data);
- sp->data = NULL;
- }
- if (sp->net)
- sctp_free_remote_addr(sp->net);
- sp->net = NULL;
- /* Free the chunk */
- sctp_free_a_strmoq(stcb, sp);
- /* sa_ignore FREED_MEMORY */
- sp = TAILQ_FIRST(&outs->outqueue);
- }
- }
-
- /* pending send queue SHOULD be empty */
- if (!TAILQ_EMPTY(&asoc->send_queue)) {
- chk = TAILQ_FIRST(&asoc->send_queue);
+ /* sent queue SHOULD be empty */
+ if (!TAILQ_EMPTY(&asoc->sent_queue)) {
+ chk = TAILQ_FIRST(&asoc->sent_queue);
while (chk) {
- TAILQ_REMOVE(&asoc->send_queue, chk, sctp_next);
- asoc->send_queue_cnt--;
+ TAILQ_REMOVE(&asoc->sent_queue, chk, sctp_next);
+ asoc->sent_queue_cnt--;
if (chk->data) {
/*
* trim off the sctp chunk header(it should
@@ -3498,10 +3474,12 @@ sctp_report_all_outbound(struct sctp_tcb *stcb, int holds_lock)
if (chk->send_size >= sizeof(struct sctp_data_chunk)) {
m_adj(chk->data, sizeof(struct sctp_data_chunk));
sctp_mbuf_crush(chk->data);
+ chk->send_size -= sizeof(struct sctp_data_chunk);
}
}
sctp_free_bufspace(stcb, asoc, chk, 1);
- sctp_ulp_notify(SCTP_NOTIFY_DG_FAIL, stcb, SCTP_NOTIFY_DATAGRAM_UNSENT, chk);
+ sctp_ulp_notify(SCTP_NOTIFY_DG_FAIL, stcb,
+ SCTP_NOTIFY_DATAGRAM_SENT, chk);
if (chk->data) {
sctp_m_freem(chk->data);
chk->data = NULL;
@@ -3511,15 +3489,15 @@ sctp_report_all_outbound(struct sctp_tcb *stcb, int holds_lock)
chk->whoTo = NULL;
sctp_free_a_chunk(stcb, chk);
/* sa_ignore FREED_MEMORY */
- chk = TAILQ_FIRST(&asoc->send_queue);
+ chk = TAILQ_FIRST(&asoc->sent_queue);
}
}
- /* sent queue SHOULD be empty */
- if (!TAILQ_EMPTY(&asoc->sent_queue)) {
- chk = TAILQ_FIRST(&asoc->sent_queue);
+ /* pending send queue SHOULD be empty */
+ if (!TAILQ_EMPTY(&asoc->send_queue)) {
+ chk = TAILQ_FIRST(&asoc->send_queue);
while (chk) {
- TAILQ_REMOVE(&asoc->sent_queue, chk, sctp_next);
- asoc->sent_queue_cnt--;
+ TAILQ_REMOVE(&asoc->send_queue, chk, sctp_next);
+ asoc->send_queue_cnt--;
if (chk->data) {
/*
* trim off the sctp chunk header(it should
@@ -3528,11 +3506,11 @@ sctp_report_all_outbound(struct sctp_tcb *stcb, int holds_lock)
if (chk->send_size >= sizeof(struct sctp_data_chunk)) {
m_adj(chk->data, sizeof(struct sctp_data_chunk));
sctp_mbuf_crush(chk->data);
+ chk->send_size -= sizeof(struct sctp_data_chunk);
}
}
sctp_free_bufspace(stcb, asoc, chk, 1);
- sctp_ulp_notify(SCTP_NOTIFY_DG_FAIL, stcb,
- SCTP_NOTIFY_DATAGRAM_SENT, chk);
+ sctp_ulp_notify(SCTP_NOTIFY_DG_FAIL, stcb, SCTP_NOTIFY_DATAGRAM_UNSENT, chk);
if (chk->data) {
sctp_m_freem(chk->data);
chk->data = NULL;
@@ -3542,9 +3520,35 @@ sctp_report_all_outbound(struct sctp_tcb *stcb, int holds_lock)
chk->whoTo = NULL;
sctp_free_a_chunk(stcb, chk);
/* sa_ignore FREED_MEMORY */
- chk = TAILQ_FIRST(&asoc->sent_queue);
+ chk = TAILQ_FIRST(&asoc->send_queue);
+ }
+ }
+ for (i = 0; i < stcb->asoc.streamoutcnt; i++) {
+ /* For each stream */
+ outs = &stcb->asoc.strmout[i];
+ /* clean up any sends there */
+ stcb->asoc.locked_on_sending = NULL;
+ sp = TAILQ_FIRST(&outs->outqueue);
+ while (sp) {
+ stcb->asoc.stream_queue_cnt--;
+ TAILQ_REMOVE(&outs->outqueue, sp, next);
+ sctp_free_spbufspace(stcb, asoc, sp);
+ sctp_ulp_notify(SCTP_NOTIFY_SPECIAL_SP_FAIL, stcb,
+ SCTP_NOTIFY_DATAGRAM_UNSENT, (void *)sp);
+ if (sp->data) {
+ sctp_m_freem(sp->data);
+ sp->data = NULL;
+ }
+ if (sp->net)
+ sctp_free_remote_addr(sp->net);
+ sp->net = NULL;
+ /* Free the chunk */
+ sctp_free_a_strmoq(stcb, sp);
+ /* sa_ignore FREED_MEMORY */
+ sp = TAILQ_FIRST(&outs->outqueue);
}
}
+
if (holds_lock == 0) {
SCTP_TCB_SEND_UNLOCK(stcb);
}
OpenPOWER on IntegriCloud