Deleted Added
full compact
sctp_input.c (230379) sctp_input.c (233660)
1/*-
2 * Copyright (c) 2001-2008, by Cisco Systems, Inc. All rights reserved.
3 * Copyright (c) 2008-2011, by Randall Stewart. All rights reserved.
4 * Copyright (c) 2008-2011, by Michael Tuexen. All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are met:
8 *

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

28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
30 * THE POSSIBILITY OF SUCH DAMAGE.
31 */
32
33/* $KAME: sctp_input.c,v 1.27 2005/03/06 16:04:17 itojun Exp $ */
34
35#include <sys/cdefs.h>
1/*-
2 * Copyright (c) 2001-2008, by Cisco Systems, Inc. All rights reserved.
3 * Copyright (c) 2008-2011, by Randall Stewart. All rights reserved.
4 * Copyright (c) 2008-2011, by Michael Tuexen. All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are met:
8 *

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

28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
30 * THE POSSIBILITY OF SUCH DAMAGE.
31 */
32
33/* $KAME: sctp_input.c,v 1.27 2005/03/06 16:04:17 itojun Exp $ */
34
35#include <sys/cdefs.h>
36__FBSDID("$FreeBSD: head/sys/netinet/sctp_input.c 230379 2012-01-20 13:26:11Z tuexen $");
36__FBSDID("$FreeBSD: head/sys/netinet/sctp_input.c 233660 2012-03-29 13:36:53Z rrs $");
37
38#include <netinet/sctp_os.h>
39#include <netinet/sctp_var.h>
40#include <netinet/sctp_sysctl.h>
41#include <netinet/sctp_pcb.h>
42#include <netinet/sctp_header.h>
43#include <netinet/sctputil.h>
44#include <netinet/sctp_output.h>

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

2785 inp->sctp_features = (*inp_p)->sctp_features;
2786 inp->sctp_mobility_features = (*inp_p)->sctp_mobility_features;
2787 inp->sctp_socket = so;
2788 inp->sctp_frag_point = (*inp_p)->sctp_frag_point;
2789 inp->sctp_cmt_on_off = (*inp_p)->sctp_cmt_on_off;
2790 inp->sctp_ecn_enable = (*inp_p)->sctp_ecn_enable;
2791 inp->partial_delivery_point = (*inp_p)->partial_delivery_point;
2792 inp->sctp_context = (*inp_p)->sctp_context;
37
38#include <netinet/sctp_os.h>
39#include <netinet/sctp_var.h>
40#include <netinet/sctp_sysctl.h>
41#include <netinet/sctp_pcb.h>
42#include <netinet/sctp_header.h>
43#include <netinet/sctputil.h>
44#include <netinet/sctp_output.h>

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

2785 inp->sctp_features = (*inp_p)->sctp_features;
2786 inp->sctp_mobility_features = (*inp_p)->sctp_mobility_features;
2787 inp->sctp_socket = so;
2788 inp->sctp_frag_point = (*inp_p)->sctp_frag_point;
2789 inp->sctp_cmt_on_off = (*inp_p)->sctp_cmt_on_off;
2790 inp->sctp_ecn_enable = (*inp_p)->sctp_ecn_enable;
2791 inp->partial_delivery_point = (*inp_p)->partial_delivery_point;
2792 inp->sctp_context = (*inp_p)->sctp_context;
2793 inp->local_strreset_support = (*inp_p)->local_strreset_support;
2793 inp->inp_starting_point_for_iterator = NULL;
2794 /*
2795 * copy in the authentication parameters from the
2796 * original endpoint
2797 */
2798 if (inp->sctp_ep.local_hmacs)
2799 sctp_free_hmaclist(inp->sctp_ep.local_hmacs);
2800 inp->sctp_ep.local_hmacs =

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

