diff options
author | rrs <rrs@FreeBSD.org> | 2007-06-09 13:46:57 +0000 |
---|---|---|
committer | rrs <rrs@FreeBSD.org> | 2007-06-09 13:46:57 +0000 |
commit | 4ecfa17662f61c5918ac2f9a900430917a2de0d2 (patch) | |
tree | 1afec9873efbc725a9bb5c46d940784789c46118 /sys/netinet/sctputil.c | |
parent | af285a5d356346bc793bdb7693bb0ab8399d24b9 (diff) | |
download | FreeBSD-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.c | 88 |
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); } |