summaryrefslogtreecommitdiffstats
path: root/sys/netinet
diff options
context:
space:
mode:
authorrrs <rrs@FreeBSD.org>2010-07-26 09:22:52 +0000
committerrrs <rrs@FreeBSD.org>2010-07-26 09:22:52 +0000
commit88ff5f0e8cb11275170b89d235f96cc54721269e (patch)
tree764063735524f837909e1ab5b9ddfd8e3f4b7803 /sys/netinet
parentaaaecc410064ae4b587ec6d856ced5dd96d85c61 (diff)
downloadFreeBSD-src-88ff5f0e8cb11275170b89d235f96cc54721269e.zip
FreeBSD-src-88ff5f0e8cb11275170b89d235f96cc54721269e.tar.gz
Make sure that we report chunks if a socket
still exists that were not sent. In either case carefully remove the data if it does not get taken by the reporting routines. MFC after: 2 weeks
Diffstat (limited to 'sys/netinet')
-rw-r--r--sys/netinet/sctp_pcb.c36
1 files changed, 29 insertions, 7 deletions
diff --git a/sys/netinet/sctp_pcb.c b/sys/netinet/sctp_pcb.c
index 559938a..ad8bc52 100644
--- a/sys/netinet/sctp_pcb.c
+++ b/sys/netinet/sctp_pcb.c
@@ -4830,9 +4830,17 @@ sctp_free_assoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb, int from_inpcbfre
while (sp) {
TAILQ_REMOVE(&outs->outqueue, sp, next);
if (sp->data) {
- sctp_m_freem(sp->data);
- sp->data = NULL;
- sp->tail_mbuf = NULL;
+ if (so) {
+ /* Still an open socket - report */
+ sctp_ulp_notify(SCTP_NOTIFY_SPECIAL_SP_FAIL, stcb,
+ SCTP_NOTIFY_DATAGRAM_UNSENT,
+ (void *)sp, 0);
+ }
+ if (sp->data) {
+ sctp_m_freem(sp->data);
+ sp->data = NULL;
+ sp->tail_mbuf = NULL;
+ }
}
sctp_free_remote_addr(sp->net);
sctp_free_spbufspace(stcb, asoc, sp);
@@ -4892,8 +4900,15 @@ sctp_free_assoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb, int from_inpcbfre
while (chk) {
TAILQ_REMOVE(&asoc->send_queue, chk, sctp_next);
if (chk->data) {
- sctp_m_freem(chk->data);
- chk->data = NULL;
+ if (so) {
+ /* Still a socket? */
+ sctp_ulp_notify(SCTP_NOTIFY_DG_FAIL, stcb,
+ SCTP_NOTIFY_DATAGRAM_UNSENT, chk, 0);
+ }
+ if (chk->data) {
+ sctp_m_freem(chk->data);
+ chk->data = NULL;
+ }
}
if (chk->holds_key_ref)
sctp_auth_key_release(stcb, chk->auth_keyid);
@@ -4917,8 +4932,15 @@ sctp_free_assoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb, int from_inpcbfre
while (chk) {
TAILQ_REMOVE(&asoc->sent_queue, chk, sctp_next);
if (chk->data) {
- sctp_m_freem(chk->data);
- chk->data = NULL;
+ if (so) {
+ /* Still a socket? */
+ sctp_ulp_notify(SCTP_NOTIFY_DG_FAIL, stcb,
+ SCTP_NOTIFY_DATAGRAM_SENT, chk, 0);
+ }
+ if (chk->data) {
+ sctp_m_freem(chk->data);
+ chk->data = NULL;
+ }
}
if (chk->holds_key_ref)
sctp_auth_key_release(stcb, chk->auth_keyid);
OpenPOWER on IntegriCloud