Deleted Added
full compact
sctp_indata.c (169655) sctp_indata.c (170056)
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_indata.c,v 1.36 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_indata.c,v 1.36 2005/03/06 16:04:17 itojun Exp $ */
32
33#include <sys/cdefs.h>
34__FBSDID("$FreeBSD: head/sys/netinet/sctp_indata.c 169655 2007-05-17 12:16:24Z rrs $");
34__FBSDID("$FreeBSD: head/sys/netinet/sctp_indata.c 170056 2007-05-28 11:17:24Z rrs $");
35
36#include <netinet/sctp_os.h>
37#include <netinet/sctp_var.h>
38#include <netinet/sctp_sysctl.h>
39#include <netinet/sctp_pcb.h>
40#include <netinet/sctp_header.h>
41#include <netinet/sctputil.h>
42#include <netinet/sctp_output.h>

--- 1561 unchanged lines hidden (view full) ---

1604 /*
1605 * Before we continue lets validate that we are not being fooled by
1606 * an evil attacker. We can only have 4k chunks based on our TSN
1607 * spread allowed by the mapping array 512 * 8 bits, so there is no
1608 * way our stream sequence numbers could have wrapped. We of course
1609 * only validate the FIRST fragment so the bit must be set.
1610 */
1611 strmseq = ntohs(ch->dp.stream_sequence);
35
36#include <netinet/sctp_os.h>
37#include <netinet/sctp_var.h>
38#include <netinet/sctp_sysctl.h>
39#include <netinet/sctp_pcb.h>
40#include <netinet/sctp_header.h>
41#include <netinet/sctputil.h>
42#include <netinet/sctp_output.h>

--- 1561 unchanged lines hidden (view full) ---