3607 sctp_ulp_notify(SCTP_NOTIFY_STR_RESET_FAILED_OUT, stcb, number_entries, srparam->list_of_streams, SCTP_SO_NOT_LOCKED);
3608 }
3609 } else if (type == SCTP_STR_RESET_IN_REQUEST) {
3610 /* Answered my request */
3611 number_entries = (lparm_len - sizeof(struct sctp_stream_reset_in_request)) / sizeof(uint16_t);
3612 if (asoc->stream_reset_outstanding)
3613 asoc->stream_reset_outstanding--;
3614 if (action != SCTP_STREAM_RESET_PERFORMED) {
2794 inp->inp_starting_point_for_iterator = NULL;
2795 /*
2796 * copy in the authentication parameters from the
2797 * original endpoint
2798 */
2799 if (inp->sctp_ep.local_hmacs)
2800 sctp_free_hmaclist(inp->sctp_ep.local_hmacs);
2801 inp->sctp_ep.local_hmacs =

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

3608 sctp_ulp_notify(SCTP_NOTIFY_STR_RESET_FAILED_OUT, stcb, number_entries, srparam->list_of_streams, SCTP_SO_NOT_LOCKED);
3609 }
3610 } else if (type == SCTP_STR_RESET_IN_REQUEST) {
3611 /* Answered my request */
3612 number_entries = (lparm_len - sizeof(struct sctp_stream_reset_in_request)) / sizeof(uint16_t);
3613 if (asoc->stream_reset_outstanding)
3614 asoc->stream_reset_outstanding--;
3615 if (action != SCTP_STREAM_RESET_PERFORMED) {
3615 sctp_ulp_notify(SCTP_NOTIFY_STR_RESET_FAILED_IN, stcb, number_entries, srparam->list_of_streams, SCTP_SO_NOT_LOCKED);
3616 sctp_ulp_notify(SCTP_NOTIFY_STR_RESET_FAILED_IN, stcb,
3617 number_entries, srparam->list_of_streams, SCTP_SO_NOT_LOCKED);
3616 }
3618 }
3617 } else if (type == SCTP_STR_RESET_ADD_STREAMS) {
3619 } else if (type == SCTP_STR_RESET_ADD_OUT_STREAMS) {
3618 /* Ok we now may have more streams */
3620 /* Ok we now may have more streams */
3621 int num_stream;
3622
3623 num_stream = stcb->asoc.strm_pending_add_size;
3624 if (num_stream > (stcb->asoc.strm_realoutsize - stcb->asoc.streamoutcnt)) {
3625 /* TSNH */
3626 num_stream = stcb->asoc.strm_realoutsize - stcb->asoc.streamoutcnt;
3627 }
3628 stcb->asoc.strm_pending_add_size = 0;
3619 if (asoc->stream_reset_outstanding)
3620 asoc->stream_reset_outstanding--;
3621 if (action == SCTP_STREAM_RESET_PERFORMED) {
3622 /* Put the new streams into effect */
3629 if (asoc->stream_reset_outstanding)
3630 asoc->stream_reset_outstanding--;
3631 if (action == SCTP_STREAM_RESET_PERFORMED) {
3632 /* Put the new streams into effect */
3623 stcb->asoc.streamoutcnt = stcb->asoc.strm_realoutsize;
3624 sctp_ulp_notify(SCTP_NOTIFY_STR_RESET_ADD_OK, stcb,
3625 (uint32_t) stcb->asoc.streamoutcnt, NULL, SCTP_SO_NOT_LOCKED);
3633 stcb->asoc.streamoutcnt += num_stream;
3634 sctp_notify_stream_reset_add(stcb, stcb->asoc.streamincnt, stcb->asoc.streamoutcnt, 0);
3626 } else {
3635 } else {
3627 sctp_ulp_notify(SCTP_NOTIFY_STR_RESET_ADD_FAIL, stcb,
3628 (uint32_t) stcb->asoc.streamoutcnt, NULL, SCTP_SO_NOT_LOCKED);
3636 sctp_notify_stream_reset_add(stcb, stcb->asoc.streamincnt, stcb->asoc.streamoutcnt,
3637 SCTP_STREAM_CHANGED_DENIED);
3629 }
3638 }
3639 } else if (type == SCTP_STR_RESET_ADD_IN_STREAMS) {
3640 if (asoc->stream_reset_outstanding)
3641 asoc->stream_reset_outstanding--;
3642 if (action != SCTP_STREAM_RESET_PERFORMED) {
3643 sctp_notify_stream_reset_add(stcb, stcb->asoc.streamincnt, stcb->asoc.streamoutcnt,
3644 SCTP_STREAM_CHANGED_DENIED);
3645 }
3630 } else if (type == SCTP_STR_RESET_TSN_REQUEST) {
3631 /**
3632 * a) Adopt the new in tsn.
3633 * b) reset the map
3634 * c) Adopt the new out-tsn
3635 */
3636 struct sctp_stream_reset_response_tsn *resp;
3637 struct sctp_forward_tsn_chunk fwdtsn;

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

3662 stcb->asoc.highest_tsn_inside_nr_map = stcb->asoc.highest_tsn_inside_map;
3663 memset(stcb->asoc.nr_mapping_array, 0, stcb->asoc.mapping_array_size);
3664
3665 stcb->asoc.sending_seq = ntohl(resp->receivers_next_tsn);
3666 stcb->asoc.last_acked_seq = stcb->asoc.cumulative_tsn;
3667
3668 sctp_reset_out_streams(stcb, 0, (uint16_t *) NULL);
3669 sctp_reset_in_stream(stcb, 0, (uint16_t *) NULL);
3646 } else if (type == SCTP_STR_RESET_TSN_REQUEST) {
3647 /**
3648 * a) Adopt the new in tsn.
3649 * b) reset the map
3650 * c) Adopt the new out-tsn
3651 */
3652 struct sctp_stream_reset_response_tsn *resp;
3653 struct sctp_forward_tsn_chunk fwdtsn;

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

3678 stcb->asoc.highest_tsn_inside_nr_map = stcb->asoc.highest_tsn_inside_map;
3679 memset(stcb->asoc.nr_mapping_array, 0, stcb->asoc.mapping_array_size);
3680
3681 stcb->asoc.sending_seq = ntohl(resp->receivers_next_tsn);
3682 stcb->asoc.last_acked_seq = stcb->asoc.cumulative_tsn;
3683
3684 sctp_reset_out_streams(stcb, 0, (uint16_t *) NULL);
3685 sctp_reset_in_stream(stcb, 0, (uint16_t *) NULL);
3670
3686 sctp_notify_stream_reset_tsn(stcb, stcb->asoc.sending_seq, (stcb->asoc.mapping_array_base_tsn + 1), 0);
3687 } else {
3688 sctp_notify_stream_reset_tsn(stcb, stcb->asoc.sending_seq, (stcb->asoc.mapping_array_base_tsn + 1),
3689 SCTP_STREAM_RESET_FAILED);
3671 }
3672 }
3673 /* get rid of the request and get the request flags */
3674 if (asoc->stream_reset_outstanding == 0) {
3675 sctp_clean_up_stream_reset(stcb);
3676 }
3677 }
3678 }

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

