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 --- |