1604 /*
1605 * Before we continue lets validate that we are not being fooled by
1606 * an evil attacker. We can only have 4k chunks based on our TSN
1607 * spread allowed by the mapping array 512 * 8 bits, so there is no
1608 * way our stream sequence numbers could have wrapped. We of course
1609 * only validate the FIRST fragment so the bit must be set.
1610 */
1611 strmseq = ntohs(ch->dp.stream_sequence);
1612
1613#ifdef SCTP_ASOCLOG_OF_TSNS
1614 asoc->in_tsnlog[asoc->tsn_in_at].tsn = tsn;
1615 asoc->in_tsnlog[asoc->tsn_in_at].strm = strmno;
1616 asoc->in_tsnlog[asoc->tsn_in_at].seq = strmseq;
1617 asoc->in_tsnlog[asoc->tsn_in_at].sz = chk_length;
1618 asoc->in_tsnlog[asoc->tsn_in_at].flgs = chunk_flags;
1619 asoc->tsn_in_at++;
1620 if (asoc->tsn_in_at >= SCTP_TSN_LOG_SIZE) {
1621 asoc->tsn_in_at = 0;
1622 asoc->tsn_in_wrapped = 1;
1623 }
1624#endif
1625 if ((chunk_flags & SCTP_DATA_FIRST_FRAG) &&
1612#ifdef SCTP_ASOCLOG_OF_TSNS
1613 asoc->in_tsnlog[asoc->tsn_in_at].tsn = tsn;
1614 asoc->in_tsnlog[asoc->tsn_in_at].strm = strmno;
1615 asoc->in_tsnlog[asoc->tsn_in_at].seq = strmseq;
1616 asoc->in_tsnlog[asoc->tsn_in_at].sz = chk_length;
1617 asoc->in_tsnlog[asoc->tsn_in_at].flgs = chunk_flags;
1618 asoc->tsn_in_at++;
1619 if (asoc->tsn_in_at >= SCTP_TSN_LOG_SIZE) {
1620 asoc->tsn_in_at = 0;
1621 asoc->tsn_in_wrapped = 1;
1622 }
1623#endif
1624 if ((chunk_flags & SCTP_DATA_FIRST_FRAG) &&
1625 (TAILQ_EMPTY(&asoc->resetHead)) &&
1626 (chunk_flags & SCTP_DATA_UNORDERED) == 0 &&
1627 (compare_with_wrap(asoc->strmin[strmno].last_sequence_delivered,
1628 strmseq, MAX_SEQ) ||
1629 asoc->strmin[strmno].last_sequence_delivered == strmseq)) {
1630 /* The incoming sseq is behind where we last delivered? */
1631 SCTPDBG(SCTP_DEBUG_INDATA1, "EVIL/Broken-Dup S-SEQ:%d delivered:%d from peer, Abort!\n",
1632 strmseq, asoc->strmin[strmno].last_sequence_delivered);
1633 oper = sctp_get_mbuf_for_msg((sizeof(struct sctp_paramhdr) + 3 * sizeof(uint32_t)),

--- 367 unchanged lines hidden (view full) ---

2001 * We take complete messages that have a stream reset
2002 * intervening (aka the TSN is after where our
2003 * cum-ack needs to be) off and put them on a
2004 * pending_reply_queue. The reassembly ones we do
2005 * not have to worry about since they are all sorted
2006 * and proceessed by TSN order. It is only the
2007 * singletons I must worry about.
2008 */
1626 (chunk_flags & SCTP_DATA_UNORDERED) == 0 &&
1627 (compare_with_wrap(asoc->strmin[strmno].last_sequence_delivered,
1628 strmseq, MAX_SEQ) ||
1629 asoc->strmin[strmno].last_sequence_delivered == strmseq)) {
1630 /* The incoming sseq is behind where we last delivered? */
1631 SCTPDBG(SCTP_DEBUG_INDATA1, "EVIL/Broken-Dup S-SEQ:%d delivered:%d from peer, Abort!\n",
1632 strmseq, asoc->strmin[strmno].last_sequence_delivered);
1633 oper = sctp_get_mbuf_for_msg((sizeof(struct sctp_paramhdr) + 3 * sizeof(uint32_t)),

--- 367 unchanged lines hidden (view full) ---

2001 * We take complete messages that have a stream reset
2002 * intervening (aka the TSN is after where our
2003 * cum-ack needs to be) off and put them on a
2004 * pending_reply_queue. The reassembly ones we do
2005 * not have to worry about since they are all sorted
2006 * and proceessed by TSN order. It is only the
2007 * singletons I must worry about.
2008 */
2009 struct sctp_stream_reset_list *liste;
2010
2011 if (((liste = TAILQ_FIRST(&asoc->resetHead)) != NULL) &&
2009 if (((liste = TAILQ_FIRST(&asoc->resetHead)) != NULL) &&
2012 ((compare_with_wrap(tsn, ntohl(liste->tsn), MAX_TSN)) ||
2013 (tsn == ntohl(liste->tsn)))
2010 ((compare_with_wrap(tsn, liste->tsn, MAX_TSN)))
2014 ) {
2015 /*
2016 * yep its past where we need to reset... go
2017 * ahead and queue it.
2018 */
2019 if (TAILQ_EMPTY(&asoc->pending_reply_queue)) {
2020 /* first one on */
2021 TAILQ_INSERT_TAIL(&asoc->pending_reply_queue, control, next);

--- 68 unchanged lines hidden (view full) ---

2090#endif
2091#ifdef SCTP_MAP_LOGGING
2092 sctp_log_map(asoc->mapping_array_base_tsn, asoc->cumulative_tsn,
2093 asoc->highest_tsn_inside_map, SCTP_MAP_PREPARE_SLIDE);
2094#endif
2095 SCTP_SET_TSN_PRESENT(asoc->mapping_array, gap);
2096 /* check the special flag for stream resets */
2097 if (((liste = TAILQ_FIRST(&asoc->resetHead)) != NULL) &&
2011 ) {
2012 /*
2013 * yep its past where we need to reset... go
2014 * ahead and queue it.
2015 */
2016 if (TAILQ_EMPTY(&asoc->pending_reply_queue)) {
2017 /* first one on */
2018 TAILQ_INSERT_TAIL(&asoc->pending_reply_queue, control, next);

--- 68 unchanged lines hidden (view full) ---

2087#endif
2088#ifdef SCTP_MAP_LOGGING
2089 sctp_log_map(asoc->mapping_array_base_tsn, asoc->cumulative_tsn,
2090 asoc->highest_tsn_inside_map, SCTP_MAP_PREPARE_SLIDE);
2091#endif
2092 SCTP_SET_TSN_PRESENT(asoc->mapping_array, gap);
2093 /* check the special flag for stream resets */
2094 if (((liste = TAILQ_FIRST(&asoc->resetHead)) != NULL) &&
2098 ((compare_with_wrap(asoc->cumulative_tsn, ntohl(liste->tsn), MAX_TSN)) ||
2099 (asoc->cumulative_tsn == ntohl(liste->tsn)))
2095 ((compare_with_wrap(asoc->cumulative_tsn, liste->tsn, MAX_TSN)) ||
2096 (asoc->cumulative_tsn == liste->tsn))
2100 ) {
2101 /*
2102 * we have finished working through the backlogged TSN's now
2103 * time to reset streams. 1: call reset function. 2: free
2104 * pending_reply space 3: distribute any chunks in
2105 * pending_reply_queue.
2106 */
2107 struct sctp_queued_to_read *ctl;

--- 11 unchanged lines hidden (view full) ---

2119 sctp_queue_data_to_stream(stcb, asoc, ctl, abort_flag);
2120 if (*abort_flag) {
2121 return (0);
2122 }
2123 ctl = TAILQ_FIRST(&asoc->pending_reply_queue);
2124 }
2125 } else if (ctl) {
2126 /* more than one in queue */
2097 ) {
2098 /*
2099 * we have finished working through the backlogged TSN's now
2100 * time to reset streams. 1: call reset function. 2: free
2101 * pending_reply space 3: distribute any chunks in
2102 * pending_reply_queue.
2103 */
2104 struct sctp_queued_to_read *ctl;

--- 11 unchanged lines hidden (view full) ---

2116 sctp_queue_data_to_stream(stcb, asoc, ctl, abort_flag);
2117 if (*abort_flag) {
2118 return (0);
2119 }
2120 ctl = TAILQ_FIRST(&asoc->pending_reply_queue);
2121 }
2122 } else if (ctl) {
2123 /* more than one in queue */
2127 while (!compare_with_wrap(ctl->sinfo_tsn, ntohl(liste->tsn), MAX_TSN)) {
2124 while (!compare_with_wrap(ctl->sinfo_tsn, liste->tsn, MAX_TSN)) {
2128 /*
2129 * if ctl->sinfo_tsn is <= liste->tsn we can
2130 * process it which is the NOT of
2131 * ctl->sinfo_tsn > liste->tsn
2132 */
2133 TAILQ_REMOVE(&asoc->pending_reply_queue, ctl, next);
2134 sctp_queue_data_to_stream(stcb, asoc, ctl, abort_flag);
2135 if (*abort_flag) {

--- 527 unchanged lines hidden (view full) ---

2663 sctp_abort_association(inp, stcb, m, iphlen, sh, op_err, 0, 0);
2664 return (2);
2665 }
2666 break;
2667 default:
2668 /* unknown chunk type, use bit rules */
2669 if (ch->ch.chunk_type & 0x40) {
2670 /* Add a error report to the queue */
2125 /*
2126 * if ctl->sinfo_tsn is <= liste->tsn we can
2127 * process it which is the NOT of
2128 * ctl->sinfo_tsn > liste->tsn
2129 */
2130 TAILQ_REMOVE(&asoc->pending_reply_queue, ctl, next);
2131 sctp_queue_data_to_stream(stcb, asoc, ctl, abort_flag);
2132 if (*abort_flag) {

--- 527 unchanged lines hidden (view full) ---

2660 sctp_abort_association(inp, stcb, m, iphlen, sh, op_err, 0, 0);
2661 return (2);
2662 }
2663 break;
2664 default:
2665 /* unknown chunk type, use bit rules */
2666 if (ch->ch.chunk_type & 0x40) {
2667 /* Add a error report to the queue */
2671 struct mbuf *mm;
2668 struct mbuf *merr;
2672 struct sctp_paramhdr *phd;
2673
2669 struct sctp_paramhdr *phd;
2670
2674 mm = sctp_get_mbuf_for_msg(sizeof(*phd), 0, M_DONTWAIT, 1, MT_DATA);
2675 if (mm) {
2676 phd = mtod(mm, struct sctp_paramhdr *);
2671 merr = sctp_get_mbuf_for_msg(sizeof(*phd), 0, M_DONTWAIT, 1, MT_DATA);
2672 if (merr) {
2673 phd = mtod(merr, struct sctp_paramhdr *);
2677 /*
2678 * We cheat and use param
2679 * type since we did not
2680 * bother to define a error
2681 * cause struct. They are
2682 * the same basic format
2683 * with different names.
2684 */
2685 phd->param_type =
2686 htons(SCTP_CAUSE_UNRECOG_CHUNK);
2687 phd->param_length =
2688 htons(chk_length + sizeof(*phd));
2674 /*
2675 * We cheat and use param
2676 * type since we did not
2677 * bother to define a error
2678 * cause struct. They are
2679 * the same basic format
2680 * with different names.
2681 */
2682 phd->param_type =
2683 htons(SCTP_CAUSE_UNRECOG_CHUNK);
2684 phd->param_length =
2685 htons(chk_length + sizeof(*phd));
2689 SCTP_BUF_LEN(mm) = sizeof(*phd);
2690 SCTP_BUF_NEXT(mm) = SCTP_M_COPYM(m, *offset,
2686 SCTP_BUF_LEN(merr) = sizeof(*phd);
2687 SCTP_BUF_NEXT(merr) = SCTP_M_COPYM(m, *offset,
2691 SCTP_SIZE32(chk_length),
2692 M_DONTWAIT);
2688 SCTP_SIZE32(chk_length),
2689 M_DONTWAIT);
2693 if (SCTP_BUF_NEXT(mm)) {
2694 sctp_queue_op_err(stcb, mm);
2690 if (SCTP_BUF_NEXT(merr)) {
2691 sctp_queue_op_err(stcb, merr);
2695 } else {
2692 } else {
2696 sctp_m_freem(mm);
2693 sctp_m_freem(merr);
2697 }
2698 }
2699 }
2700 if ((ch->ch.chunk_type & 0x80) == 0) {
2701 /* discard the rest of this packet */
2702 stop_proc = 1;
2703 } /* else skip this bad chunk and
2704 * continue... */

--- 3183 unchanged lines hidden (view full) ---

5888 }
5889 /*************************************************************/
5890 /* 3. Update the PR-stream re-ordering queues */
5891 /*************************************************************/
5892 stseq = (struct sctp_strseq *)((caddr_t)fwd + sizeof(*fwd));
5893 fwd_sz -= sizeof(*fwd);
5894 {
5895 /* New method. */
2694 }
2695 }
2696 }
2697 if ((ch->ch.chunk_type & 0x80) == 0) {
2698 /* discard the rest of this packet */
2699 stop_proc = 1;
2700 } /* else skip this bad chunk and
2701 * continue... */

--- 3183 unchanged lines hidden (view full) ---

5885 }
5886 /*************************************************************/
5887 /* 3. Update the PR-stream re-ordering queues */
5888 /*************************************************************/
5889 stseq = (struct sctp_strseq *)((caddr_t)fwd + sizeof(*fwd));
5890 fwd_sz -= sizeof(*fwd);
5891 {
5892 /* New method. */
5896 int num_str, i;
5893 unsigned int num_str;
5897
5898 num_str = fwd_sz / sizeof(struct sctp_strseq);
5899 for (i = 0; i < num_str; i++) {
5900 uint16_t st;
5901 unsigned char *xx;
5902
5903 /* Convert */
5904 xx = (unsigned char *)&stseq[i];

--- 30 unchanged lines hidden ---
5894
5895 num_str = fwd_sz / sizeof(struct sctp_strseq);
5896 for (i = 0; i < num_str; i++) {
5897 uint16_t st;
5898 unsigned char *xx;
5899
5900 /* Convert */
5901 xx = (unsigned char *)&stseq[i];

--- 30 unchanged lines hidden ---