3695 */
3696 struct sctp_association *asoc = &stcb->asoc;
3697
3698 seq = ntohl(req->request_seq);
3699 if (asoc->str_reset_seq_in == seq) {
3700 if (trunc) {
3701 /* Can't do it, since they exceeded our buffer size */
3702 asoc->last_reset_action[1] = asoc->last_reset_action[0];
3690 }
3691 }
3692 /* get rid of the request and get the request flags */
3693 if (asoc->stream_reset_outstanding == 0) {
3694 sctp_clean_up_stream_reset(stcb);
3695 }
3696 }
3697 }

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

3714 */
3715 struct sctp_association *asoc = &stcb->asoc;
3716
3717 seq = ntohl(req->request_seq);
3718 if (asoc->str_reset_seq_in == seq) {
3719 if (trunc) {
3720 /* Can't do it, since they exceeded our buffer size */
3721 asoc->last_reset_action[1] = asoc->last_reset_action[0];
3703 asoc->last_reset_action[0] = SCTP_STREAM_RESET_DENIED;
3704 sctp_add_stream_reset_result(chk, seq, asoc->last_reset_action[0]);
3722 asoc->last_reset_action[0] = SCTP_STREAM_RESET_REJECT;
3705 } else if (stcb->asoc.stream_reset_out_is_outstanding == 0) {
3706 len = ntohs(req->ph.param_length);
3707 number_entries = ((len - sizeof(struct sctp_stream_reset_in_request)) / sizeof(uint16_t));
3708 for (i = 0; i < number_entries; i++) {
3709 temp = ntohs(req->list_of_streams[i]);
3710 req->list_of_streams[i] = temp;
3711 }
3712 /* move the reset action back one */

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

3718 asoc->stream_reset_out_is_outstanding = 1;
3719 asoc->str_reset = chk;
3720 sctp_timer_start(SCTP_TIMER_TYPE_STRRESET, stcb->sctp_ep, stcb, chk->whoTo);
3721 stcb->asoc.stream_reset_outstanding++;
3722 } else {
3723 /* Can't do it, since we have sent one out */
3724 asoc->last_reset_action[1] = asoc->last_reset_action[0];
3725 asoc->last_reset_action[0] = SCTP_STREAM_RESET_TRY_LATER;
3723 } else if (stcb->asoc.stream_reset_out_is_outstanding == 0) {
3724 len = ntohs(req->ph.param_length);
3725 number_entries = ((len - sizeof(struct sctp_stream_reset_in_request)) / sizeof(uint16_t));
3726 for (i = 0; i < number_entries; i++) {
3727 temp = ntohs(req->list_of_streams[i]);
3728 req->list_of_streams[i] = temp;
3729 }
3730 /* move the reset action back one */

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

3736 asoc->stream_reset_out_is_outstanding = 1;
3737 asoc->str_reset = chk;
3738 sctp_timer_start(SCTP_TIMER_TYPE_STRRESET, stcb->sctp_ep, stcb, chk->whoTo);
3739 stcb->asoc.stream_reset_outstanding++;
3740 } else {
3741 /* Can't do it, since we have sent one out */
3742 asoc->last_reset_action[1] = asoc->last_reset_action[0];
3743 asoc->last_reset_action[0] = SCTP_STREAM_RESET_TRY_LATER;
3726 sctp_add_stream_reset_result(chk, seq, asoc->last_reset_action[0]);
3727 }
3744 }
3745 sctp_add_stream_reset_result(chk, seq, asoc->last_reset_action[0]);
3728 asoc->str_reset_seq_in++;
3729 } else if (asoc->str_reset_seq_in - 1 == seq) {
3730 sctp_add_stream_reset_result(chk, seq, asoc->last_reset_action[0]);
3731 } else if (asoc->str_reset_seq_in - 2 == seq) {
3732 sctp_add_stream_reset_result(chk, seq, asoc->last_reset_action[1]);
3733 } else {
3734 sctp_add_stream_reset_result(chk, seq, SCTP_STREAM_RESET_BAD_SEQNO);
3735 }

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

