sctp_output.c (170943) | sctp_output.c (171158) |
---|---|
1/*- 2 * Copyright (c) 2001-2007, by Cisco Systems, Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions are met: 6 * 7 * a) Redistributions of source code must retain the above copyright notice, 8 * this list of conditions and the following disclaimer. --- 17 unchanged lines hidden (view full) --- 26 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 28 * THE POSSIBILITY OF SUCH DAMAGE. 29 */ 30 31/* $KAME: sctp_output.c,v 1.46 2005/03/06 16:04:17 itojun Exp $ */ 32 33#include <sys/cdefs.h> | 1/*- 2 * Copyright (c) 2001-2007, by Cisco Systems, Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions are met: 6 * 7 * a) Redistributions of source code must retain the above copyright notice, 8 * this list of conditions and the following disclaimer. --- 17 unchanged lines hidden (view full) --- 26 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 28 * THE POSSIBILITY OF SUCH DAMAGE. 29 */ 30 31/* $KAME: sctp_output.c,v 1.46 2005/03/06 16:04:17 itojun Exp $ */ 32 33#include <sys/cdefs.h> |
34__FBSDID("$FreeBSD: head/sys/netinet/sctp_output.c 170943 2007-06-18 22:36:52Z rrs $"); | 34__FBSDID("$FreeBSD: head/sys/netinet/sctp_output.c 171158 2007-07-02 19:22:22Z rrs $"); |
35 36#include <netinet/sctp_os.h> 37#include <sys/proc.h> 38#include <netinet/sctp_var.h> 39#include <netinet/sctp_sysctl.h> 40#include <netinet/sctp_header.h> 41#include <netinet/sctp_pcb.h> 42#include <netinet/sctputil.h> 43#include <netinet/sctp_output.h> 44#include <netinet/sctp_uio.h> 45#include <netinet/sctputil.h> 46#include <netinet/sctp_auth.h> 47#include <netinet/sctp_timer.h> 48#include <netinet/sctp_asconf.h> 49#include <netinet/sctp_indata.h> 50#include <netinet/sctp_bsd_addr.h> | 35 36#include <netinet/sctp_os.h> 37#include <sys/proc.h> 38#include <netinet/sctp_var.h> 39#include <netinet/sctp_sysctl.h> 40#include <netinet/sctp_header.h> 41#include <netinet/sctp_pcb.h> 42#include <netinet/sctputil.h> 43#include <netinet/sctp_output.h> 44#include <netinet/sctp_uio.h> 45#include <netinet/sctputil.h> 46#include <netinet/sctp_auth.h> 47#include <netinet/sctp_timer.h> 48#include <netinet/sctp_asconf.h> 49#include <netinet/sctp_indata.h> 50#include <netinet/sctp_bsd_addr.h> |
51#include <netinet/sctp_input.h> |
|
51 52 53 54#define SCTP_MAX_GAPS_INARRAY 4 55struct sack_track { 56 uint8_t right_edge; /* mergable on the right edge */ 57 uint8_t left_edge; /* mergable on the left edge */ 58 uint8_t num_entries; --- 5578 unchanged lines hidden (view full) --- 5637 } else { 5638 if (m) { 5639 ret = sctp_msg_append(stcb, stcb->asoc.primary_destination, m, 5640 &ca->sndrcv, 1); 5641 } 5642 asoc = &stcb->asoc; 5643 if (ca->sndrcv.sinfo_flags & SCTP_EOF) { 5644 /* shutdown this assoc */ | 52 53 54 55#define SCTP_MAX_GAPS_INARRAY 4 56struct sack_track { 57 uint8_t right_edge; /* mergable on the right edge */ 58 uint8_t left_edge; /* mergable on the left edge */ 59 uint8_t num_entries; --- 5578 unchanged lines hidden (view full) --- 5638 } else { 5639 if (m) { 5640 ret = sctp_msg_append(stcb, stcb->asoc.primary_destination, m, 5641 &ca->sndrcv, 1); 5642 } 5643 asoc = &stcb->asoc; 5644 if (ca->sndrcv.sinfo_flags & SCTP_EOF) { 5645 /* shutdown this assoc */ |
5646 int cnt; 5647 5648 cnt = sctp_is_there_unsent_data(stcb); 5649 |
|
5645 if (TAILQ_EMPTY(&asoc->send_queue) && 5646 TAILQ_EMPTY(&asoc->sent_queue) && | 5650 if (TAILQ_EMPTY(&asoc->send_queue) && 5651 TAILQ_EMPTY(&asoc->sent_queue) && |
5647 (asoc->stream_queue_cnt == 0)) { | 5652 (cnt == 0)) { |
5648 if (asoc->locked_on_sending) { 5649 goto abort_anyway; 5650 } 5651 /* 5652 * there is nothing queued to send, so I'm 5653 * done... 5654 */ 5655 if ((SCTP_GET_STATE(asoc) != SCTP_STATE_SHUTDOWN_SENT) && --- 226 unchanged lines hidden (view full) --- 5882 nchk = TAILQ_NEXT(chk, sctp_next); 5883 if (chk->rec.chunk_id.id == SCTP_COOKIE_ECHO) { 5884 TAILQ_REMOVE(&asoc->control_send_queue, chk, sctp_next); 5885 if (chk->data) { 5886 sctp_m_freem(chk->data); 5887 chk->data = NULL; 5888 } 5889 asoc->ctrl_queue_cnt--; | 5653 if (asoc->locked_on_sending) { 5654 goto abort_anyway; 5655 } 5656 /* 5657 * there is nothing queued to send, so I'm 5658 * done... 5659 */ 5660 if ((SCTP_GET_STATE(asoc) != SCTP_STATE_SHUTDOWN_SENT) && --- 226 unchanged lines hidden (view full) --- 5887 nchk = TAILQ_NEXT(chk, sctp_next); 5888 if (chk->rec.chunk_id.id == SCTP_COOKIE_ECHO) { 5889 TAILQ_REMOVE(&asoc->control_send_queue, chk, sctp_next); 5890 if (chk->data) { 5891 sctp_m_freem(chk->data); 5892 chk->data = NULL; 5893 } 5894 asoc->ctrl_queue_cnt--; |
5890 if (chk->whoTo) 5891 sctp_free_remote_addr(chk->whoTo); | |
5892 sctp_free_a_chunk(stcb, chk); 5893 } 5894 chk = nchk; 5895 } 5896} 5897 5898void 5899sctp_toss_old_asconf(struct sctp_tcb *stcb) --- 9 unchanged lines hidden (view full) --- 5909 /* find SCTP_ASCONF chunk in queue (only one ever in queue) */ 5910 if (chk->rec.chunk_id.id == SCTP_ASCONF) { 5911 TAILQ_REMOVE(&asoc->control_send_queue, chk, sctp_next); 5912 if (chk->data) { 5913 sctp_m_freem(chk->data); 5914 chk->data = NULL; 5915 } 5916 asoc->ctrl_queue_cnt--; | 5895 sctp_free_a_chunk(stcb, chk); 5896 } 5897 chk = nchk; 5898 } 5899} 5900 5901void 5902sctp_toss_old_asconf(struct sctp_tcb *stcb) --- 9 unchanged lines hidden (view full) --- 5912 /* find SCTP_ASCONF chunk in queue (only one ever in queue) */ 5913 if (chk->rec.chunk_id.id == SCTP_ASCONF) { 5914 TAILQ_REMOVE(&asoc->control_send_queue, chk, sctp_next); 5915 if (chk->data) { 5916 sctp_m_freem(chk->data); 5917 chk->data = NULL; 5918 } 5919 asoc->ctrl_queue_cnt--; |
5917 if (chk->whoTo) 5918 sctp_free_remote_addr(chk->whoTo); | |
5919 sctp_free_a_chunk(stcb, chk); 5920 } 5921 } 5922} 5923 5924 5925static void 5926sctp_clean_up_datalist(struct sctp_tcb *stcb, --- 105 unchanged lines hidden (view full) --- 6032 /* Stray chunks must be cleaned up */ 6033 clean_up_anyway: 6034 TAILQ_REMOVE(&asoc->control_send_queue, chk, sctp_next); 6035 if (chk->data) { 6036 sctp_m_freem(chk->data); 6037 chk->data = NULL; 6038 } 6039 asoc->ctrl_queue_cnt--; | 5920 sctp_free_a_chunk(stcb, chk); 5921 } 5922 } 5923} 5924 5925 5926static void 5927sctp_clean_up_datalist(struct sctp_tcb *stcb, --- 105 unchanged lines hidden (view full) --- 6033 /* Stray chunks must be cleaned up */ 6034 clean_up_anyway: 6035 TAILQ_REMOVE(&asoc->control_send_queue, chk, sctp_next); 6036 if (chk->data) { 6037 sctp_m_freem(chk->data); 6038 chk->data = NULL; 6039 } 6040 asoc->ctrl_queue_cnt--; |
6040 sctp_free_remote_addr(chk->whoTo); | |
6041 sctp_free_a_chunk(stcb, chk); 6042 } else if (chk->rec.chunk_id.id == SCTP_STREAM_RESET) { 6043 /* special handling, we must look into the param */ 6044 if (chk != asoc->str_reset) { 6045 goto clean_up_anyway; 6046 } 6047 } 6048 } --- 2935 unchanged lines hidden (view full) --- 8984 if ((a_chk->data == NULL) || 8985 (a_chk->whoTo == NULL)) { 8986 /* rats, no mbuf memory */ 8987 if (a_chk->data) { 8988 /* was a problem with the destination */ 8989 sctp_m_freem(a_chk->data); 8990 a_chk->data = NULL; 8991 } | 6041 sctp_free_a_chunk(stcb, chk); 6042 } else if (chk->rec.chunk_id.id == SCTP_STREAM_RESET) { 6043 /* special handling, we must look into the param */ 6044 if (chk != asoc->str_reset) { 6045 goto clean_up_anyway; 6046 } 6047 } 6048 } --- 2935 unchanged lines hidden (view full) --- 8984 if ((a_chk->data == NULL) || 8985 (a_chk->whoTo == NULL)) { 8986 /* rats, no mbuf memory */ 8987 if (a_chk->data) { 8988 /* was a problem with the destination */ 8989 sctp_m_freem(a_chk->data); 8990 a_chk->data = NULL; 8991 } |
8992 if (a_chk->whoTo) 8993 atomic_subtract_int(&a_chk->whoTo->ref_count, 1); | |
8994 sctp_free_a_chunk(stcb, a_chk); 8995 if (stcb->asoc.delayed_ack) { 8996 sctp_timer_stop(SCTP_TIMER_TYPE_RECV, 8997 stcb->sctp_ep, stcb, NULL, SCTP_FROM_SCTP_OUTPUT + SCTP_LOC_6); 8998 sctp_timer_start(SCTP_TIMER_TYPE_RECV, 8999 stcb->sctp_ep, stcb, NULL); 9000 } else { 9001 stcb->asoc.send_sack = 1; --- 569 unchanged lines hidden (view full) --- 9571 stcb->asoc.max_send_times)) { 9572 /*- 9573 * we have lost the association, in a way this is 9574 * quite bad since we really are one less time since 9575 * we really did not send yet. This is the down side 9576 * to the Q's style as defined in the RFC and not my 9577 * alternate style defined in the RFC. 9578 */ | 8992 sctp_free_a_chunk(stcb, a_chk); 8993 if (stcb->asoc.delayed_ack) { 8994 sctp_timer_stop(SCTP_TIMER_TYPE_RECV, 8995 stcb->sctp_ep, stcb, NULL, SCTP_FROM_SCTP_OUTPUT + SCTP_LOC_6); 8996 sctp_timer_start(SCTP_TIMER_TYPE_RECV, 8997 stcb->sctp_ep, stcb, NULL); 8998 } else { 8999 stcb->asoc.send_sack = 1; --- 569 unchanged lines hidden (view full) --- 9569 stcb->asoc.max_send_times)) { 9570 /*- 9571 * we have lost the association, in a way this is 9572 * quite bad since we really are one less time since 9573 * we really did not send yet. This is the down side 9574 * to the Q's style as defined in the RFC and not my 9575 * alternate style defined in the RFC. 9576 */ |
9579 atomic_subtract_int(&chk->whoTo->ref_count, 1); | |
9580 if (chk->data != NULL) { 9581 sctp_m_freem(chk->data); 9582 chk->data = NULL; 9583 } 9584 sctp_free_a_chunk(stcb, chk); 9585 return (-1); 9586 } 9587 net->hb_responded = 0; --- 1983 unchanged lines hidden (view full) --- 11571 goto out; 11572 } 11573dataless_eof: 11574 /* EOF thing ? */ 11575 if ((srcv->sinfo_flags & SCTP_EOF) && 11576 (got_all_of_the_send == 1) && 11577 (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) 11578 ) { | 9577 if (chk->data != NULL) { 9578 sctp_m_freem(chk->data); 9579 chk->data = NULL; 9580 } 9581 sctp_free_a_chunk(stcb, chk); 9582 return (-1); 9583 } 9584 net->hb_responded = 0; --- 1983 unchanged lines hidden (view full) --- 11568 goto out; 11569 } 11570dataless_eof: 11571 /* EOF thing ? */ 11572 if ((srcv->sinfo_flags & SCTP_EOF) && 11573 (got_all_of_the_send == 1) && 11574 (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) 11575 ) { |
11576 int cnt; 11577 |
|
11579 SCTP_STAT_INCR(sctps_sends_with_eof); 11580 error = 0; 11581 if (hold_tcblock == 0) { 11582 SCTP_TCB_LOCK(stcb); 11583 hold_tcblock = 1; 11584 } | 11578 SCTP_STAT_INCR(sctps_sends_with_eof); 11579 error = 0; 11580 if (hold_tcblock == 0) { 11581 SCTP_TCB_LOCK(stcb); 11582 hold_tcblock = 1; 11583 } |
11584 cnt = sctp_is_there_unsent_data(stcb); |
|
11585 if (TAILQ_EMPTY(&asoc->send_queue) && 11586 TAILQ_EMPTY(&asoc->sent_queue) && | 11585 if (TAILQ_EMPTY(&asoc->send_queue) && 11586 TAILQ_EMPTY(&asoc->sent_queue) && |
11587 (asoc->stream_queue_cnt == 0)) { | 11587 (cnt == 0)) { |
11588 if (asoc->locked_on_sending) { 11589 goto abort_anyway; 11590 } 11591 /* there is nothing queued to send, so I'm done... */ 11592 if ((SCTP_GET_STATE(asoc) != SCTP_STATE_SHUTDOWN_SENT) && 11593 (SCTP_GET_STATE(asoc) != SCTP_STATE_SHUTDOWN_RECEIVED) && 11594 (SCTP_GET_STATE(asoc) != SCTP_STATE_SHUTDOWN_ACK_SENT)) { 11595 /* only send SHUTDOWN the first time through */ --- 280 unchanged lines hidden --- | 11588 if (asoc->locked_on_sending) { 11589 goto abort_anyway; 11590 } 11591 /* there is nothing queued to send, so I'm done... */ 11592 if ((SCTP_GET_STATE(asoc) != SCTP_STATE_SHUTDOWN_SENT) && 11593 (SCTP_GET_STATE(asoc) != SCTP_STATE_SHUTDOWN_RECEIVED) && 11594 (SCTP_GET_STATE(asoc) != SCTP_STATE_SHUTDOWN_ACK_SENT)) { 11595 /* only send SHUTDOWN the first time through */ --- 280 unchanged lines hidden --- |