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