3781 ntohl(req->request_seq),
3782 SCTP_STREAM_RESET_PERFORMED,
3783 stcb->asoc.sending_seq,
3784 stcb->asoc.mapping_array_base_tsn);
3785 sctp_reset_out_streams(stcb, 0, (uint16_t *) NULL);
3786 sctp_reset_in_stream(stcb, 0, (uint16_t *) NULL);
3787 stcb->asoc.last_reset_action[1] = stcb->asoc.last_reset_action[0];
3788 stcb->asoc.last_reset_action[0] = SCTP_STREAM_RESET_PERFORMED;
3746 asoc->str_reset_seq_in++;
3747 } else if (asoc->str_reset_seq_in - 1 == seq) {
3748 sctp_add_stream_reset_result(chk, seq, asoc->last_reset_action[0]);
3749 } else if (asoc->str_reset_seq_in - 2 == seq) {
3750 sctp_add_stream_reset_result(chk, seq, asoc->last_reset_action[1]);
3751 } else {
3752 sctp_add_stream_reset_result(chk, seq, SCTP_STREAM_RESET_BAD_SEQNO);
3753 }

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

3799 ntohl(req->request_seq),
3800 SCTP_STREAM_RESET_PERFORMED,
3801 stcb->asoc.sending_seq,
3802 stcb->asoc.mapping_array_base_tsn);
3803 sctp_reset_out_streams(stcb, 0, (uint16_t *) NULL);
3804 sctp_reset_in_stream(stcb, 0, (uint16_t *) NULL);
3805 stcb->asoc.last_reset_action[1] = stcb->asoc.last_reset_action[0];
3806 stcb->asoc.last_reset_action[0] = SCTP_STREAM_RESET_PERFORMED;
3789
3807 sctp_notify_stream_reset_tsn(stcb, stcb->asoc.sending_seq, (stcb->asoc.mapping_array_base_tsn + 1), 0);
3790 asoc->str_reset_seq_in++;
3791 } else if (asoc->str_reset_seq_in - 1 == seq) {
3792 sctp_add_stream_reset_result_tsn(chk, seq, asoc->last_reset_action[0],
3793 stcb->asoc.last_sending_seq[0],
3794 stcb->asoc.last_base_tsnsent[0]
3795 );
3796 } else if (asoc->str_reset_seq_in - 2 == seq) {
3797 sctp_add_stream_reset_result_tsn(chk, seq, asoc->last_reset_action[1],

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

3826 * it, and setup the data in processor to trigger it off
3827 * when needed and dequeue all the queued data.
3828 */
3829 tsn = ntohl(req->send_reset_at_tsn);
3830
3831 /* move the reset action back one */
3832 asoc->last_reset_action[1] = asoc->last_reset_action[0];
3833 if (trunc) {
3808 asoc->str_reset_seq_in++;
3809 } else if (asoc->str_reset_seq_in - 1 == seq) {
3810 sctp_add_stream_reset_result_tsn(chk, seq, asoc->last_reset_action[0],
3811 stcb->asoc.last_sending_seq[0],
3812 stcb->asoc.last_base_tsnsent[0]
3813 );
3814 } else if (asoc->str_reset_seq_in - 2 == seq) {
3815 sctp_add_stream_reset_result_tsn(chk, seq, asoc->last_reset_action[1],

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

3844 * it, and setup the data in processor to trigger it off
3845 * when needed and dequeue all the queued data.
3846 */
3847 tsn = ntohl(req->send_reset_at_tsn);
3848
3849 /* move the reset action back one */
3850 asoc->last_reset_action[1] = asoc->last_reset_action[0];
3851 if (trunc) {
3834 sctp_add_stream_reset_result(chk, seq, SCTP_STREAM_RESET_DENIED);
3835 asoc->last_reset_action[0] = SCTP_STREAM_RESET_DENIED;
3852 asoc->last_reset_action[0] = SCTP_STREAM_RESET_REJECT;
3836 } else if (SCTP_TSN_GE(asoc->cumulative_tsn, tsn)) {
3837 /* we can do it now */
3838 sctp_reset_in_stream(stcb, number_entries, req->list_of_streams);
3853 } else if (SCTP_TSN_GE(asoc->cumulative_tsn, tsn)) {
3854 /* we can do it now */
3855 sctp_reset_in_stream(stcb, number_entries, req->list_of_streams);
3839 sctp_add_stream_reset_result(chk, seq, SCTP_STREAM_RESET_PERFORMED);
3840 asoc->last_reset_action[0] = SCTP_STREAM_RESET_PERFORMED;
3841 } else {
3842 /*
3843 * we must queue it up and thus wait for the TSN's
3844 * to arrive that are at or before tsn
3845 */
3846 struct sctp_stream_reset_list *liste;
3847 int siz;
3848
3849 siz = sizeof(struct sctp_stream_reset_list) + (number_entries * sizeof(uint16_t));
3850 SCTP_MALLOC(liste, struct sctp_stream_reset_list *,
3851 siz, SCTP_M_STRESET);
3852 if (liste == NULL) {
3853 /* gak out of memory */
3856 asoc->last_reset_action[0] = SCTP_STREAM_RESET_PERFORMED;
3857 } else {
3858 /*
3859 * we must queue it up and thus wait for the TSN's
3860 * to arrive that are at or before tsn
3861 */
3862 struct sctp_stream_reset_list *liste;
3863 int siz;
3864
3865 siz = sizeof(struct sctp_stream_reset_list) + (number_entries * sizeof(uint16_t));
3866 SCTP_MALLOC(liste, struct sctp_stream_reset_list *,
3867 siz, SCTP_M_STRESET);
3868 if (liste == NULL) {
3869 /* gak out of memory */
3854 sctp_add_stream_reset_result(chk, seq, SCTP_STREAM_RESET_DENIED);
3855 asoc->last_reset_action[0] = SCTP_STREAM_RESET_DENIED;
3870 sctp_add_stream_reset_result(chk, seq, SCTP_STREAM_RESET_REJECT);
3871 asoc->last_reset_action[0] = SCTP_STREAM_RESET_REJECT;
3856 return;
3857 }
3858 liste->tsn = tsn;
3859 liste->number_entries = number_entries;
3860 memcpy(&liste->req, req,
3861 (sizeof(struct sctp_stream_reset_out_request) + (number_entries * sizeof(uint16_t))));
3862 TAILQ_INSERT_TAIL(&asoc->resetHead, liste, next_resp);
3872 return;
3873 }
3874 liste->tsn = tsn;
3875 liste->number_entries = number_entries;
3876 memcpy(&liste->req, req,
3877 (sizeof(struct sctp_stream_reset_out_request) + (number_entries * sizeof(uint16_t))));
3878 TAILQ_INSERT_TAIL(&asoc->resetHead, liste, next_resp);
3863 sctp_add_stream_reset_result(chk, seq, SCTP_STREAM_RESET_PERFORMED);
3864 asoc->last_reset_action[0] = SCTP_STREAM_RESET_PERFORMED;
3865 }
3879 asoc->last_reset_action[0] = SCTP_STREAM_RESET_PERFORMED;
3880 }
3881 sctp_add_stream_reset_result(chk, seq, asoc->last_reset_action[0]);
3866 asoc->str_reset_seq_in++;
3867 } else if ((asoc->str_reset_seq_in - 1) == seq) {
3868 /*
3869 * one seq back, just echo back last action since my
3870 * response was lost.
3871 */
3872 sctp_add_stream_reset_result(chk, seq, asoc->last_reset_action[0]);
3873 } else if ((asoc->str_reset_seq_in - 2) == seq) {

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

3884static void
3885sctp_handle_str_reset_add_strm(struct sctp_tcb *stcb, struct sctp_tmit_chunk *chk,
3886 struct sctp_stream_reset_add_strm *str_add)
3887{
3888 /*
3889 * Peer is requesting to add more streams. If its within our
3890 * max-streams we will allow it.
3891 */
3882 asoc->str_reset_seq_in++;
3883 } else if ((asoc->str_reset_seq_in - 1) == seq) {
3884 /*
3885 * one seq back, just echo back last action since my
3886 * response was lost.
3887 */
3888 sctp_add_stream_reset_result(chk, seq, asoc->last_reset_action[0]);
3889 } else if ((asoc->str_reset_seq_in - 2) == seq) {

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

3900static void
3901sctp_handle_str_reset_add_strm(struct sctp_tcb *stcb, struct sctp_tmit_chunk *chk,
3902 struct sctp_stream_reset_add_strm *str_add)
3903{
3904 /*
3905 * Peer is requesting to add more streams. If its within our
3906 * max-streams we will allow it.
3907 */
3892 uint16_t num_stream, i;
3908 uint32_t num_stream, i;
3893 uint32_t seq;
3894 struct sctp_association *asoc = &stcb->asoc;
3895 struct sctp_queued_to_read *ctl, *nctl;
3896
3897 /* Get the number. */
3898 seq = ntohl(str_add->request_seq);
3899 num_stream = ntohs(str_add->number_of_streams);
3900 /* Now what would be the new total? */
3901 if (asoc->str_reset_seq_in == seq) {
3902 num_stream += stcb->asoc.streamincnt;
3909 uint32_t seq;
3910 struct sctp_association *asoc = &stcb->asoc;
3911 struct sctp_queued_to_read *ctl, *nctl;
3912
3913 /* Get the number. */
3914 seq = ntohl(str_add->request_seq);
3915 num_stream = ntohs(str_add->number_of_streams);
3916 /* Now what would be the new total? */
3917 if (asoc->str_reset_seq_in == seq) {
3918 num_stream += stcb->asoc.streamincnt;
3903 if (num_stream > stcb->asoc.max_inbound_streams) {
3919 if ((num_stream > stcb->asoc.max_inbound_streams) ||
3920 (num_stream > 0xffff)) {
3904 /* We must reject it they ask for to many */
3905 denied:
3921 /* We must reject it they ask for to many */
3922 denied:
3906 sctp_add_stream_reset_result(chk, seq, SCTP_STREAM_RESET_DENIED);
3907 stcb->asoc.last_reset_action[1] = stcb->asoc.last_reset_action[0];
3923 stcb->asoc.last_reset_action[1] = stcb->asoc.last_reset_action[0];
3908 stcb->asoc.last_reset_action[0] = SCTP_STREAM_RESET_DENIED;
3924 stcb->asoc.last_reset_action[0] = SCTP_STREAM_RESET_REJECT;
3909 } else {
3910 /* Ok, we can do that :-) */
3911 struct sctp_stream_in *oldstrm;
3912
3913 /* save off the old */
3914 oldstrm = stcb->asoc.strmin;
3915 SCTP_MALLOC(stcb->asoc.strmin, struct sctp_stream_in *,
3916 (num_stream * sizeof(struct sctp_stream_in)),

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

3936 TAILQ_INIT(&stcb->asoc.strmin[i].inqueue);
3937 stcb->asoc.strmin[i].stream_no = i;
3938 stcb->asoc.strmin[i].last_sequence_delivered = 0xffff;
3939 stcb->asoc.strmin[i].delivery_started = 0;
3940 }
3941 SCTP_FREE(oldstrm, SCTP_M_STRMI);
3942 /* update the size */
3943 stcb->asoc.streamincnt = num_stream;
3925 } else {
3926 /* Ok, we can do that :-) */
3927 struct sctp_stream_in *oldstrm;
3928
3929 /* save off the old */
3930 oldstrm = stcb->asoc.strmin;
3931 SCTP_MALLOC(stcb->asoc.strmin, struct sctp_stream_in *,
3932 (num_stream * sizeof(struct sctp_stream_in)),

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

3952 TAILQ_INIT(&stcb->asoc.strmin[i].inqueue);
3953 stcb->asoc.strmin[i].stream_no = i;
3954 stcb->asoc.strmin[i].last_sequence_delivered = 0xffff;
3955 stcb->asoc.strmin[i].delivery_started = 0;
3956 }
3957 SCTP_FREE(oldstrm, SCTP_M_STRMI);
3958 /* update the size */
3959 stcb->asoc.streamincnt = num_stream;
3944 /* Send the ack */
3945 sctp_add_stream_reset_result(chk, seq, SCTP_STREAM_RESET_PERFORMED);
3946 stcb->asoc.last_reset_action[1] = stcb->asoc.last_reset_action[0];
3947 stcb->asoc.last_reset_action[0] = SCTP_STREAM_RESET_PERFORMED;
3960 stcb->asoc.last_reset_action[1] = stcb->asoc.last_reset_action[0];
3961 stcb->asoc.last_reset_action[0] = SCTP_STREAM_RESET_PERFORMED;
3948 sctp_ulp_notify(SCTP_NOTIFY_STR_RESET_INSTREAM_ADD_OK, stcb,
3949 (uint32_t) stcb->asoc.streamincnt, NULL, SCTP_SO_NOT_LOCKED);
3962 sctp_notify_stream_reset_add(stcb, stcb->asoc.streamincnt, stcb->asoc.streamoutcnt, 0);
3950 }
3963 }
3964 sctp_add_stream_reset_result(chk, seq, asoc->last_reset_action[0]);
3965 asoc->str_reset_seq_in++;
3951 } else if ((asoc->str_reset_seq_in - 1) == seq) {
3952 /*
3953 * one seq back, just echo back last action since my
3954 * response was lost.
3955 */
3956 sctp_add_stream_reset_result(chk, seq, asoc->last_reset_action[0]);
3957 } else if ((asoc->str_reset_seq_in - 2) == seq) {
3958 /*
3959 * two seq back, just echo back last action since my
3960 * response was lost.
3961 */
3962 sctp_add_stream_reset_result(chk, seq, asoc->last_reset_action[1]);
3963 } else {
3964 sctp_add_stream_reset_result(chk, seq, SCTP_STREAM_RESET_BAD_SEQNO);
3965
3966 }
3967}
3968
3966 } else if ((asoc->str_reset_seq_in - 1) == seq) {
3967 /*
3968 * one seq back, just echo back last action since my
3969 * response was lost.
3970 */
3971 sctp_add_stream_reset_result(chk, seq, asoc->last_reset_action[0]);
3972 } else if ((asoc->str_reset_seq_in - 2) == seq) {
3973 /*
3974 * two seq back, just echo back last action since my
3975 * response was lost.
3976 */
3977 sctp_add_stream_reset_result(chk, seq, asoc->last_reset_action[1]);
3978 } else {
3979 sctp_add_stream_reset_result(chk, seq, SCTP_STREAM_RESET_BAD_SEQNO);
3980
3981 }
3982}
3983
3984static void
3985sctp_handle_str_reset_add_out_strm(struct sctp_tcb *stcb, struct sctp_tmit_chunk *chk,
3986 struct sctp_stream_reset_add_strm *str_add)
3987{
3988 /*
3989 * Peer is requesting to add more streams. If its within our
3990 * max-streams we will allow it.
3991 */
3992 uint16_t num_stream;
3993 uint32_t seq;
3994 struct sctp_association *asoc = &stcb->asoc;
3995
3996 /* Get the number. */
3997 seq = ntohl(str_add->request_seq);
3998 num_stream = ntohs(str_add->number_of_streams);
3999 /* Now what would be the new total? */
4000 if (asoc->str_reset_seq_in == seq) {
4001 if (stcb->asoc.stream_reset_outstanding) {
4002 /* We must reject it we have something pending */
4003 stcb->asoc.last_reset_action[1] = stcb->asoc.last_reset_action[0];
4004 stcb->asoc.last_reset_action[0] = SCTP_STREAM_RESET_REJECT;
4005 } else {
4006 /* Ok, we can do that :-) */
4007 int mychk;
4008
4009 mychk = stcb->asoc.streamoutcnt;
4010 mychk += num_stream;
4011 if (mychk < 0x10000) {
4012 stcb->asoc.last_reset_action[1] = stcb->asoc.last_reset_action[0];
4013 stcb->asoc.last_reset_action[0] = SCTP_STREAM_RESET_PERFORMED;
4014 if (sctp_send_str_reset_req(stcb, 0, NULL, 0, 0, 0, 1, num_stream, 0, 1)) {
4015 stcb->asoc.last_reset_action[0] = SCTP_STREAM_RESET_REJECT;
4016 }
4017 } else {
4018 stcb->asoc.last_reset_action[1] = stcb->asoc.last_reset_action[0];
4019 stcb->asoc.last_reset_action[0] = SCTP_STREAM_RESET_REJECT;
4020 }
4021 }
4022 sctp_add_stream_reset_result(chk, seq, stcb->asoc.last_reset_action[0]);
4023 asoc->str_reset_seq_in++;
4024 } else if ((asoc->str_reset_seq_in - 1) == seq) {
4025 /*
4026 * one seq back, just echo back last action since my
4027 * response was lost.
4028 */
4029 sctp_add_stream_reset_result(chk, seq, asoc->last_reset_action[0]);
4030 } else if ((asoc->str_reset_seq_in - 2) == seq) {
4031 /*
4032 * two seq back, just echo back last action since my
4033 * response was lost.
4034 */
4035 sctp_add_stream_reset_result(chk, seq, asoc->last_reset_action[1]);
4036 } else {
4037 sctp_add_stream_reset_result(chk, seq, SCTP_STREAM_RESET_BAD_SEQNO);
4038 }
4039}
4040
3969#ifdef __GNUC__
3970__attribute__((noinline))
3971#endif
3972 static int
3973 sctp_handle_stream_reset(struct sctp_tcb *stcb, struct mbuf *m, int offset,
3974 struct sctp_stream_reset_out_req *sr_req)
3975{
3976 int chk_length, param_len, ptype;
3977 struct sctp_paramhdr pstore;
3978 uint8_t cstore[SCTP_CHUNK_BUFFER_SIZE];
3979
4041#ifdef __GNUC__
4042__attribute__((noinline))
4043#endif
4044 static int
4045 sctp_handle_stream_reset(struct sctp_tcb *stcb, struct mbuf *m, int offset,
4046 struct sctp_stream_reset_out_req *sr_req)
4047{
4048 int chk_length, param_len, ptype;
4049 struct sctp_paramhdr pstore;
4050 uint8_t cstore[SCTP_CHUNK_BUFFER_SIZE];
4051
3980 uint32_t seq;
4052 uint32_t seq = 0;
3981 int num_req = 0;
3982 int trunc = 0;
3983 struct sctp_tmit_chunk *chk;
3984 struct sctp_chunkhdr *ch;
3985 struct sctp_paramhdr *ph;
3986 int ret_code = 0;
3987 int num_param = 0;
3988

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

4036 (uint8_t *) & cstore);
4037 ptype = ntohs(ph->param_type);
4038 num_param++;
4039 if (param_len > (int)sizeof(cstore)) {
4040 trunc = 1;
4041 } else {
4042 trunc = 0;
4043 }
4053 int num_req = 0;
4054 int trunc = 0;
4055 struct sctp_tmit_chunk *chk;
4056 struct sctp_chunkhdr *ch;
4057 struct sctp_paramhdr *ph;
4058 int ret_code = 0;
4059 int num_param = 0;
4060

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

4108 (uint8_t *) & cstore);
4109 ptype = ntohs(ph->param_type);
4110 num_param++;
4111 if (param_len > (int)sizeof(cstore)) {
4112 trunc = 1;
4113 } else {
4114 trunc = 0;
4115 }
4044
4045 if (num_param > SCTP_MAX_RESET_PARAMS) {
4046 /* hit the max of parameters already sorry.. */
4047 break;
4048 }
4049 if (ptype == SCTP_STR_RESET_OUT_REQUEST) {
4050 struct sctp_stream_reset_out_request *req_out;
4051
4052 req_out = (struct sctp_stream_reset_out_request *)ph;
4053 num_req++;
4054 if (stcb->asoc.stream_reset_outstanding) {
4055 seq = ntohl(req_out->response_seq);
4056 if (seq == stcb->asoc.str_reset_seq_out) {
4057 /* implicit ack */
4058 (void)sctp_handle_stream_reset_response(stcb, seq, SCTP_STREAM_RESET_PERFORMED, NULL);
4059 }
4060 }
4061 sctp_handle_str_reset_request_out(stcb, chk, req_out, trunc);
4116 if (num_param > SCTP_MAX_RESET_PARAMS) {
4117 /* hit the max of parameters already sorry.. */
4118 break;
4119 }
4120 if (ptype == SCTP_STR_RESET_OUT_REQUEST) {
4121 struct sctp_stream_reset_out_request *req_out;
4122
4123 req_out = (struct sctp_stream_reset_out_request *)ph;
4124 num_req++;
4125 if (stcb->asoc.stream_reset_outstanding) {
4126 seq = ntohl(req_out->response_seq);
4127 if (seq == stcb->asoc.str_reset_seq_out) {
4128 /* implicit ack */
4129 (void)sctp_handle_stream_reset_response(stcb, seq, SCTP_STREAM_RESET_PERFORMED, NULL);
4130 }
4131 }
4132 sctp_handle_str_reset_request_out(stcb, chk, req_out, trunc);
4062 } else if (ptype == SCTP_STR_RESET_ADD_STREAMS) {
4133 } else if (ptype == SCTP_STR_RESET_ADD_OUT_STREAMS) {
4063 struct sctp_stream_reset_add_strm *str_add;
4064
4065 str_add = (struct sctp_stream_reset_add_strm *)ph;
4066 num_req++;
4067 sctp_handle_str_reset_add_strm(stcb, chk, str_add);
4134 struct sctp_stream_reset_add_strm *str_add;
4135
4136 str_add = (struct sctp_stream_reset_add_strm *)ph;
4137 num_req++;
4138 sctp_handle_str_reset_add_strm(stcb, chk, str_add);
4139 } else if (ptype == SCTP_STR_RESET_ADD_IN_STREAMS) {
4140 struct sctp_stream_reset_add_strm *str_add;
4141
4142 str_add = (struct sctp_stream_reset_add_strm *)ph;
4143 num_req++;
4144 sctp_handle_str_reset_add_out_strm(stcb, chk, str_add);
4068 } else if (ptype == SCTP_STR_RESET_IN_REQUEST) {
4069 struct sctp_stream_reset_in_request *req_in;
4070
4071 num_req++;
4145 } else if (ptype == SCTP_STR_RESET_IN_REQUEST) {
4146 struct sctp_stream_reset_in_request *req_in;
4147
4148 num_req++;
4072
4073 req_in = (struct sctp_stream_reset_in_request *)ph;
4149 req_in = (struct sctp_stream_reset_in_request *)ph;
4074
4075 sctp_handle_str_reset_request_in(stcb, chk, req_in, trunc);
4076 } else if (ptype == SCTP_STR_RESET_TSN_REQUEST) {
4077 struct sctp_stream_reset_tsn_request *req_tsn;
4078
4079 num_req++;
4080 req_tsn = (struct sctp_stream_reset_tsn_request *)ph;
4150 sctp_handle_str_reset_request_in(stcb, chk, req_in, trunc);
4151 } else if (ptype == SCTP_STR_RESET_TSN_REQUEST) {
4152 struct sctp_stream_reset_tsn_request *req_tsn;
4153
4154 num_req++;
4155 req_tsn = (struct sctp_stream_reset_tsn_request *)ph;
4081
4082 if (sctp_handle_str_reset_request_tsn(stcb, chk, req_tsn)) {
4083 ret_code = 1;
4084 goto strres_nochunk;
4085 }
4086 /* no more */
4087 break;
4088 } else if (ptype == SCTP_STR_RESET_RESPONSE) {
4089 struct sctp_stream_reset_response *resp;

--- 1944 unchanged lines hidden ---
4156 if (sctp_handle_str_reset_request_tsn(stcb, chk, req_tsn)) {
4157 ret_code = 1;
4158 goto strres_nochunk;
4159 }
4160 /* no more */
4161 break;
4162 } else if (ptype == SCTP_STR_RESET_RESPONSE) {
4163 struct sctp_stream_reset_response *resp;

--- 1944 unchanged lines hidden ---