diff options
author | rrs <rrs@FreeBSD.org> | 2010-07-26 09:22:52 +0000 |
---|---|---|
committer | rrs <rrs@FreeBSD.org> | 2010-07-26 09:22:52 +0000 |
commit | 88ff5f0e8cb11275170b89d235f96cc54721269e (patch) | |
tree | 764063735524f837909e1ab5b9ddfd8e3f4b7803 /sys/netinet | |
parent | aaaecc410064ae4b587ec6d856ced5dd96d85c61 (diff) | |
download | FreeBSD-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.c | 36 |
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); |