diff options
author | rrs <rrs@FreeBSD.org> | 2007-07-02 19:22:22 +0000 |
---|---|---|
committer | rrs <rrs@FreeBSD.org> | 2007-07-02 19:22:22 +0000 |
commit | a400d04306bce1d90fa1fb76eb5ed9c3977a1c32 (patch) | |
tree | 1af5bea59680545d915388b260052ee36e2b1ab6 /sys/netinet/sctp_indata.c | |
parent | bb6f1c3d9ba9c5a3452440ffdafda555b482e1b2 (diff) | |
download | FreeBSD-src-a400d04306bce1d90fa1fb76eb5ed9c3977a1c32.zip FreeBSD-src-a400d04306bce1d90fa1fb76eb5ed9c3977a1c32.tar.gz |
- Consolidate the code that free's chunks to actually also
call the sctp_free_remote_address() function.
- Assure that when we allocate a chunk the whoTo is NULL,
also when we free it and place it into the cache we NULL
it (that way the consolidation code will always work).
- Fix a small race, when a empty data holder is left on the stream
out queue, and both sides do a shutdown, the empty data holder
would prevent us from sending a SHUTDOWN-ACK and at the same time we
never would cleanup the empty holder (since nothing was ever in queue).
We now add a utility function that a) cleans up empty holders and
b) properly determines if there are still pending data chunks on
the stream out wheel.
Approved by: re@freebsd.org (Ken Smith)
Diffstat (limited to 'sys/netinet/sctp_indata.c')
-rw-r--r-- | sys/netinet/sctp_indata.c | 26 |
1 files changed, 15 insertions, 11 deletions
diff --git a/sys/netinet/sctp_indata.c b/sys/netinet/sctp_indata.c index d49721c..06fcddc 100644 --- a/sys/netinet/sctp_indata.c +++ b/sys/netinet/sctp_indata.c @@ -387,7 +387,6 @@ sctp_service_reassembly(struct sctp_tcb *stcb, struct sctp_association *asoc) chk->data = NULL; } /* Now free the address and data */ - sctp_free_remote_addr(chk->whoTo); sctp_free_a_chunk(stcb, chk); /* sa_ignore FREED_MEMORY */ chk = TAILQ_FIRST(&asoc->reasmqueue); @@ -481,7 +480,6 @@ sctp_service_reassembly(struct sctp_tcb *stcb, struct sctp_association *asoc) sctp_ucount_decr(asoc->cnt_on_reasm_queue); /* free up the chk */ chk->data = NULL; - sctp_free_remote_addr(chk->whoTo); sctp_free_a_chunk(stcb, chk); if (asoc->fragmented_delivery_inprogress == 0) { @@ -690,7 +688,9 @@ sctp_queue_data_to_stream(struct sctp_tcb *stcb, struct sctp_association *asoc, control->data = NULL; asoc->size_on_all_streams -= control->length; sctp_ucount_decr(asoc->cnt_on_all_streams); - sctp_free_remote_addr(control->whoFrom); + if (control->whoFrom) + sctp_free_remote_addr(control->whoFrom); + control->whoFrom = NULL; sctp_free_a_readq(stcb, control); return; } else { @@ -1009,7 +1009,6 @@ sctp_queue_data_for_reasm(struct sctp_tcb *stcb, struct sctp_association *asoc, sctp_m_freem(chk->data); chk->data = NULL; } - sctp_free_remote_addr(chk->whoTo); sctp_free_a_chunk(stcb, chk); return; } else { @@ -1876,7 +1875,10 @@ failed_pdapi_express_del: /* Evil/Broke peer */ sctp_m_freem(control->data); control->data = NULL; - sctp_free_remote_addr(control->whoFrom); + if (control->whoFrom) { + sctp_free_remote_addr(control->whoFrom); + control->whoFrom = NULL; + } sctp_free_a_readq(stcb, control); oper = sctp_get_mbuf_for_msg((sizeof(struct sctp_paramhdr) + 3 * sizeof(uint32_t)), 0, M_DONTWAIT, 1, MT_DATA); @@ -1908,7 +1910,10 @@ failed_pdapi_express_del: if (sctp_does_tsn_belong_to_reasm(asoc, control->sinfo_tsn)) { sctp_m_freem(control->data); control->data = NULL; - sctp_free_remote_addr(control->whoFrom); + if (control->whoFrom) { + sctp_free_remote_addr(control->whoFrom); + control->whoFrom = NULL; + } sctp_free_a_readq(stcb, control); oper = sctp_get_mbuf_for_msg((sizeof(struct sctp_paramhdr) + 3 * sizeof(uint32_t)), @@ -1953,7 +1958,10 @@ failed_pdapi_express_del: if (sctp_does_tsn_belong_to_reasm(asoc, control->sinfo_tsn)) { sctp_m_freem(control->data); control->data = NULL; - sctp_free_remote_addr(control->whoFrom); + if (control->whoFrom) { + sctp_free_remote_addr(control->whoFrom); + control->whoFrom = NULL; + } sctp_free_a_readq(stcb, control); oper = sctp_get_mbuf_for_msg((sizeof(struct sctp_paramhdr) + 3 * sizeof(uint32_t)), 0, M_DONTWAIT, 1, MT_DATA); @@ -4318,7 +4326,6 @@ sctp_express_handle_sack(struct sctp_tcb *stcb, uint32_t cumack, } tp1->data = NULL; asoc->sent_queue_cnt--; - sctp_free_remote_addr(tp1->whoTo); sctp_free_a_chunk(stcb, tp1); tp1 = tp2; } @@ -5029,8 +5036,6 @@ skip_segments: } tp1->data = NULL; asoc->sent_queue_cnt--; - sctp_free_remote_addr(tp1->whoTo); - sctp_free_a_chunk(stcb, tp1); wake_him++; tp1 = tp2; @@ -5825,7 +5830,6 @@ sctp_handle_forward_tsn(struct sctp_tcb *stcb, sctp_m_freem(chk->data); chk->data = NULL; } - sctp_free_remote_addr(chk->whoTo); sctp_free_a_chunk(stcb, chk); } else { /* |