aboutsummaryrefslogtreecommitdiffstats
path: root/net/sctp/sm_statefuns.c
diff options
context:
space:
mode:
authorWei Yongjun <yjwei@cn.fujitsu.com>2007-08-02 04:57:44 -0400
committerVlad Yasevich <vladislav.yasevich@hp.com>2007-08-02 10:41:18 -0400
commitaecedeab6fcf914929cd8ff6fa0b8ae9bfdf3d30 (patch)
tree7757855692d2275b32d03988a4e27b47ef127a5f /net/sctp/sm_statefuns.c
parente4d1feab5df035312494ce3037ac5f041d0f5fc9 (diff)
SCTP: drop SACK if ctsn is not less than the next tsn of assoc
We need to drop the SACK if the peer is attempting to acknowledge unset data, i.e. the CTSN in the SACK is greater or equal to the next TSN we will send. Example: Endpoint A Endpoint B <--------------- DATA (TSN=1) SACK(TSN=1) ---------------> <--------------- DATA (TSN=2) <--------------- DATA (TSN=3) <--------------- DATA (TSN=4) <--------------- DATA (TSN=5) SACK(TSN=1000) ---------------> <--------------- DATA (TSN=6) <--------------- DATA (TSN=7) Signed-off-by: Wei Yongjun <yjwei@cn.fujitsu.com> Signed-off-by: Vlad Yasevich <vladislav.yasevich@hp.com>
Diffstat (limited to 'net/sctp/sm_statefuns.c')
-rw-r--r--net/sctp/sm_statefuns.c103
1 files changed, 78 insertions, 25 deletions
diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c
index fd2dfdd7d7fd..71cad56dd73f 100644
--- a/net/sctp/sm_statefuns.c
+++ b/net/sctp/sm_statefuns.c
@@ -97,6 +97,13 @@ static sctp_disposition_t sctp_stop_t1_and_abort(sctp_cmd_seq_t *commands,
97 const struct sctp_association *asoc, 97 const struct sctp_association *asoc,
98 struct sctp_transport *transport); 98 struct sctp_transport *transport);
99 99
100static sctp_disposition_t sctp_sf_abort_violation(
101 const struct sctp_association *asoc,
102 void *arg,
103 sctp_cmd_seq_t *commands,
104 const __u8 *payload,
105 const size_t paylen);
106
100static sctp_disposition_t sctp_sf_violation_chunklen( 107static sctp_disposition_t sctp_sf_violation_chunklen(
101 const struct sctp_endpoint *ep, 108 const struct sctp_endpoint *ep,
102 const struct sctp_association *asoc, 109 const struct sctp_association *asoc,
@@ -104,6 +111,13 @@ static sctp_disposition_t sctp_sf_violation_chunklen(
104 void *arg, 111 void *arg,
105 sctp_cmd_seq_t *commands); 112 sctp_cmd_seq_t *commands);
106 113
114static sctp_disposition_t sctp_sf_violation_ctsn(
115 const struct sctp_endpoint *ep,
116 const struct sctp_association *asoc,
117 const sctp_subtype_t type,
118 void *arg,
119 sctp_cmd_seq_t *commands);
120
107/* Small helper function that checks if the chunk length 121/* Small helper function that checks if the chunk length
108 * is of the appropriate length. The 'required_length' argument 122 * is of the appropriate length. The 'required_length' argument
109 * is set to be the size of a specific chunk we are testing. 123 * is set to be the size of a specific chunk we are testing.
@@ -2880,6 +2894,13 @@ sctp_disposition_t sctp_sf_eat_sack_6_2(const struct sctp_endpoint *ep,
2880 return SCTP_DISPOSITION_DISCARD; 2894 return SCTP_DISPOSITION_DISCARD;
2881 } 2895 }
2882 2896
2897 /* If Cumulative TSN Ack beyond the max tsn currently
2898 * send, terminating the association and respond to the
2899 * sender with an ABORT.
2900 */
2901 if (!TSN_lt(ctsn, asoc->next_tsn))
2902 return sctp_sf_violation_ctsn(ep, asoc, type, arg, commands);
2903
2883 /* Return this SACK for further processing. */ 2904 /* Return this SACK for further processing. */
2884 sctp_add_cmd_sf(commands, SCTP_CMD_PROCESS_SACK, SCTP_SACKH(sackh)); 2905 sctp_add_cmd_sf(commands, SCTP_CMD_PROCESS_SACK, SCTP_SACKH(sackh));
2885 2906
@@ -3691,40 +3712,21 @@ sctp_disposition_t sctp_sf_violation(const struct sctp_endpoint *ep,
3691 return SCTP_DISPOSITION_VIOLATION; 3712 return SCTP_DISPOSITION_VIOLATION;
3692} 3713}
3693 3714
3694
3695/* 3715/*
3696 * Handle a protocol violation when the chunk length is invalid. 3716 * Common function to handle a protocol violation.
3697 * "Invalid" length is identified as smaller then the minimal length a
3698 * given chunk can be. For example, a SACK chunk has invalid length
3699 * if it's length is set to be smaller then the size of sctp_sack_chunk_t.
3700 *
3701 * We inform the other end by sending an ABORT with a Protocol Violation
3702 * error code.
3703 *
3704 * Section: Not specified
3705 * Verification Tag: Nothing to do
3706 * Inputs
3707 * (endpoint, asoc, chunk)
3708 *
3709 * Outputs
3710 * (reply_msg, msg_up, counters)
3711 *
3712 * Generate an ABORT chunk and terminate the association.
3713 */ 3717 */
3714static sctp_disposition_t sctp_sf_violation_chunklen( 3718static sctp_disposition_t sctp_sf_abort_violation(
3715 const struct sctp_endpoint *ep,
3716 const struct sctp_association *asoc, 3719 const struct sctp_association *asoc,
3717 const sctp_subtype_t type,
3718 void *arg, 3720 void *arg,
3719 sctp_cmd_seq_t *commands) 3721 sctp_cmd_seq_t *commands,
3722 const __u8 *payload,
3723 const size_t paylen)
3720{ 3724{
3721 struct sctp_chunk *chunk = arg; 3725 struct sctp_chunk *chunk = arg;
3722 struct sctp_chunk *abort = NULL; 3726 struct sctp_chunk *abort = NULL;
3723 char err_str[]="The following chunk had invalid length:";
3724 3727
3725 /* Make the abort chunk. */ 3728 /* Make the abort chunk. */
3726 abort = sctp_make_abort_violation(asoc, chunk, err_str, 3729 abort = sctp_make_abort_violation(asoc, chunk, payload, paylen);
3727 sizeof(err_str));
3728 if (!abort) 3730 if (!abort)
3729 goto nomem; 3731 goto nomem;
3730 3732
@@ -3756,6 +3758,57 @@ nomem:
3756 return SCTP_DISPOSITION_NOMEM; 3758 return SCTP_DISPOSITION_NOMEM;
3757} 3759}
3758 3760
3761/*
3762 * Handle a protocol violation when the chunk length is invalid.
3763 * "Invalid" length is identified as smaller then the minimal length a
3764 * given chunk can be. For example, a SACK chunk has invalid length
3765 * if it's length is set to be smaller then the size of sctp_sack_chunk_t.
3766 *
3767 * We inform the other end by sending an ABORT with a Protocol Violation
3768 * error code.
3769 *
3770 * Section: Not specified
3771 * Verification Tag: Nothing to do
3772 * Inputs
3773 * (endpoint, asoc, chunk)
3774 *
3775 * Outputs
3776 * (reply_msg, msg_up, counters)
3777 *
3778 * Generate an ABORT chunk and terminate the association.
3779 */
3780static sctp_disposition_t sctp_sf_violation_chunklen(
3781 const struct sctp_endpoint *ep,
3782 const struct sctp_association *asoc,
3783 const sctp_subtype_t type,
3784 void *arg,
3785 sctp_cmd_seq_t *commands)
3786{
3787 char err_str[]="The following chunk had invalid length:";
3788
3789 return sctp_sf_abort_violation(asoc, arg, commands, err_str,
3790 sizeof(err_str));
3791}
3792
3793/* Handle a protocol violation when the peer trying to advance the
3794 * cumulative tsn ack to a point beyond the max tsn currently sent.
3795 *
3796 * We inform the other end by sending an ABORT with a Protocol Violation
3797 * error code.
3798 */
3799static sctp_disposition_t sctp_sf_violation_ctsn(
3800 const struct sctp_endpoint *ep,
3801 const struct sctp_association *asoc,
3802 const sctp_subtype_t type,
3803 void *arg,
3804 sctp_cmd_seq_t *commands)
3805{
3806 char err_str[]="The cumulative tsn ack beyond the max tsn currently sent:";
3807
3808 return sctp_sf_abort_violation(asoc, arg, commands, err_str,
3809 sizeof(err_str));
3810}
3811
3759/*************************************************************************** 3812/***************************************************************************
3760 * These are the state functions for handling primitive (Section 10) events. 3813 * These are the state functions for handling primitive (Section 10) events.
3761 ***************************************************************************/ 3814 ***************************************************************************/